[libdap] 01/48: Initial commit of 3.11.1

Alastair McKinstry mckinstry at moszumanska.debian.org
Sun Jul 5 10:17:04 UTC 2015


This is an automated email from the git hooks/post-receive script.

mckinstry pushed a commit to tag unstable/3.12.0-1
in repository libdap.

commit 919bc5bcb84b80289dc80718faa8f69a4921e034
Author: Alastair McKinstry <mckinstry at debian.org>
Date:   Fri Aug 19 10:23:57 2011 +0100

    Initial commit of 3.11.1
---
 AlarmHandler.h                                     |   109 +
 Ancillary.cc                                       |   227 +
 Ancillary.h                                        |    73 +
 Array.cc                                           |   919 +
 Array.h                                            |   225 +
 ArrayGeoConstraint.cc                              |   212 +
 ArrayGeoConstraint.h                               |   140 +
 AttrTable.cc                                       |  1370 +
 AttrTable.h                                        |   346 +
 BaseType.cc                                        |  1090 +
 BaseType.h                                         |   513 +
 BaseTypeFactory.cc                                 |   128 +
 BaseTypeFactory.h                                  |   104 +
 Byte.cc                                            |   306 +
 Byte.h                                             |   119 +
 COPYING                                            |   504 +
 COPYRIGHT_URI                                      |    32 +
 COPYRIGHT_W3C                                      |    50 +
 ChangeLog                                          |  8453 ++++++
 Clause.cc                                          |   237 +
 Clause.h                                           |   135 +
 Connect.cc                                         |  1118 +
 Connect.h                                          |   226 +
 ConstraintEvaluator.cc                             |   467 +
 ConstraintEvaluator.h                              |   136 +
 Constructor.cc                                     |   520 +
 Constructor.h                                      |   103 +
 DAS.cc                                             |   423 +
 DAS.h                                              |   183 +
 DDS.cc                                             |  1209 +
 DDS.h                                              |   337 +
 DDXExceptions.h                                    |    49 +
 DDXParserSAX2.cc                                   |  1223 +
 DDXParserSAX2.h                                    |   267 +
 DODSFilter.cc                                      |  1344 +
 DODSFilter.h                                       |   242 +
 DapIndent.cc                                       |    85 +
 DapIndent.h                                        |    67 +
 DapObj.h                                           |   110 +
 DataDDS.cc                                         |   172 +
 DataDDS.h                                          |   147 +
 EncodingType.h                                     |    58 +
 Error.cc                                           |   293 +
 Error.h                                            |   119 +
 Error.lex                                          |   165 +
 Error.tab.cc                                       |  1633 ++
 Error.tab.hh                                       |    80 +
 Error.y                                            |   133 +
 EventHandler.h                                     |    74 +
 Float32.cc                                         |   300 +
 Float32.h                                          |   115 +
 Float64.cc                                         |   307 +
 Float64.h                                          |   117 +
 GNU/GNURegex.cc                                    |   167 +
 GNU/GNURegex.h                                     |    60 +
 GNU/GetOpt.cc                                      |   274 +
 GNU/GetOpt.h                                       |   125 +
 GNU/README                                         |     8 +
 GSEClause.cc                                       |   351 +
 GSEClause.h                                        |   143 +
 GeoConstraint.cc                                   |   659 +
 GeoConstraint.h                                    |   376 +
 Grid.cc                                            |  1146 +
 Grid.h                                             |   223 +
 GridGeoConstraint.cc                               |   396 +
 GridGeoConstraint.h                                |    86 +
 HTTPCache.cc                                       |  1622 ++
 HTTPCache.h                                        |   277 +
 HTTPCacheDisconnectedMode.h                        |    55 +
 HTTPCacheInterruptHandler.h                        |    95 +
 HTTPCacheResponse.h                                |    96 +
 HTTPCacheTable.cc                                  |   863 +
 HTTPCacheTable.h                                   |   378 +
 HTTPConnect.cc                                     |  1008 +
 HTTPConnect.h                                      |   175 +
 HTTPResponse.h                                     |   150 +
 INSTALL                                            |   175 +
 Int16.cc                                           |   288 +
 Int16.h                                            |   114 +
 Int32.cc                                           |   299 +
 Int32.h                                            |   117 +
 InternalErr.cc                                     |    98 +
 InternalErr.h                                      |    93 +
 Keywords2.cc                                       |   211 +
 Keywords2.h                                        |    86 +
 Makefile.am                                        |   326 +
 Makefile.in                                        |  2257 ++
 Marshaller.h                                       |    84 +
 NEWS                                               |   653 +
 OSX_Resources/Description.plist                    |    10 +
 OSX_Resources/Info.plist                           |    46 +
 OSX_Resources/Info.plist.proto                     |    46 +
 OSX_Resources/InstallationCheck                    |    45 +
 OSX_Resources/InstallationCheck.strings            |     6 +
 OSX_Resources/License.txt                          |   177 +
 OSX_Resources/ReadMe.txt                           |   237 +
 OSX_Resources/Welcome.html                         |    23 +
 OSX_Resources/background.jpg                       |   Bin 0 -> 8481 bytes
 OSX_Resources/macify_license_file.pl               |    36 +
 OSX_Resources/update_mac_package_contents.pl       |    43 +
 ObjectType.h                                       |    73 +
 Operators.h                                        |   276 +
 PipeResponse.h                                     |    92 +
 RCReader.cc                                        |   498 +
 RCReader.h                                         |   360 +
 README                                             |   414 +
 README.dodsrc                                      |   150 +
 RValue.cc                                          |   177 +
 RValue.h                                           |    77 +
 Resource.h                                         |   156 +
 Response.h                                         |   160 +
 ResponseBuilder.cc                                 |   723 +
 ResponseBuilder.h                                  |   166 +
 ResponseTooBigErr.cc                               |    52 +
 ResponseTooBigErr.h                                |    55 +
 Sequence.cc                                        |  1570 ++
 Sequence.h                                         |   355 +
 SignalHandler.cc                                   |   227 +
 SignalHandler.h                                    |   118 +
 SignalHandlerRegisteredErr.h                       |    63 +
 StdinResponse.h                                    |    86 +
 Str.cc                                             |   319 +
 Str.h                                              |   113 +
 Structure.cc                                       |   535 +
 Structure.h                                        |   163 +
 UInt16.cc                                          |   289 +
 UInt16.h                                           |   114 +
 UInt32.cc                                          |   291 +
 UInt32.h                                           |   116 +
 UnMarshaller.h                                     |    85 +
 Url.cc                                             |    73 +
 Url.h                                              |    84 +
 VCPP/BeforeInstall.txt                             |     1 +
 VCPP/License.txt                                   |   177 +
 VCPP/Makefile                                      |   543 +
 VCPP/config.h                                      |    53 +
 VCPP/dependancies                                  |     0
 VCPP/doc/readme.txt                                |   131 +
 VCPP/dods-datatypes.h                              |    42 +
 VCPP/libdap.iss                                    |    53 +
 VCPP/sample/Makefile                               |    74 +
 VCPP/sample/getdap.cc                              |   430 +
 VCPP/unistd.h                                      |     4 +
 VCPP/xdr-datatypes.h                               |    48 +
 Vector.cc                                          |  1648 ++
 Vector.h                                           |   190 +
 XDRFileMarshaller.cc                               |   209 +
 XDRFileMarshaller.h                                |    83 +
 XDRFileUnMarshaller.cc                             |   197 +
 XDRFileUnMarshaller.h                              |    84 +
 XDRStreamMarshaller.cc                             |   401 +
 XDRStreamMarshaller.h                              |    92 +
 XDRStreamUnMarshaller.cc                           |   358 +
 XDRStreamUnMarshaller.h                            |    94 +
 XDRUtils.cc                                        |   179 +
 XDRUtils.h                                         |    71 +
 aclocal.m4                                         |  1030 +
 ce_expr.lex                                        |   219 +
 ce_expr.tab.cc                                     |  2649 ++
 ce_expr.tab.hh                                     |    95 +
 ce_expr.y                                          |  1080 +
 ce_functions.cc                                    |  1071 +
 ce_functions.h                                     |    66 +
 ce_parser.h                                        |    36 +
 cgi_util.h                                         |    15 +
 conf/acinclude.m4                                  |   606 +
 conf/arg-nonnull.h                                 |    26 +
 conf/c++defs.h                                     |   271 +
 conf/check_zlib.m4                                 |   122 +
 conf/config.guess                                  |  1561 ++
 conf/config.sub                                    |  1686 ++
 conf/cppunit.m4                                    |    92 +
 conf/depcomp                                       |   630 +
 conf/install-sh                                    |   520 +
 conf/libdap.m4                                     |   314 +
 conf/libtool.m4                                    |  7357 ++++++
 conf/ltmain.sh                                     |  8406 ++++++
 conf/ltoptions.m4                                  |   368 +
 conf/ltsugar.m4                                    |   123 +
 conf/ltversion.m4                                  |    23 +
 conf/lt~obsolete.m4                                |    92 +
 conf/missing                                       |   376 +
 conf/pkg.m4                                        |   157 +
 conf/warn-on-use.h                                 |   109 +
 config.h.in                                        |   852 +
 config_dap.h                                       |    20 +
 configure                                          | 25697 +++++++++++++++++++
 configure.ac                                       |   309 +
 dap-config-pkgconfig                               |    86 +
 dap-config.in                                      |    90 +
 das.lex                                            |   220 +
 das.tab.cc                                         |  2201 ++
 das.tab.hh                                         |    83 +
 das.y                                              |   547 +
 dds.lex                                            |   195 +
 dds.tab.cc                                         |  2177 ++
 dds.tab.hh                                         |    97 +
 dds.y                                              |   509 +
 debug.h                                            |    80 +
 dods-datatypes-config.h.in                         |    49 +
 dods-datatypes-static.h                            |    49 +
 dods-datatypes.h                                   |    49 +
 dods-limits.h                                      |    68 +
 doxy.conf                                          |  1363 +
 doxy_private.conf                                  |   950 +
 escaping.cc                                        |   497 +
 escaping.h                                         |    87 +
 expr.h                                             |    96 +
 getdap.cc                                          |   523 +
 gl/Makefile.am                                     |   775 +
 gl/Makefile.in                                     |  1561 ++
 gl/alloca.in.h                                     |    56 +
 gl/btowc.c                                         |    39 +
 gl/config.charset                                  |   683 +
 gl/gettext.h                                       |   280 +
 gl/iswblank.c                                      |    27 +
 gl/langinfo.in.h                                   |   174 +
 gl/localcharset.c                                  |   548 +
 gl/localcharset.h                                  |    41 +
 gl/m4/00gnulib.m4                                  |    30 +
 gl/m4/alloca.m4                                    |    43 +
 gl/m4/btowc.m4                                     |   121 +
 gl/m4/codeset.m4                                   |    23 +
 gl/m4/configmake.m4                                |    50 +
 gl/m4/extensions.m4                                |   118 +
 gl/m4/fcntl-o.m4                                   |   112 +
 gl/m4/glibc21.m4                                   |    34 +
 gl/m4/gnulib-cache.m4                              |    36 +
 gl/m4/gnulib-common.m4                             |   234 +
 gl/m4/gnulib-comp.m4                               |   340 +
 gl/m4/gnulib-tool.m4                               |    57 +
 gl/m4/include_next.m4                              |   244 +
 gl/m4/langinfo_h.m4                                |   105 +
 gl/m4/localcharset.m4                              |    17 +
 gl/m4/locale-fr.m4                                 |   188 +
 gl/m4/locale-ja.m4                                 |   110 +
 gl/m4/locale-zh.m4                                 |    95 +
 gl/m4/longlong.m4                                  |   106 +
 gl/m4/malloc.m4                                    |    66 +
 gl/m4/mbrtowc.m4                                   |   511 +
 gl/m4/mbsinit.m4                                   |    32 +
 gl/m4/mbstate_t.m4                                 |    41 +
 gl/m4/multiarch.m4                                 |    62 +
 gl/m4/nl_langinfo.m4                               |    52 +
 gl/m4/regex.m4                                     |   225 +
 gl/m4/ssize_t.m4                                   |    23 +
 gl/m4/stdbool.m4                                   |   103 +
 gl/m4/stddef_h.m4                                  |    45 +
 gl/m4/stdint.m4                                    |   474 +
 gl/m4/stdlib_h.m4                                  |   114 +
 gl/m4/unistd_h.m4                                  |   162 +
 gl/m4/warn-on-use.m4                               |    45 +
 gl/m4/wchar_h.m4                                   |   170 +
 gl/m4/wchar_t.m4                                   |    24 +
 gl/m4/wcrtomb.m4                                   |   101 +
 gl/m4/wctype_h.m4                                  |   100 +
 gl/m4/wint_t.m4                                    |    32 +
 gl/malloc.c                                        |    60 +
 gl/mbrtowc.c                                       |   395 +
 gl/mbsinit.c                                       |    47 +
 gl/nl_langinfo.c                                   |   270 +
 gl/ref-add.sin                                     |    30 +
 gl/ref-del.sin                                     |    25 +
 gl/regcomp.c                                       |  3876 +++
 gl/regex.c                                         |    71 +
 gl/regex.h                                         |   675 +
 gl/regex_internal.c                                |  1741 ++
 gl/regex_internal.h                                |   870 +
 gl/regexec.c                                       |  4417 ++++
 gl/stdbool.in.h                                    |   122 +
 gl/stddef.in.h                                     |    87 +
 gl/stdint.in.h                                     |   582 +
 gl/stdlib.in.h                                     |   726 +
 gl/streq.h                                         |   176 +
 gl/unistd.in.h                                     |  1378 +
 gl/verify.h                                        |   163 +
 gl/wchar.in.h                                      |   433 +
 gl/wcrtomb.c                                       |    53 +
 gl/wctype.in.h                                     |   385 +
 gse.lex                                            |   174 +
 gse.tab.cc                                         |  1716 ++
 gse.tab.hh                                         |    88 +
 gse.y                                              |   228 +
 gse_parser.h                                       |    84 +
 lex.Error.cc                                       |  1971 ++
 lex.ce_expr.cc                                     |  2008 ++
 lex.das.cc                                         |  2153 ++
 lex.dds.cc                                         |  2103 ++
 lex.gse_.cc                                        |  1882 ++
 libdap.pc.in                                       |    15 +
 libdap.spec                                        |   171 +
 libdapclient.pc.in                                 |    16 +
 libdapserver.pc.in                                 |    14 +
 mime_util.cc                                       |  1044 +
 mime_util.h                                        |   153 +
 parser-util.cc                                     |   383 +
 parser.h                                           |   196 +
 tests/DASTest                                      |  3894 +++
 tests/DASTest.at                                   |    70 +
 tests/DDSTest                                      |  3355 +++
 tests/DDSTest.at                                   |    63 +
 tests/EXPRTest                                     |  8644 +++++++
 tests/EXPRTest.at                                  |   124 +
 tests/Makefile.am                                  |   113 +
 tests/Makefile.in                                  |  1082 +
 tests/README                                       |    19 +
 tests/TestArray.cc                                 |   426 +
 tests/TestArray.h                                  |    74 +
 tests/TestByte.cc                                  |   150 +
 tests/TestByte.h                                   |    79 +
 tests/TestCommon.cc                                |    24 +
 tests/TestCommon.h                                 |    68 +
 tests/TestFloat32.cc                               |   134 +
 tests/TestFloat32.h                                |    70 +
 tests/TestFloat64.cc                               |   128 +
 tests/TestFloat64.h                                |    69 +
 tests/TestGrid.cc                                  |   166 +
 tests/TestGrid.h                                   |    69 +
 tests/TestInt16.cc                                 |   118 +
 tests/TestInt16.h                                  |    69 +
 tests/TestInt32.cc                                 |   125 +
 tests/TestInt32.h                                  |    69 +
 tests/TestSequence.cc                              |   153 +
 tests/TestSequence.h                               |    72 +
 tests/TestStr.cc                                   |   117 +
 tests/TestStr.h                                    |    72 +
 tests/TestStructure.cc                             |   150 +
 tests/TestStructure.h                              |    67 +
 tests/TestTypeFactory.cc                           |   126 +
 tests/TestTypeFactory.h                            |    73 +
 tests/TestUInt16.cc                                |   119 +
 tests/TestUInt16.h                                 |    69 +
 tests/TestUInt32.cc                                |   119 +
 tests/TestUInt32.h                                 |    69 +
 tests/TestUrl.cc                                   |   114 +
 tests/TestUrl.h                                    |    69 +
 tests/atconfig                                     |    20 +
 tests/atlocal                                      |     5 +
 tests/atlocal.in                                   |     5 +
 tests/das-test.cc                                  |   378 +
 tests/das-testsuite/bad_value_test.1.das           |    12 +
 tests/das-testsuite/bad_value_test.1.das.base      |    20 +
 tests/das-testsuite/das.das                        |     0
 tests/das-testsuite/das.das.base                   |     0
 tests/das-testsuite/special.test.das               |     0
 tests/das-testsuite/special.test.das.base          |     0
 tests/das-testsuite/special.test.hdf.das           |     0
 tests/das-testsuite/special.test.hdf.das.base      |     0
 tests/das-testsuite/test.1.das                     |     6 +
 tests/das-testsuite/test.1.das.base                |     5 +
 tests/das-testsuite/test.1.gz                      |     0
 tests/das-testsuite/test.11.das                    |    15 +
 tests/das-testsuite/test.11.das.base               |     9 +
 tests/das-testsuite/test.12.das                    |     8 +
 tests/das-testsuite/test.12.das.base               |     8 +
 tests/das-testsuite/test.13.das                    |     8 +
 tests/das-testsuite/test.13.das.base               |     8 +
 tests/das-testsuite/test.14.das                    |     8 +
 tests/das-testsuite/test.14.das.base               |     5 +
 tests/das-testsuite/test.15.das                    |     8 +
 tests/das-testsuite/test.15.das.base               |     8 +
 tests/das-testsuite/test.16.das                    |    13 +
 tests/das-testsuite/test.16.das.base               |     3 +
 tests/das-testsuite/test.17.das                    |    13 +
 tests/das-testsuite/test.17.das.base               |    15 +
 tests/das-testsuite/test.18.das                    |    10 +
 tests/das-testsuite/test.18.das.base               |     6 +
 tests/das-testsuite/test.19.das                    |    10 +
 tests/das-testsuite/test.19.das.base               |     9 +
 tests/das-testsuite/test.1a.das                    |    54 +
 tests/das-testsuite/test.1a.das.base               |    26 +
 tests/das-testsuite/test.2.das                     |     8 +
 tests/das-testsuite/test.2.das.base                |     6 +
 tests/das-testsuite/test.20.das                    |    10 +
 tests/das-testsuite/test.20.das.base               |     9 +
 tests/das-testsuite/test.21.das                    |    10 +
 tests/das-testsuite/test.21.das.base               |     9 +
 tests/das-testsuite/test.22.das                    |     9 +
 tests/das-testsuite/test.22.das.base               |     8 +
 tests/das-testsuite/test.23.das                    |    13 +
 tests/das-testsuite/test.23.das.base               |     7 +
 tests/das-testsuite/test.24.das                    |    17 +
 tests/das-testsuite/test.24.das.base               |    11 +
 tests/das-testsuite/test.25.das                    |    17 +
 tests/das-testsuite/test.25.das.base               |     4 +
 tests/das-testsuite/test.26.das                    |    15 +
 tests/das-testsuite/test.26.das.base               |    11 +
 tests/das-testsuite/test.27.das                    |    15 +
 tests/das-testsuite/test.27.das.base               |    11 +
 tests/das-testsuite/test.28.das                    |    16 +
 tests/das-testsuite/test.28.das.base               |    11 +
 tests/das-testsuite/test.29.das                    |    16 +
 tests/das-testsuite/test.29.das.base               |     3 +
 tests/das-testsuite/test.3.Z                       |     0
 tests/das-testsuite/test.3.Z.das                   |     0
 tests/das-testsuite/test.3.Z.das.base              |     4 +
 tests/das-testsuite/test.3.das                     |    12 +
 tests/das-testsuite/test.3.das.base                |     9 +
 tests/das-testsuite/test.30.das                    |    17 +
 tests/das-testsuite/test.30.das.base               |     3 +
 tests/das-testsuite/test.31.das                    |    20 +
 tests/das-testsuite/test.31.das.base               |    15 +
 tests/das-testsuite/test.32.das                    |    10 +
 tests/das-testsuite/test.32.das.base               |     7 +
 tests/das-testsuite/test.33.das                    |    10 +
 tests/das-testsuite/test.33.das.base               |     7 +
 tests/das-testsuite/test.34.das                    |    10 +
 tests/das-testsuite/test.34.das.base               |    10 +
 tests/das-testsuite/test.35.das                    |     9 +
 tests/das-testsuite/test.35.das.base               |     9 +
 tests/das-testsuite/test.4.das                     |     8 +
 tests/das-testsuite/test.4.das.base                |     6 +
 tests/das-testsuite/test.5.das                     |     9 +
 tests/das-testsuite/test.5.das.base                |     2 +
 tests/das-testsuite/test.6.das                     |    10 +
 tests/das-testsuite/test.6.das.base                |     4 +
 tests/das-testsuite/test.7.das                     |    12 +
 tests/das-testsuite/test.7.das.base                |     4 +
 tests/das-testsuite/test.8.das                     |     9 +
 tests/das-testsuite/test.8.das.base                |     5 +
 tests/das-testsuite/test.9.das                     |    18 +
 tests/das-testsuite/test.9.das.base                |    13 +
 tests/dds-test.cc                                  |   297 +
 tests/dds-testsuite/3B42.980909.5.HDF.das.dds      |   626 +
 tests/dds-testsuite/3B42.980909.5.HDF.das.dds.base |     3 +
 tests/dds-testsuite/3B42.980909.5.HDF.dds          |     8 +
 tests/dds-testsuite/3B42.980909.5.HDF.dds.base     |    10 +
 .../dds-testsuite/3B42.980909.5.hacked.HDF.das.dds |    39 +
 .../3B42.980909.5.hacked.HDF.das.dds.base          |     3 +
 tests/dds-testsuite/AsciiOutputTest1.dds           |    33 +
 tests/dds-testsuite/AsciiOutputTest1.dds.base      |    28 +
 tests/dds-testsuite/S2000415.HDF.das.dds           |   316 +
 tests/dds-testsuite/S2000415.HDF.das.dds.base      |     3 +
 tests/dds-testsuite/S2000415.HDF.dds               |    35 +
 tests/dds-testsuite/S2000415.HDF.dds.base          |    37 +
 tests/dds-testsuite/fnoc1.nc.das.dds               |    32 +
 tests/dds-testsuite/fnoc1.nc.das.dds.base          |     3 +
 tests/dds-testsuite/fnoc1.nc.dds                   |     7 +
 tests/dds-testsuite/fnoc1.nc.dds.base              |     9 +
 tests/dds-testsuite/test.1.dds                     |     7 +
 tests/dds-testsuite/test.1.dds.base                |     7 +
 tests/dds-testsuite/test.10.dds                    |    45 +
 tests/dds-testsuite/test.10.dds.base               |    39 +
 tests/dds-testsuite/test.11.dds                    |    37 +
 tests/dds-testsuite/test.11.dds.base               |    30 +
 tests/dds-testsuite/test.12.dds                    |     6 +
 tests/dds-testsuite/test.12.dds.base               |     6 +
 tests/dds-testsuite/test.13.dds                    |     6 +
 tests/dds-testsuite/test.13.dds.base               |     3 +
 tests/dds-testsuite/test.14.dds                    |     4 +
 tests/dds-testsuite/test.14.dds.base               |     4 +
 tests/dds-testsuite/test.15.dds                    |     8 +
 tests/dds-testsuite/test.15.dds.base               |     7 +
 tests/dds-testsuite/test.16.dds                    |    21 +
 tests/dds-testsuite/test.16.dds.base               |    20 +
 tests/dds-testsuite/test.17.dds                    |    12 +
 tests/dds-testsuite/test.17.dds.base               |     5 +
 tests/dds-testsuite/test.18.dds                    |    12 +
 tests/dds-testsuite/test.18.dds.base               |    11 +
 tests/dds-testsuite/test.19.dds                    |    14 +
 tests/dds-testsuite/test.19.dds.base               |    13 +
 tests/dds-testsuite/test.19b.das.dds               |    33 +
 tests/dds-testsuite/test.19b.das.dds.base          |     3 +
 tests/dds-testsuite/test.19b.dds                   |    14 +
 tests/dds-testsuite/test.19b.dds.base              |    13 +
 tests/dds-testsuite/test.2.dds                     |     4 +
 tests/dds-testsuite/test.2.dds.base                |     6 +
 tests/dds-testsuite/test.20.dds                    |    12 +
 tests/dds-testsuite/test.20.dds.base               |    11 +
 tests/dds-testsuite/test.3.dds                     |     4 +
 tests/dds-testsuite/test.3.dds.base                |     6 +
 tests/dds-testsuite/test.4.dds                     |     6 +
 tests/dds-testsuite/test.4.dds.base                |     8 +
 tests/dds-testsuite/test.6.dds                     |     6 +
 tests/dds-testsuite/test.6.dds.base                |     8 +
 tests/dds-testsuite/test.7.dds                     |    10 +
 tests/dds-testsuite/test.7.dds.base                |    12 +
 tests/dds-testsuite/test.8.dds                     |    14 +
 tests/dds-testsuite/test.8.dds.base                |    16 +
 tests/dds-testsuite/test.9.dds                     |    22 +
 tests/dds-testsuite/test.9.dds.base                |    24 +
 tests/expr-test.cc                                 |   660 +
 tests/expr-testsuite/data.61a.base                 |     6 +
 tests/expr-testsuite/data.61b.base                 |     6 +
 tests/expr-testsuite/data.61c.base                 |     6 +
 tests/expr-testsuite/data.61d.base                 |     6 +
 tests/expr-testsuite/data.z0.base                  |     1 +
 tests/expr-testsuite/data.z1.base                  |    18 +
 tests/expr-testsuite/data.z2.base                  |    18 +
 tests/expr-testsuite/data.z3.base                  |    18 +
 tests/expr-testsuite/data.z4.base                  |    20 +
 tests/expr-testsuite/data.z5.base                  |    20 +
 tests/expr-testsuite/data.z6.base                  |    18 +
 tests/expr-testsuite/data.z7.base                  |    20 +
 tests/expr-testsuite/data.z8.base                  |    32 +
 tests/expr-testsuite/data.zz0.base                 |     1 +
 tests/expr-testsuite/data.zz1.base                 |     6 +
 tests/expr-testsuite/data.zz2.base                 |     6 +
 tests/expr-testsuite/test.1                        |    11 +
 tests/expr-testsuite/test.1.base                   |     7 +
 tests/expr-testsuite/test.1a.base                  |     8 +
 tests/expr-testsuite/test.1b.base                  |     8 +
 tests/expr-testsuite/test.1c.base                  |     6 +
 tests/expr-testsuite/test.1d.base                  |     7 +
 tests/expr-testsuite/test.2                        |    21 +
 tests/expr-testsuite/test.2.base                   |    20 +
 tests/expr-testsuite/test.2a                       |    22 +
 tests/expr-testsuite/test.2a.base                  |     0
 tests/expr-testsuite/test.2b.base                  |    24 +
 tests/expr-testsuite/test.2c.base                  |    23 +
 tests/expr-testsuite/test.2d.base                  |    19 +
 tests/expr-testsuite/test.2e.base                  |    20 +
 tests/expr-testsuite/test.2f.base                  |    21 +
 tests/expr-testsuite/test.2g.base                  |    22 +
 tests/expr-testsuite/test.3                        |    11 +
 tests/expr-testsuite/test.3.base                   |     0
 tests/expr-testsuite/test.4                        |    12 +
 tests/expr-testsuite/test.4.base                   |     0
 tests/expr-testsuite/test.4a.base                  |     7 +
 tests/expr-testsuite/test.5                        |    20 +
 tests/expr-testsuite/test.5.base                   |     0
 tests/expr-testsuite/test.5a.base                  |    23 +
 tests/expr-testsuite/test.5b.base                  |    18 +
 tests/expr-testsuite/test.5c.base                  |    18 +
 tests/expr-testsuite/test.5d.base                  |    19 +
 tests/expr-testsuite/test.5e.base                  |     1 +
 tests/expr-testsuite/test.6                        |    11 +
 tests/expr-testsuite/test.6.base                   |     0
 tests/expr-testsuite/test.61                       |    10 +
 tests/expr-testsuite/test.6a.base                  |     7 +
 tests/expr-testsuite/test.6b.base                  |     2 +
 tests/expr-testsuite/test.7                        |     8 +
 tests/expr-testsuite/test.7.base                   |    10 +
 tests/expr-testsuite/test.8                        |    11 +
 tests/expr-testsuite/test.8.base                   |     9 +
 tests/expr-testsuite/test.8a.base                  |    10 +
 tests/expr-testsuite/test.8b.base                  |    10 +
 tests/expr-testsuite/test.9                        |    15 +
 tests/expr-testsuite/test.9.base                   |    15 +
 tests/expr-testsuite/test.a                        |     8 +
 tests/expr-testsuite/test.a.base                   |    12 +
 tests/expr-testsuite/test.aa.base                  |    12 +
 tests/expr-testsuite/test.ab.base                  |    11 +
 tests/expr-testsuite/test.ac.base                  |    12 +
 tests/expr-testsuite/test.b                        |    12 +
 tests/expr-testsuite/test.b.base                   |    20 +
 tests/expr-testsuite/test.ba.base                  |    18 +
 tests/expr-testsuite/test.bb.base                  |    18 +
 tests/expr-testsuite/test.bc.base                  |    18 +
 tests/expr-testsuite/test.bd.base                  |    16 +
 tests/expr-testsuite/test.be.base                  |    20 +
 tests/expr-testsuite/test.c0                       |    12 +
 tests/expr-testsuite/test.c1                       |    12 +
 tests/expr-testsuite/test.c2                       |    13 +
 tests/expr-testsuite/test.c3                       |     9 +
 tests/expr-testsuite/test.c4                       |    13 +
 tests/expr-testsuite/test.c5                       |    17 +
 tests/expr-testsuite/test.cc0                      |     6 +
 tests/expr-testsuite/test.cc1                      |     6 +
 tests/expr-testsuite/test.d                        |    16 +
 tests/expr-testsuite/test.d.base                   |    28 +
 tests/expr-testsuite/test.da.base                  |    25 +
 tests/expr-testsuite/test.db.base                  |    25 +
 tests/expr-testsuite/test.dc.base                  |    25 +
 tests/expr-testsuite/test.dd.base                  |    25 +
 tests/expr-testsuite/test.de.base                  |    22 +
 tests/expr-testsuite/test.df.base                  |    19 +
 tests/expr-testsuite/test.dg.base                  |    25 +
 tests/expr-testsuite/test.e                        |     8 +
 tests/expr-testsuite/test.ea.base                  |    11 +
 tests/expr-testsuite/test.eb.base                  |    11 +
 tests/package.m4                                   |     6 +
 unit-tests/ArrayGeoConstraintTest.cc               |   231 +
 unit-tests/ArrayTest.cc                            |   232 +
 unit-tests/AttrTableTest.cc                        |   400 +
 unit-tests/ByteTest.cc                             |   118 +
 unit-tests/CEFunctionsTest.cc                      |   582 +
 unit-tests/DASTest.cc                              |    96 +
 unit-tests/DDSTest.cc                              |   610 +
 unit-tests/DDXParserTest.cc                        |   568 +
 unit-tests/DODSFilterTest.cc                       |   571 +
 unit-tests/GridGeoConstraintTest.cc                |  1312 +
 unit-tests/HTTPCacheTest.cc                        |   875 +
 unit-tests/HTTPConnectTest.cc                      |   545 +
 unit-tests/Keywords2Test.cc                        |   217 +
 unit-tests/MIMEUtilTest.cc                         |   236 +
 unit-tests/Makefile.am                             |   166 +
 unit-tests/Makefile.in                             |  1476 ++
 unit-tests/MarshallerTest.cc                       |   995 +
 unit-tests/RCReaderTest.cc                         |   359 +
 unit-tests/RegexTest.cc                            |   149 +
 unit-tests/ResponseBuilderTest.cc                  |   494 +
 unit-tests/SequenceTest.cc                         |   428 +
 unit-tests/SignalHandlerTest.cc                    |   112 +
 unit-tests/ancT.cc                                 |   110 +
 unit-tests/arrayT.cc                               |   190 +
 unit-tests/attrTableT.cc                           |   318 +
 unit-tests/cache-testsuite/Makefile.am             |    15 +
 unit-tests/cache-testsuite/Makefile.in             |   722 +
 unit-tests/cache-testsuite/cleanup.sh.in           |    24 +
 unit-tests/cache-testsuite/dods_cache_init/.index  |     1 +
 .../cache-testsuite/dods_cache_init/656/dodsKbcD0h |    20 +
 .../dods_cache_init/656/dodsKbcD0h.meta            |     8 +
 unit-tests/cache-testsuite/dodsrc                  |    16 +
 unit-tests/cache-testsuite/dot.index               |     2 +
 unit-tests/ce-functions-testsuite/geo_grid.das     |    35 +
 unit-tests/ce-functions-testsuite/geo_grid.dds     |    38 +
 unit-tests/ce-functions-testsuite/geo_grid_3d.dds  |    11 +
 .../ce-functions-testsuite/geo_grid_coads_lon.dds  |    10 +
 unit-tests/ce-functions-testsuite/two_grid.das     |     8 +
 unit-tests/ce-functions-testsuite/two_grid.dds     |    28 +
 unit-tests/cgi-util-tests/01group.hdf              |     0
 unit-tests/cgi-util-tests/02group.hdf              |     0
 unit-tests/cgi-util-tests/03group.hdf              |     0
 unit-tests/cgi-util-tests/group.htm                |     1 +
 unit-tests/cgi-util-tests/group01.hdf              |     0
 .../cgi-util-tests/multipart_mime_header1.txt      |     6 +
 unit-tests/das-testsuite/bad_value_test.1          |    12 +
 unit-tests/das-testsuite/config/unix.exp           |    54 +
 unit-tests/das-testsuite/das                       |     0
 unit-tests/das-testsuite/das-test.0/scanner.1.exp  |    47 +
 unit-tests/das-testsuite/das-test.0/scanner.2.exp  |   163 +
 unit-tests/das-testsuite/das-test.0/scanner.3.exp  |    82 +
 unit-tests/das-testsuite/das-test.0/scanner.4.exp  |   119 +
 unit-tests/das-testsuite/das-test.0/scanner.5.exp  |    80 +
 unit-tests/das-testsuite/das-test.0/scanner.6.exp  |    80 +
 unit-tests/das-testsuite/das-test.0/scanner.7.exp  |    80 +
 unit-tests/das-testsuite/das-test.0/scanner.8.exp  |    80 +
 unit-tests/das-testsuite/das-test.0/scanner.9.exp  |    80 +
 unit-tests/das-testsuite/das-test.0/scanner.a.exp  |    94 +
 unit-tests/das-testsuite/das-test.0/scanner.b.exp  |   199 +
 unit-tests/das-testsuite/das-test.0/scanner.c.exp  |   206 +
 unit-tests/das-testsuite/das-test.0/test.1.exp     |    87 +
 unit-tests/das-testsuite/das-test.0/test.11.exp    |    59 +
 unit-tests/das-testsuite/das-test.0/test.12.exp    |    85 +
 unit-tests/das-testsuite/das-test.0/test.13.exp    |    85 +
 unit-tests/das-testsuite/das-test.0/test.14.exp    |    47 +
 unit-tests/das-testsuite/das-test.0/test.15.exp    |    85 +
 unit-tests/das-testsuite/das-test.0/test.16.exp    |    71 +
 unit-tests/das-testsuite/das-test.0/test.17.exp    |    90 +
 unit-tests/das-testsuite/das-test.0/test.18.exp    |    58 +
 unit-tests/das-testsuite/das-test.0/test.19.exp    |    83 +
 unit-tests/das-testsuite/das-test.0/test.2.exp     |    64 +
 unit-tests/das-testsuite/das-test.0/test.20.exp    |    82 +
 unit-tests/das-testsuite/das-test.0/test.21.exp    |    79 +
 unit-tests/das-testsuite/das-test.0/test.22.exp    |    82 +
 unit-tests/das-testsuite/das-test.0/test.23.exp    |    39 +
 unit-tests/das-testsuite/das-test.0/test.24.exp    |    44 +
 unit-tests/das-testsuite/das-test.0/test.25.exp    |    45 +
 unit-tests/das-testsuite/das-test.0/test.26.exp    |    43 +
 unit-tests/das-testsuite/das-test.0/test.27.exp    |    43 +
 unit-tests/das-testsuite/das-test.0/test.28.exp    |    44 +
 unit-tests/das-testsuite/das-test.0/test.29.exp    |    44 +
 unit-tests/das-testsuite/das-test.0/test.3.exp     |    76 +
 unit-tests/das-testsuite/das-test.0/test.30.exp    |    44 +
 unit-tests/das-testsuite/das-test.0/test.31.exp    |    47 +
 unit-tests/das-testsuite/das-test.0/test.32.exp    |    42 +
 unit-tests/das-testsuite/das-test.0/test.33.exp    |    42 +
 unit-tests/das-testsuite/das-test.0/test.4.exp     |    94 +
 unit-tests/das-testsuite/das-test.0/test.5.exp     |    62 +
 unit-tests/das-testsuite/das-test.0/test.6.exp     |    94 +
 unit-tests/das-testsuite/das-test.0/test.7.exp     |   106 +
 unit-tests/das-testsuite/das-test.0/test.8.exp     |    63 +
 unit-tests/das-testsuite/das-test.0/test.9.exp     |    71 +
 unit-tests/das-testsuite/special.test.das          |     0
 unit-tests/das-testsuite/special.test.hdf          |     0
 unit-tests/das-testsuite/test.1                    |    54 +
 unit-tests/das-testsuite/test.1.das                |     6 +
 unit-tests/das-testsuite/test.1.gz                 |     0
 unit-tests/das-testsuite/test.11                   |    15 +
 unit-tests/das-testsuite/test.12                   |     8 +
 unit-tests/das-testsuite/test.13                   |     8 +
 unit-tests/das-testsuite/test.14                   |     8 +
 unit-tests/das-testsuite/test.15                   |     8 +
 unit-tests/das-testsuite/test.16                   |    13 +
 unit-tests/das-testsuite/test.17                   |    13 +
 unit-tests/das-testsuite/test.18                   |    10 +
 unit-tests/das-testsuite/test.19                   |    10 +
 unit-tests/das-testsuite/test.2                    |     8 +
 unit-tests/das-testsuite/test.20                   |    10 +
 unit-tests/das-testsuite/test.21                   |    10 +
 unit-tests/das-testsuite/test.22                   |     9 +
 unit-tests/das-testsuite/test.23                   |    13 +
 unit-tests/das-testsuite/test.24                   |    17 +
 unit-tests/das-testsuite/test.25                   |    17 +
 unit-tests/das-testsuite/test.26                   |    15 +
 unit-tests/das-testsuite/test.27                   |    15 +
 unit-tests/das-testsuite/test.28                   |    16 +
 unit-tests/das-testsuite/test.29                   |    16 +
 unit-tests/das-testsuite/test.3                    |    12 +
 unit-tests/das-testsuite/test.3.Z                  |     0
 unit-tests/das-testsuite/test.3.Z.das              |     0
 unit-tests/das-testsuite/test.30                   |    17 +
 unit-tests/das-testsuite/test.31                   |    20 +
 unit-tests/das-testsuite/test.32                   |    10 +
 unit-tests/das-testsuite/test.33                   |    10 +
 unit-tests/das-testsuite/test.34                   |    10 +
 unit-tests/das-testsuite/test.4                    |     8 +
 unit-tests/das-testsuite/test.5                    |     9 +
 unit-tests/das-testsuite/test.6                    |    10 +
 unit-tests/das-testsuite/test.7                    |    12 +
 unit-tests/das-testsuite/test.8                    |     9 +
 unit-tests/das-testsuite/test.9                    |    18 +
 unit-tests/dasT.cc                                 |   176 +
 unit-tests/dds-testsuite/3B42.980909.5.HDF.das     |   626 +
 unit-tests/dds-testsuite/3B42.980909.5.HDF.dds     |     8 +
 .../dds-testsuite/3B42.980909.5.hacked.HDF.das     |    34 +
 unit-tests/dds-testsuite/AsciiOutputTest1.dds      |    33 +
 unit-tests/dds-testsuite/S2000415.HDF.das          |   316 +
 unit-tests/dds-testsuite/S2000415.HDF.dds          |    35 +
 unit-tests/dds-testsuite/S2000415.HDF.test1.das    |    20 +
 unit-tests/dds-testsuite/coads_climatology.nc.das  |    50 +
 unit-tests/dds-testsuite/coads_climatology.nc.dds  |    34 +
 unit-tests/dds-testsuite/config/unix.exp           |    55 +
 unit-tests/dds-testsuite/dds-test.0/test.1.exp     |    51 +
 unit-tests/dds-testsuite/dds-test.0/test.10.exp    |   113 +
 unit-tests/dds-testsuite/dds-test.0/test.11.exp    |    74 +
 unit-tests/dds-testsuite/dds-test.0/test.12.exp    |    53 +
 unit-tests/dds-testsuite/dds-test.0/test.13.exp    |    66 +
 unit-tests/dds-testsuite/dds-test.0/test.14.exp    |    48 +
 unit-tests/dds-testsuite/dds-test.0/test.15.exp    |    54 +
 unit-tests/dds-testsuite/dds-test.0/test.16.exp    |    55 +
 unit-tests/dds-testsuite/dds-test.0/test.17.exp    |    68 +
 unit-tests/dds-testsuite/dds-test.0/test.18.exp    |    46 +
 unit-tests/dds-testsuite/dds-test.0/test.19.exp    |    54 +
 unit-tests/dds-testsuite/dds-test.0/test.2.exp     |    50 +
 unit-tests/dds-testsuite/dds-test.0/test.20.exp    |    50 +
 unit-tests/dds-testsuite/dds-test.0/test.3.exp     |    50 +
 unit-tests/dds-testsuite/dds-test.0/test.4.exp     |    58 +
 unit-tests/dds-testsuite/dds-test.0/test.6.exp     |    58 +
 unit-tests/dds-testsuite/dds-test.0/test.7.exp     |    65 +
 unit-tests/dds-testsuite/dds-test.0/test.8.exp     |    69 +
 unit-tests/dds-testsuite/dds-test.0/test.9.exp     |    80 +
 unit-tests/dds-testsuite/fnoc1.nc.das              |    32 +
 unit-tests/dds-testsuite/fnoc1.nc.dds              |     7 +
 .../dds-testsuite/hdf_dimension_attribute_grid.das |    12 +
 .../dds-testsuite/hdf_dimension_attribute_grid.dds |    11 +
 unit-tests/dds-testsuite/test.1                    |     7 +
 unit-tests/dds-testsuite/test.10                   |    45 +
 unit-tests/dds-testsuite/test.11                   |    37 +
 unit-tests/dds-testsuite/test.12                   |     6 +
 unit-tests/dds-testsuite/test.13                   |     6 +
 unit-tests/dds-testsuite/test.14                   |     4 +
 unit-tests/dds-testsuite/test.15                   |     8 +
 unit-tests/dds-testsuite/test.16                   |    21 +
 unit-tests/dds-testsuite/test.17                   |    12 +
 unit-tests/dds-testsuite/test.18                   |    12 +
 unit-tests/dds-testsuite/test.19                   |    14 +
 unit-tests/dds-testsuite/test.19b                  |    14 +
 unit-tests/dds-testsuite/test.19b.das              |    33 +
 unit-tests/dds-testsuite/test.19c                  |     6 +
 unit-tests/dds-testsuite/test.19c.das              |    12 +
 unit-tests/dds-testsuite/test.19d                  |     6 +
 unit-tests/dds-testsuite/test.19d.das              |     8 +
 unit-tests/dds-testsuite/test.19d1.das             |    11 +
 unit-tests/dds-testsuite/test.19e                  |     6 +
 unit-tests/dds-testsuite/test.19e.das              |    12 +
 unit-tests/dds-testsuite/test.19f                  |    11 +
 unit-tests/dds-testsuite/test.19f.das              |    13 +
 unit-tests/dds-testsuite/test.19f1.das             |    16 +
 unit-tests/dds-testsuite/test.19g                  |    14 +
 unit-tests/dds-testsuite/test.19g.das              |    23 +
 unit-tests/dds-testsuite/test.2                    |     4 +
 unit-tests/dds-testsuite/test.20                   |    12 +
 unit-tests/dds-testsuite/test.3                    |     4 +
 unit-tests/dds-testsuite/test.4                    |     6 +
 unit-tests/dds-testsuite/test.6                    |     6 +
 unit-tests/dds-testsuite/test.7                    |    10 +
 unit-tests/dds-testsuite/test.8                    |    14 +
 unit-tests/dds-testsuite/test.9                    |    22 +
 unit-tests/ddsT.cc                                 |   630 +
 unit-tests/ddx-testsuite/D1.ddx                    |    21 +
 unit-tests/ddx-testsuite/DDX_from_dataddx.xml      |    37 +
 unit-tests/ddx-testsuite/EOSDB.ddx                 |   187 +
 .../ddx-testsuite/dataddx_without_top_headers.dap  |   Bin 0 -> 1712 bytes
 unit-tests/ddx-testsuite/error.01.ddx              |     7 +
 unit-tests/ddx-testsuite/error.02.ddx              |    10 +
 unit-tests/ddx-testsuite/error.03.ddx              |    11 +
 unit-tests/ddx-testsuite/error.04.ddx              |    17 +
 unit-tests/ddx-testsuite/error.05.ddx              |    12 +
 unit-tests/ddx-testsuite/error.06.ddx              |     9 +
 unit-tests/ddx-testsuite/test.00.ddx               |     9 +
 unit-tests/ddx-testsuite/test.01.ddx               |    16 +
 unit-tests/ddx-testsuite/test.01.error.ddx         |    45 +
 unit-tests/ddx-testsuite/test.01.orig.ddx          |    45 +
 unit-tests/ddx-testsuite/test.02.ddx               |    19 +
 unit-tests/ddx-testsuite/test.03.ddx               |    21 +
 unit-tests/ddx-testsuite/test.04.ddx               |    18 +
 unit-tests/ddx-testsuite/test.05.ddx               |   197 +
 unit-tests/ddx-testsuite/test.06.ddx               |    44 +
 unit-tests/ddx-testsuite/test.07.ddx               |    77 +
 unit-tests/ddx-testsuite/test.08.ddx               |    39 +
 unit-tests/ddx-testsuite/test.09.ddx               |    57 +
 unit-tests/ddx-testsuite/test.0a.ddx               |    30 +
 unit-tests/ddx-testsuite/test.0b.ddx               |    47 +
 unit-tests/ddx-testsuite/test.0c.ddx               |    12 +
 unit-tests/ddx-testsuite/test.0d.ddx               |    10 +
 unit-tests/ddx-testsuite/test.1.other_xml.ddx      |    15 +
 unit-tests/ddx-testsuite/test.2.other_xml.ddx      |    20 +
 unit-tests/ddx-testsuite/test.3.other_xml.ddx      |    77 +
 unit-tests/generalUtilTest.cc                      |   335 +
 unit-tests/marshT.cc                               |   486 +
 unit-tests/parserUtilTest.cc                       |   145 +
 unit-tests/rcreader-testsuite/dodsrc_ssl_1         |    17 +
 unit-tests/rcreader-testsuite/dodsrc_ssl_2         |    19 +
 unit-tests/rcreader-testsuite/dodsrc_ssl_3         |    19 +
 unit-tests/rcreader-testsuite/test1.rc             |    19 +
 unit-tests/rcreader-testsuite/test2.rc             |    16 +
 unit-tests/rcreader-testsuite/test3.rc             |    17 +
 unit-tests/rcreader-testsuite/test4.rc             |    19 +
 unit-tests/rcreader-testsuite/test5.rc             |    19 +
 unit-tests/sequenceT.cc                            |   143 +
 unit-tests/server-testsuite/bears.data             |     9 +
 unit-tests/server-testsuite/coads.data             |     1 +
 unit-tests/server-testsuite/coads.data.das         |     6 +
 unit-tests/server-testsuite/config/unix.exp        |    48 +
 unit-tests/server-testsuite/dsp_1.data             |     2 +
 unit-tests/server-testsuite/ff_test1_ce1.data      |     5 +
 unit-tests/server-testsuite/ff_test1_ce2.data      |     5 +
 unit-tests/server-testsuite/ff_test2_ce1.data      |     5 +
 unit-tests/server-testsuite/ff_test2_ce2.data      |     5 +
 unit-tests/server-testsuite/ff_test2_ce3.data      |     5 +
 unit-tests/server-testsuite/fnoc1.data             |     2 +
 unit-tests/server-testsuite/geturl.0/dodsdev.exp   |   102 +
 unit-tests/server-testsuite/geturl.0/urls.tcl      |   275 +
 unit-tests/server-testsuite/jg_diatoms.data        |     7 +
 unit-tests/server-testsuite/jg_test.data           |     9 +
 unit-tests/server-testsuite/nscat_hdf.data         |     5 +
 unit-tests/server-testsuite/nscat_s2.data          |     2 +
 unit-tests/structT.cc                              |   154 +
 unit-tests/testFile.cc                             |    36 +
 unit-tests/test_config.h                           |     7 +
 unit-tests/test_config.h.in                        |     7 +
 util.cc                                            |   567 +
 util.h                                             |   149 +
 util_mit.cc                                        |   368 +
 util_mit.h                                         |    36 +
 xdr-datatypes-config.h.in                          |    30 +
 xdr-datatypes-static.h                             |    56 +
 xdr-datatypes.h                                    |    31 +
 xdrutil_ppc.c                                      |    41 +
 841 files changed, 210053 insertions(+)

diff --git a/AlarmHandler.h b/AlarmHandler.h
new file mode 100644
index 0000000..8f78abe
--- /dev/null
+++ b/AlarmHandler.h
@@ -0,0 +1,109 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef alarm_handler_h
+#define alarm_handler_h
+
+#include <cstdio>
+
+#include <string>
+
+#include "EventHandler.h"
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** Handle the time out alarm. When an OPeNDAP server runs until the time out
+    alarm is triggered, this class provides the concrete implementation of
+    EventHandler::handle_signal().
+
+    @see EventHandler
+    @see SignalHandler
+    @author James Gallagher <jgallagher at opendap.org> */
+class AlarmHandler : public EventHandler
+{
+private:
+#if FILE_METHODS
+    FILE *d_file;  // Sink for the Error object.
+#endif
+    ostream &d_stream;
+    string d_version;
+
+    // Ensure that d_stream gets initialized...
+    AlarmHandler() :
+#if FILE_METHODS
+        d_file( 0 ),
+#endif
+        d_stream( cout )
+    {}
+
+public:
+#if FILE_METHODS
+    AlarmHandler(FILE *s) : d_file(s), d_stream( cout )
+    {}
+#endif
+    /** Store information to be used by the handler.
+    @param out Write to this stream. */
+    AlarmHandler(ostream &out) :
+#if FILE_METHODS
+        d_file(0),
+#endif
+        d_stream( out )
+    {}
+
+    virtual ~AlarmHandler()
+    {
+#if FILE_METHODS
+        if( d_file )
+            fclose( d_file ) ;
+#endif
+    }
+
+    /** Handle an alarm signal. When one of our servers gets an alarm, that
+    means it has hit its time out. We need to dump two CRLF pairs down
+    the stream and then send an Error object explaining that a timeout
+    has been reached.
+
+    Because this is a signal handler, it should call only reentrant
+    system services, functions, et cetera. Generally that eliminates
+    stdio functions but I'm using them anyway. This handler never returns
+    to the code that was running when the alarm signal was raised.
+
+    @param signum We know it is SIGALRM; here as a check
+    @return Never returns; calls exit after sending the Error object. */
+    virtual void handle_signal(int signum)
+    {
+        if (signum != SIGALRM)
+            fprintf(stderr, "SIGALRM handler caught another signal!\n");
+        exit(1);
+    }
+
+};
+
+} // namespace libdap
+
+#endif
diff --git a/Ancillary.cc b/Ancillary.cc
new file mode 100644
index 0000000..d23ed62
--- /dev/null
+++ b/Ancillary.cc
@@ -0,0 +1,227 @@
+// Ancillary.cc
+
+#include "config.h"
+#include "Ancillary.h"
+#include "debug.h"
+
+#ifndef WIN32
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+// Win32 does not define this. 08/21/02 jhrg
+#define F_OK 0
+#endif
+
+namespace libdap {
+
+/** This function accepts a dataset path name, and searches for a
+    matching ancillary data file name with a very specific set of
+    search rules, given here:
+
+    <pre>
+    directory           filename          extension
+    same                same            `.'given
+    given               same            `.'given
+    same                given           `.'given
+    given               given           `.'given
+    </pre>
+
+    Where ``same'' refers to the input dataset pathname, and ``given''
+    refers to the function arguments.
+
+    For example, If you call this function with a
+    dataset name of <tt>/a/data</tt>, an extension of <tt>das</tt>, a
+    directory of
+    <tt>b</tt>, and a filename of <tt>ralph</tt>, the function will
+    look (in order)
+    for the following files:
+
+    <pre>
+    /a/data.das
+    /b/data.das
+    /a/ralph.das
+    /b/ralph.das
+    </pre>
+
+    The function will return a string containing the name of the first
+    file in the list that exists, if any.
+
+    @note This code now checks for <code>pathname.ext</code> 3/17/99 jhrg
+
+    @brief Find a file with ancillary data.
+    @param pathname The input pathname of a dataset.
+    @param ext The input extension the desired file is to have.
+    @param dir The input directory in which the desired file may be
+    found.
+    @param file The input filename the desired file may have.
+    @return A string containing the pathname of the file found by
+    searching with the given components.  If no file was found, the
+    null string is returned.
+*/
+string
+Ancillary::find_ancillary_file( const string &pathname,
+				const string &ext,
+				const string &dir,
+				const string &file )
+{
+    string::size_type slash = pathname.rfind('/') + 1;
+    string directory = pathname.substr(0, slash);
+    string filename = pathname.substr(slash);
+    string basename = pathname.substr(slash, pathname.rfind('.') - slash);
+
+    DBG(cerr << "find ancillary file params: " << pathname << ", " << ext
+        << ", " << dir << ", " << file << endl);
+    DBG(cerr << "find ancillary file comp: " << directory << ", " << filename
+        << ", " << basename << endl);
+
+    string dot_ext = "." + ext;
+
+    string name = directory + basename + dot_ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    name = pathname + dot_ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    name = directory + ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    name = dir + basename + dot_ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    name = directory + file + dot_ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    name = dir + file + dot_ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    name = dir + ext;
+    if (access(name.c_str(), F_OK) == 0)
+        return name;
+
+    return "";
+}
+
+// Given a pathname to a datafile, take that pathname apart and look for an
+// ancillary file that describes a group of datafiles of which this datafile
+// is a member. Assume that groups follow a simple naming convention where
+// files use either leading or trailing digits and a common basename to name
+// group members. For example, 00stuff.hdf, 01stuff.hdf, 02stuff.hdf, ..., is
+// a group and is has `stuff' as its basename.
+
+/** Assume that <tt>name</tt> refers to a file that is one of a
+    group of files which share a common `base' name and differ only by
+    some prefix or suffix digits (e.g. <tt>00base</tt>, <tt>01base</tt>,
+    ... or <tt>base00</tt>, ... have the base name <tt>base</tt>). This
+    function looks for a file <tt>base.ext</tt>.
+
+    @param name The name (full or relative) to one member of a group
+    of files.
+    @param ext The extension of the group's ancillary file. Note that
+    <tt>ext</tt> should include a period (.) if that needs to
+    separate the base name from the extension.
+    @return The pathname to the group's ancillary file if found, otherwise
+    the empty string (""). */
+string
+Ancillary::find_group_ancillary_file( const string &name, const string &ext )
+{
+    // Given /usr/local/data/stuff.01.nc
+    // pathname = /usr/local/data, filename = stuff.01.nc and
+    // rootname = stuff.01
+    string::size_type slash = name.find_last_of('/');
+    string dirname = name.substr(0, slash);
+    string filename = name.substr(slash + 1);
+    string rootname = filename.substr(0, filename.find_last_of('.'));
+
+    // Instead of using regexs, scan the filename for leading and then
+    // trailing digits.
+    string::iterator rootname_iter = rootname.begin();
+    string::iterator rootname_end_iter = rootname.end();
+    if (isdigit(*rootname_iter)) {
+        while (rootname_iter != rootname_end_iter
+               && isdigit(*++rootname_iter))
+            ;
+
+        // We want: new_name = dirname + "/" + <base> + ext but without
+        // creating a bunch of temp objects.
+        string new_name = dirname;
+        new_name.append("/");
+        new_name.append(rootname_iter, rootname_end_iter);
+        new_name.append(ext);
+        DBG(cerr << "New Name (iter): " << new_name << endl);
+        if (access(new_name.c_str(), F_OK) == 0) {
+            return new_name;
+        }
+    }
+
+    string::reverse_iterator rootname_riter = rootname.rbegin();
+    string::reverse_iterator rootname_end_riter = rootname.rend();
+    if (isdigit(*rootname_riter)) {
+        while (rootname_riter != rootname_end_riter
+               && isdigit(*++rootname_riter))
+            ;
+        string new_name = dirname;
+        new_name.append("/");
+        // I used reverse iters to scan rootname backwards. To avoid
+        // reversing the fragment between end_riter and riter, pass append
+        // regular iters obtained using reverse_iterator::base(). See Meyers
+        // p. 123. 1/22/2002 jhrg
+        new_name.append(rootname_end_riter.base(), rootname_riter.base());
+        new_name.append(ext);
+        DBG(cerr << "New Name (riter): " << new_name << endl);
+        if (access(new_name.c_str(), F_OK) == 0) {
+            return new_name;
+        }
+    }
+
+    // If we're here either the file does not begin with leading digits or a
+    // template made by removing those digits was not found.
+
+    return "";
+}
+
+void
+Ancillary::read_ancillary_das( DAS &das,
+			       const string &pathname,
+			       const string &dir,
+			       const string &file )
+{
+    string name = find_ancillary_file( pathname, "das", dir, file ) ;
+
+    FILE *in = fopen( name.c_str(), "r" ) ;
+    if( in ) {
+        das.parse( in ) ;
+        int res = fclose( in ) ;
+        if( res )
+            DBG(cerr << "Ancillary::read_ancillary_das - Failed to close file " << (void *)in << endl) ;
+    }
+}
+
+void
+Ancillary::read_ancillary_dds( DDS &dds,
+			       const string &pathname,
+			       const string &dir,
+			       const string &file )
+{
+    string name = find_ancillary_file( pathname, "dds", dir, file ) ;
+
+    FILE *in = fopen( name.c_str(), "r" ) ;
+    if( in ) {
+        dds.parse( in ) ;
+        int res = fclose( in ) ;
+        if( res )
+            DBG(cerr << "Ancillary::read_ancillary_das - Failed to close file " << (void *)in << endl) ;
+    }
+}
+
+} // namespace libdap
+
diff --git a/Ancillary.h b/Ancillary.h
new file mode 100644
index 0000000..b458a1e
--- /dev/null
+++ b/Ancillary.h
@@ -0,0 +1,73 @@
+// Ancillary.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//         Patrick West <pwest at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+//      pwest           Patrick West <pwest at opendap.org>
+
+#ifndef S_Ancillary_h
+#define S_Ancillary_h 1
+
+#include <string>
+
+using std::string ;
+
+#include "DAS.h"
+#include "DDS.h"
+
+namespace libdap
+{
+
+class Ancillary
+{
+public:
+    static string	find_ancillary_file( const string &pathname,
+					     const string &ext,
+					     const string &dir,
+					     const string &file ) ;
+
+    static string	find_group_ancillary_file( const string &pathname,
+						   const string &ext ) ;
+
+    static void		read_ancillary_das( DAS &das,
+					    const string &pathname,
+					    const string &dir = "",
+					    const string &file = "" ) ;
+
+    static void		read_ancillary_dds( DDS &dds,
+					    const string &pathname,
+					    const string &dir = "",
+					    const string &file = "" ) ;
+} ;
+
+} // namespace libdap
+
+#endif // S_Ancillary_h
+
diff --git a/Array.cc b/Array.cc
new file mode 100644
index 0000000..7d86355
--- /dev/null
+++ b/Array.cc
@@ -0,0 +1,919 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Array.
+//
+// jhrg 9/13/94
+
+
+#include "config.h"
+
+#include "Array.h"
+#include "util.h"
+#include "debug.h"
+#include "InternalErr.h"
+#include "escaping.h"
+
+#include <algorithm>
+#include <functional>
+
+using namespace std;
+
+namespace libdap {
+
+void
+Array::_duplicate(const Array &a)
+{
+    _shape = a._shape;
+}
+
+// The first method of calculating length works when only one dimension is
+// constrained and you want the others to appear in total. This is important
+// when selecting from grids since users may not select from all dimensions
+// in which case that means they want the whole thing. Array projection
+// should probably work this way too, but it doesn't. 9/21/2001 jhrg
+
+/** @deprecated Calling this method should never be necessary. It is called
+    whenever the size of the Array is changed.
+
+    Changes the size property of the array.  If the array
+    exists, it is augmented by a factor of <tt>size</tt>. This does
+    not change the actual size of the array.
+*/
+void
+Array::update_length(int)
+{
+    int length = 1;
+    for (Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
+        length *= (*i).c_size > 0 ? (*i).c_size : 1;
+    }
+
+    set_length(length);
+}
+
+// Construct an instance of Array. The (BaseType *) is assumed to be
+// allocated using new - The dtor for Vector will delete this object.
+
+/** Build an array with a name and an element type. The name may be omitted,
+    which will create a nameless variable. The template (element type) pointer
+    may also be omitted, but if it is omitted when the Array is created, it
+    \e must be added (with \c add_var()) before \c read() or \c deserialize()
+    is called.
+
+    @todo Force the Array::add_var() method to be used to add \e v.
+    This version of add_var() calls Vector::add_var().
+
+    @param n A string containing the name of the variable to be
+    created.
+    @param v A pointer to a variable of the type to be included
+    in the Array.
+    @brief Array constructor
+*/
+Array::Array(const string &n, BaseType *v) : Vector(n, 0, dods_array_c)
+{
+    add_var(v); // Vector::add_var() stores null is v is null
+}
+
+/** Build an array on the server-side with a name, a dataset name from which
+    this Array is being created, and an element type.
+
+    @todo Force the Array::add_var() method to be used to add \e v.
+    This version of add_var() calls Vector::add_var().
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is being created.
+    @param v A pointer to a variable of the type to be included
+    in the Array.
+    @brief Array constructor
+*/
+Array::Array(const string &n, const string &d, BaseType *v)
+    : Vector(n, d, 0, dods_array_c)
+{
+    add_var(v); // Vector::add_var() stores null is v is null
+}
+
+/** @brief The Array copy constructor. */
+Array::Array(const Array &rhs) : Vector(rhs)
+{
+    _duplicate(rhs);
+}
+
+/** @brief The Array destructor. */
+Array::~Array()
+{
+    DBG(cerr << "Entering ~Array (" << this << ")" << endl);
+    DBG(cerr << "Exiting ~Array" << endl);
+}
+
+BaseType *
+Array::ptr_duplicate()
+{
+    return new Array(*this);
+}
+
+Array &
+Array::operator=(const Array &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<Vector &>(*this) = rhs;
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+/** @brief Add the BaseType pointer to this constructor type
+    instance.
+
+    Propagate the name of the BaseType instance to this instance. This
+    ensures that variables at any given level of the DDS table have
+    unique names (i.e., that Arrays do not have their default name ""). If
+    <tt>v</tt>'s name is null, then assume that the array \e is named and
+    don't overwrite it with <tt>v</tt>'s null name.
+
+    @note This version checks to see if \e v is an array. If so, it calls
+    Vector::add_var() using the template variable of \e v and then appends
+    the dimensions of \e v to this array. This somewhat obscure behavior
+    simplifies 'translating' Sequences to arrays when the actual variable
+    being translated is not a regular Sequence but an array of Sequences.
+
+    @param v The template variable for the array
+    @param p The Part parameter defaults to nil and is ignored by this method.
+*/
+
+void
+Array::add_var(BaseType *v, Part)
+{
+    if (v && v->type() == dods_array_c) {
+        Array &a = dynamic_cast<Array&>(*v);
+        Vector::add_var(a.var());
+        Dim_iter i = a.dim_begin();
+        Dim_iter i_end = a.dim_end();
+        while (i != i_end) {
+            append_dim(a.dimension_size(i), a.dimension_name(i));
+            ++i;
+        }
+    }
+    else {
+        Vector::add_var(v);
+    }
+}
+
+/** Given a size and a name, this function adds a dimension to the
+    array.  For example, if the Array is already 10 elements long,
+    calling <tt>append_dim</tt> with a size of 5 will transform the array
+    into a 10x5 matrix.  Calling it again with a size of 2 will
+    create a 10x5x2 array, and so on.  This sets Vector's length
+    member as a side effect.
+
+    @param size The size of the desired new row.
+    @param name The name of the new dimension.  This defaults to
+    an empty string.
+    @brief Add a dimension of a given size. */
+void
+Array::append_dim(int size, string name)
+{
+    dimension d;
+
+    // This is invariant
+    d.size = size;
+    d.name = www2id(name);
+
+    // this information changes with each constraint expression
+    d.start = 0;
+    d.stop = size - 1;
+    d.stride = 1;
+    d.c_size = size;
+
+    _shape.push_back(d);
+
+    update_length(size);
+}
+
+/** Creates a new OUTER dimension (slowest varying in rowmajor)
+ * for the array by prepending rather than appending it.
+ * @param size cardinality of the new dimension
+ * @param name  optional name for the new dimension
+ */
+void
+Array::prepend_dim(int size, const string& name/* = "" */)
+{
+  dimension d;
+
+  // This is invariant
+  d.size = size;
+  d.name = www2id(name);
+
+  // this information changes with each constraint expression
+  d.start = 0;
+  d.stop = size - 1;
+  d.stride = 1;
+  d.c_size = size;
+
+  // Shifts the whole array, but it's tiny in general
+  _shape.insert(_shape.begin(), d);
+
+  update_length(size); // the number is ignored...
+}
+
+/** Resets the dimension constraint information so that the entire
+    array is selected.
+
+    @brief Reset constraint to select entire array.
+*/
+
+void
+Array::reset_constraint()
+{
+    set_length(-1);
+
+    for (Dim_iter i = _shape.begin(); i != _shape.end(); i++) {
+        (*i).start = 0;
+        (*i).stop = (*i).size - 1;
+        (*i).stride = 1;
+        (*i).c_size = (*i).size;
+
+        update_length((*i).size);
+    }
+}
+
+
+/** Tell the Array object to clear the constraint information about
+    dimensions. Do this <i>once</i> before calling <tt>add_constraint()</tt>
+    for each new constraint expression. Only the dimensions explicitly
+    selected using <tt>add_constraint()</tt> will be sent.
+
+    @deprecated This should never be used.
+    @brief Clears the projection; add each projected dimension explicitly using
+    <tt>add_constraint</tt>.
+*/
+void
+Array::clear_constraint()
+{
+    reset_constraint();
+}
+
+// Note: MS VC++ won't tolerate embedded newlines in strings, hence the \n
+// is explicit.
+static const char *array_sss = \
+"Invalid constraint parameters: At least one of the start, stride or stop \n\
+specified do not match the array variable.";
+
+/** Once a dimension has been created (see append_dim()), it can
+    be constrained.  This will make the array appear to the rest
+    of the world to be smaller than it is.  This functions sets the
+    projection for a dimension, and marks that dimension as part of the
+    current projection.
+
+    @note A stride value <= 0 or > the array size is an error and causes
+    add_constraint to throw an Error. Similarly, start or stop values >
+    size also cause an Error exception to be thrown.
+
+    @brief Adds a constraint to an Array dimension.
+
+    @param i An iterator pointing to the dimension in the list of
+    dimensions.
+    @param start The start index of the constraint.
+    @param stride The stride value of the constraint.
+    @param stop The stop index of the constraint.
+    @exception Error Thrown if the any of values of start, stop or stride
+    cannot be applied to this array. */
+void
+Array::add_constraint(Dim_iter i, int start, int stride, int stop)
+{
+    dimension &d = *i ;
+
+    // Check for bad constraints.
+    // Jose Garcia
+    // Usually invalid data for a constraint is the user's mistake
+    // because they build a wrong URL in the client side.
+    if (start >= d.size || stop >= d.size || stride > d.size || stride <= 0)
+        throw Error(malformed_expr, array_sss);
+
+    if (((stop - start) / stride + 1) > d.size)
+        throw Error(malformed_expr, array_sss);
+
+    d.start = start;
+    d.stop = stop;
+    d.stride = stride;
+
+    d.c_size = (stop - start) / stride + 1;
+
+    DBG(cerr << "add_constraint: c_size = " << d.c_size << endl);
+
+    update_length(d.c_size);
+}
+
+/** Returns an iterator to the first dimension of the Array. */
+Array::Dim_iter
+Array::dim_begin()
+{
+    return _shape.begin() ;
+}
+
+/** Returns an iterator past the last dimension of the Array. */
+Array::Dim_iter
+Array::dim_end()
+{
+    return _shape.end() ;
+}
+
+/** Return the total number of dimensions contained in the array.
+    When <i>constrained</i> is TRUE, return the number of dimensions
+    given the most recently evaluated constraint expression.
+
+    @brief Return the total number of dimensions in the array.
+    @param constrained A boolean flag to indicate whether the array is
+    constrained or not.  Ignored.
+*/
+
+unsigned int
+Array::dimensions(bool /*constrained*/)
+{
+    unsigned int dim = 0;
+    for (Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
+        dim++;
+    }
+
+    return dim;
+}
+
+/** Return the size of the array dimension referred to by <i>i</i>.
+    If the dimension is constrained the constrained size is returned if
+    <i>constrained</i> is \c true.
+
+    @brief Returns the size of the dimension.
+
+    @param i The dimension.
+
+    @param constrained If this parameter is TRUE, the method returns the
+    constrained size of the array so long as a constraint has been applied to
+    this dimension. If TRUE and no constraint has been applied, this method
+    returns zero. If it is FALSE, the method ignores any constraint that
+    has been applied to this dimension and returns the full size of the
+    dimension. The default value is FALSE.
+
+    @return An integer containing the size of the specified dimension.
+*/
+int
+Array::dimension_size(Dim_iter i, bool constrained)
+{
+    int size = 0;
+
+    if (!_shape.empty()) {
+        if (constrained)
+            size = (*i).c_size;
+        else
+            size = (*i).size;
+    }
+
+    return size;
+}
+
+/** Use this function to return the start index of an array
+    dimension.  If the array is constrained (indicated with the
+    <i>constrained</i> argument), the start index of the constrained
+    array is returned (or zero if the dimension in question is not
+    selected at all).  See also <tt>dimension_stop()</tt> and
+    <tt>dimension_stride()</tt>.
+
+    @brief Return the start index of a dimension.
+
+    @param i The dimension.
+    @param constrained If this parameter is TRUE, the function
+    returns the start index only if the dimension is constrained
+    (subject to a start, stop, or stride constraint).  If
+    the dimension is not constrained, the function returns zero.  If it
+    is FALSE, the function returns the start index whether or not
+    the dimension is constrained.
+    @return The desired start index.
+*/
+int
+Array::dimension_start(Dim_iter i, bool /*constrained*/)
+{
+    return (!_shape.empty()) ? (*i).start : 0;
+}
+
+/** Use this function to return the stop index of an array
+    dimension.  If the array is constrained (indicated with the
+    <i>constrained</i> argument), the stop index of the constrained
+    array is returned (or zero if the dimension in question is not
+    selected at all).  See also <tt>dimension_start()</tt> and
+    <tt>dimension_stride()</tt>.
+
+    @brief Return the stop index of the constraint.
+
+    @param i The dimension.
+    @param constrained If this parameter is TRUE, the function
+    returns the stop index only if the dimension is  constrained
+    (subject to a start, stop, or stride constraint).  If
+    the dimension is not constrained, the function returns zero.  If it
+    is FALSE, the function returns the stop index whether or not
+    the dimension is constrained.
+    @return The desired stop index.
+*/
+int
+Array::dimension_stop(Dim_iter i, bool /*constrained*/)
+{
+    return (!_shape.empty()) ? (*i).stop : 0;
+}
+
+/** Use this function to return the stride value of an array
+    dimension.  If the array is constrained (indicated with the
+    <i>constrained</i> argument), the stride value of the constrained
+    array is returned (or zero if the dimension in question is not
+    selected at all).  See also <tt>dimension_stop()</tt> and
+    <tt>dimension_start()</tt>.
+
+    @brief Returns the stride value of the constraint.
+
+    @param i The dimension.
+    @param constrained If this parameter is TRUE, the function
+    returns the stride value only if the dimension is constrained
+    (subject to a start, stop, or stride constraint).  If
+    the dimension is not constrained, the function returns zero.  If it
+    is FALSE, the function returns the stride value whether or not
+    the dimension is constrained.
+    @return The stride value requested, or zero, if <i>constrained</i>
+    is TRUE and the dimension is not selected.
+*/
+int
+Array::dimension_stride(Dim_iter i, bool /*constrained*/)
+{
+    return (!_shape.empty()) ? (*i).stride : 0;
+}
+
+/** This function returns the name of the dimension indicated with
+    <i>p</i>.  Since this method is public, it is possible to call it
+    before the Array object has been properly initialized.  This will
+    cause an exception.  So don't do that.
+
+    @brief Returns the name of the specified dimension.
+
+    @param i The dimension.
+    @return A pointer to a string containing the dimension name.
+*/
+string
+Array::dimension_name(Dim_iter i)
+{
+    // Jose Garcia
+    // Since this method is public, it is possible for a user
+    // to call it before the Array object has been properly set
+    // this will cause an exception which is the user's fault.
+    // (User in this context is the developer of the surrogate library.)
+    if (_shape.empty())
+        throw  InternalErr(__FILE__, __LINE__,
+                           "*This* array has no dimensions.");
+    return (*i).name;
+}
+
+#if FILE_METHODS
+/** Prints a declaration for the Array.  This is what appears in a
+    DDS.  If the Array is constrained, the declaration will reflect
+    the size of the Array once the constraint is applied.
+
+    @brief Prints a DDS entry for the Array.
+
+    @param out Write the output to this FILE *.
+    @param space A string containing spaces to precede the
+    declaration.
+    @param print_semi A boolean indicating whether to print a
+    semi-colon after the declaration.  (TRUE means ``print a
+    semi-colon.'')
+    @param constraint_info A boolean value.  See
+    <tt>BaseType::print_decl()</tt>.
+    @param constrained This argument should be TRUE if the Array is
+    constrained, and FALSE otherwise.
+*/
+void
+Array::print_decl(FILE *out, string space, bool print_semi,
+                  bool constraint_info, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    // print it, but w/o semicolon
+    var()->print_decl(out, space, false, constraint_info, constrained);
+
+    for (Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
+        fprintf(out, "[") ;
+        if ((*i).name != "") {
+            fprintf(out, "%s = ", id2www((*i).name).c_str()) ;
+        }
+        if (constrained) {
+            fprintf(out, "%d]", (*i).c_size) ;
+        }
+        else {
+            fprintf(out, "%d]", (*i).size) ;
+        }
+    }
+
+    if (print_semi) {
+        fprintf(out, ";\n") ;
+    }
+}
+#endif
+
+/** Prints a declaration for the Array.  This is what appears in a
+    DDS.  If the Array is constrained, the declaration will reflect
+    the size of the Array once the constraint is applied.
+
+    @brief Prints a DDS entry for the Array.
+
+    @param out Write the output to this ostream.
+    @param space A string containing spaces to precede the
+    declaration.
+    @param print_semi A boolean indicating whether to print a
+    semi-colon after the declaration.  (TRUE means ``print a
+    semi-colon.'')
+    @param constraint_info A boolean value.  See
+    <tt>BaseType::print_decl()</tt>.
+    @param constrained This argument should be TRUE if the Array is
+    constrained, and FALSE otherwise.
+*/
+void
+Array::print_decl(ostream &out, string space, bool print_semi,
+                  bool constraint_info, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    // print it, but w/o semicolon
+    var()->print_decl(out, space, false, constraint_info, constrained);
+
+    for (Dim_citer i = _shape.begin(); i != _shape.end(); i++) {
+	out << "[" ;
+        if ((*i).name != "") {
+	    out << id2www((*i).name) << " = " ;
+        }
+        if (constrained) {
+	    out << (*i).c_size << "]" ;
+        }
+        else {
+	    out << (*i).size << "]" ;
+        }
+    }
+
+    if (print_semi) {
+	out << ";\n" ;
+    }
+}
+#if FILE_METHODS
+void
+Array::print_xml(FILE *out, string space, bool constrained)
+{
+    print_xml_core(out, space, constrained, "Array");
+}
+#endif
+void
+Array::print_xml(ostream &out, string space, bool constrained)
+{
+    print_xml_core(out, space, constrained, "Array");
+}
+#if FILE_METHODS
+void
+Array::print_as_map_xml(FILE *out, string space, bool constrained)
+{
+    print_xml_core(out, space, constrained, "Map");
+}
+#endif
+void
+Array::print_as_map_xml(ostream &out, string space, bool constrained)
+{
+    print_xml_core(out, space, constrained, "Map");
+}
+#if FILE_METHODS
+class PrintArrayDim : public unary_function<Array::dimension&, void>
+{
+    FILE *d_out;
+    string d_space;
+    bool d_constrained;
+public:
+    PrintArrayDim(FILE *o, string s, bool c)
+            : d_out(o), d_space(s), d_constrained(c)
+    {}
+
+    void operator()(Array::dimension &d)
+    {
+        int size = d_constrained ? d.c_size : d.size;
+        if (d.name.empty())
+            fprintf(d_out, "%s<dimension size=\"%d\"/>\n", d_space.c_str(),
+                    size);
+        else
+            fprintf(d_out, "%s<dimension name=\"%s\" size=\"%d\"/>\n",
+                    d_space.c_str(), id2xml(d.name).c_str(), size);
+    }
+};
+
+void
+Array::print_xml_core(FILE *out, string space, bool constrained, string tag)
+{
+    if (constrained && !send_p())
+        return;
+
+    fprintf(out, "%s<%s", space.c_str(), tag.c_str());
+    if (!name().empty())
+        fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
+    fprintf(out , ">\n");
+
+    get_attr_table().print_xml(out, space + "    ", constrained);
+
+    BaseType *btp = var();
+    string tmp_name = btp->name();
+    btp->set_name("");
+    btp->print_xml(out, space + "    ", constrained);
+    btp->set_name(tmp_name);
+
+    for_each(dim_begin(), dim_end(),
+             PrintArrayDim(out, space + "    ", constrained));
+
+    fprintf(out, "%s</%s>\n", space.c_str(), tag.c_str());
+}
+#endif
+
+class PrintArrayDimStrm : public unary_function<Array::dimension&, void>
+{
+    ostream &d_out;
+    string d_space;
+    bool d_constrained;
+public:
+    PrintArrayDimStrm(ostream &o, string s, bool c)
+            : d_out(o), d_space(s), d_constrained(c)
+    {}
+
+    void operator()(Array::dimension &d)
+    {
+        int size = d_constrained ? d.c_size : d.size;
+        if (d.name.empty())
+	    d_out << d_space << "<dimension size=\"" << size << "\"/>\n" ;
+        else
+	    d_out << d_space << "<dimension name=\"" << id2xml(d.name)
+	          << "\" size=\"" << size << "\"/>\n" ;
+    }
+};
+
+void
+Array::print_xml_core(ostream &out, string space, bool constrained, string tag)
+{
+    if (constrained && !send_p())
+        return;
+
+    out << space << "<" << tag ;
+    if (!name().empty())
+	out << " name=\"" << id2xml(name()) << "\"" ;
+    out << ">\n" ;
+
+    get_attr_table().print_xml(out, space + "    ", constrained);
+
+    BaseType *btp = var();
+    string tmp_name = btp->name();
+    btp->set_name("");
+    btp->print_xml(out, space + "    ", constrained);
+    btp->set_name(tmp_name);
+
+    for_each(dim_begin(), dim_end(),
+             PrintArrayDimStrm(out, space + "    ", constrained));
+
+    out << space << "</" << tag << ">\n" ;
+}
+
+#if FILE_METHODS
+/** Prints the values in ASCII of the entire (constrained) array. This method
+    Attempts to make an aesthetically pleasing display. However, it is
+    primarily intended for debugging purposes.
+
+    @param out Write the output to this FILE *.
+    @param index
+    @param dims
+    @param shape
+
+    @brief Print the value given the current constraint.
+*/
+unsigned int
+Array::print_array(FILE *out, unsigned int index, unsigned int dims,
+                   unsigned int shape[])
+{
+    if (dims == 1) {
+        fprintf(out, "{") ;
+        for (unsigned i = 0; i < shape[0] - 1; ++i) {
+            var(index++)->print_val(out, "", false);
+            fprintf(out, ", ") ;
+        }
+        var(index++)->print_val(out, "", false);
+        fprintf(out, "}") ;
+
+        return index;
+    }
+    else {
+        fprintf(out, "{") ;
+        // Fixed an off-by-one error in the following loop. Since the array
+        // length is shape[dims-1]-1 *and* since we want one less dimension
+        // than that, the correct limit on this loop is shape[dims-2]-1. From
+        // Todd Karakasian.
+        // The saga continues; the loop test should be `i < shape[0]-1'. jhrg
+        // 9/12/96.
+        for (unsigned i = 0; i < shape[0] - 1; ++i) {
+            index = print_array(out, index, dims - 1, shape + 1);
+            fprintf(out, ",") ;   // Removed the extra `}'. Also from Todd
+        }
+        index = print_array(out, index, dims - 1, shape + 1);
+        fprintf(out, "}") ;
+
+        return index;
+    }
+}
+#endif
+
+/** Prints the values in ASCII of the entire (constrained) array. This method
+    Attempts to make an anesthetically pleasing display. However, it is
+    primarily intended for debugging purposes.
+
+    @param out Write the output to this ostream
+    @param index
+    @param dims
+    @param shape
+
+    @brief Print the value given the current constraint.
+*/
+unsigned int
+Array::print_array(ostream &out, unsigned int index, unsigned int dims,
+                   unsigned int shape[])
+{
+    if (dims == 1) {
+	out << "{" ;
+        for (unsigned i = 0; i < shape[0] - 1; ++i) {
+            var(index++)->print_val(out, "", false);
+	    out << ", " ;
+        }
+        var(index++)->print_val(out, "", false);
+	out << "}" ;
+
+        return index;
+    }
+    else {
+	out << "{" ;
+        // Fixed an off-by-one error in the following loop. Since the array
+        // length is shape[dims-1]-1 *and* since we want one less dimension
+        // than that, the correct limit on this loop is shape[dims-2]-1. From
+        // Todd Karakasian.
+        // The saga continues; the loop test should be `i < shape[0]-1'. jhrg
+        // 9/12/96.
+        for (unsigned i = 0; i < shape[0] - 1; ++i) {
+            index = print_array(out, index, dims - 1, shape + 1);
+	    out << "," ;
+        }
+        index = print_array(out, index, dims - 1, shape + 1);
+	out << "}" ;
+
+        return index;
+    }
+}
+
+#if FILE_METHODS
+void
+Array::print_val(FILE *out, string space, bool print_decl_p)
+{
+    // print the declaration if print decl is true.
+    // for each dimension,
+    //   for each element,
+    //     print the array given its shape, number of dimensions.
+    // Add the `;'
+
+    if (print_decl_p) {
+        print_decl(out, space, false, false, false);
+        fprintf(out, " = ") ;
+    }
+
+    unsigned int *shape = new unsigned int[_shape.size()];
+    unsigned int index = 0;
+    for (Dim_iter i = _shape.begin(); i != _shape.end() && index < _shape.size(); i++)
+        shape[index++] = dimension_size(i, true);
+
+    print_array(out, 0, _shape.size(), shape);
+
+    delete [] shape; shape = 0;
+
+    if (print_decl_p) {
+        fprintf(out, ";\n") ;
+    }
+}
+#endif
+
+void
+Array::print_val(ostream &out, string space, bool print_decl_p)
+{
+    // print the declaration if print decl is true.
+    // for each dimension,
+    //   for each element,
+    //     print the array given its shape, number of dimensions.
+    // Add the `;'
+
+    if (print_decl_p) {
+        print_decl(out, space, false, false, false);
+	    out << " = " ;
+    }
+
+    unsigned int *shape = new unsigned int[dimensions(true)];
+    unsigned int index = 0;
+    for (Dim_iter i = _shape.begin(); i != _shape.end() && index < dimensions(true); ++i)
+        shape[index++] = dimension_size(i, true);
+
+    print_array(out, 0, dimensions(true), shape);
+
+    delete [] shape; shape = 0;
+
+    if (print_decl_p) {
+	    out << ";\n" ;
+    }
+}
+
+/** This function checks semantic features of the Array.  Currently,
+    the only check specific to the Array is that there must be
+    dimensions.  The rest is inherited from
+    <tt>BaseType::check_semantics()</tt>.
+
+    @brief Check semantic features of the Array.
+    @return A boolean value.  FALSE means there was a problem.
+*/
+
+bool
+Array::check_semantics(string &msg, bool)
+{
+    bool sem = BaseType::check_semantics(msg) && !_shape.empty();
+
+    if (!sem)
+        msg = "An array variable must have dimensions";
+
+    return sem;
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Array::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Array::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    Vector::dump(strm) ;
+    strm << DapIndent::LMarg << "shape:" << endl ;
+    DapIndent::Indent() ;
+    Dim_citer i = _shape.begin() ;
+    Dim_citer ie = _shape.end() ;
+    unsigned int dim_num = 0 ;
+    for (; i != ie; i++) {
+        strm << DapIndent::LMarg << "dimension " << dim_num++ << ":"
+	     << endl ;
+        DapIndent::Indent() ;
+        strm << DapIndent::LMarg << "name: " << (*i).name << endl ;
+        strm << DapIndent::LMarg << "size: " << (*i).size << endl ;
+        strm << DapIndent::LMarg << "start: " << (*i).start << endl ;
+        strm << DapIndent::LMarg << "stop: " << (*i).stop << endl ;
+        strm << DapIndent::LMarg << "stride: " << (*i).stride << endl ;
+        strm << DapIndent::LMarg << "constrained size: " << (*i).c_size
+             << endl ;
+        DapIndent::UnIndent() ;
+    }
+    DapIndent::UnIndent() ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Array.h b/Array.h
new file mode 100644
index 0000000..4b00fa5
--- /dev/null
+++ b/Array.h
@@ -0,0 +1,225 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Class for array variables. The dimensions of the array are stored in the
+// list SHAPE.
+//
+// jhrg 9/6/94
+
+#ifndef _array_h
+#define _array_h 1
+
+#include <string>
+#include <vector>
+
+#ifndef _dods_limits_h
+#include "dods-limits.h"
+#endif
+
+#ifndef _vector_h
+#include "Vector.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+const int DODS_MAX_ARRAY = DODS_INT_MAX;
+
+/** This class is used to hold arrays of data. The elements of the array can
+    be simple or compound data types. There is no limit on the number of
+    dimensions an array can have, or on the size of each dimension.
+
+    If desired, the user can give each dimension of an array a name. You can,
+    for example, have a 360x180 array of temperatures, covering the whole
+    globe with one-degree squares. In this case, you could name the first
+    dimension \e Longitude and the second dimension \e Latitude. This can
+    help prevent a great deal of confusion.
+
+    The Array is used as part of the Grid class, where the dimension names
+    are crucial to its structure. The dimension names correspond to \e Map
+    vectors, holding the actual values for that column of the array.
+
+    Each array dimension carries with it its own projection information. The
+    projection information takes the form of three integers: the start, stop,
+    and stride values. This is clearest with an example. Consider a
+    one-dimensional array 10 elements long. If the start value of the
+    dimension constraint is 3, then the constrained array appears to be seven
+    elements long. If the stop value is changed to 7, then the array appears
+    to be five elements long. If the stride is changed to two, the array will
+    appear to be 3 elements long. Array constraints are written as:
+    <b>[start:stride:stop]</b>.
+
+    \verbatim
+    A = [1 2 3 4 5 6 7 8 9 10]
+
+    A[3::] = [4 5 6 7 8 9 10]
+
+    A[3::7] = [4 5 6 7 8]
+
+    A[3:2:7] = [4 6 8]
+
+    A[0:3:9] = [1 4 7 10]
+    \endverbatim
+
+    @note Arrays use zero-based indexing.
+
+    @brief A multidimensional array of identical data types.
+    @see Grid
+    @see Vector
+    @see dimension */
+
+class Array: public Vector
+{
+public:
+    /** Information about a dimension. Each Array has one or more dimensions.
+        For each of an Array's dimensions, a corresponding instance of this
+        struct holds the natural size, name, constraint information and
+        constrained size.
+
+        @note Instead of using this struct's fields directly, use Array's
+        dimension accessor methods.
+
+        @note This struct is public because its type is used in public
+        typedefs. */
+    struct dimension
+    {
+        int size;  ///< The unconstrained dimension size.
+        string name;    ///< The name of this dimension.
+        int start;  ///< The constraint start index
+        int stop;  ///< The constraint end index
+        int stride;  ///< The constraint stride
+        int c_size;  ///< Size of dimension once constrained
+    };
+
+private:
+    std::vector<dimension> _shape; // list of dimensions (i.e., the shape)
+
+    friend class ArrayTest;
+
+protected:
+    void _duplicate(const Array &a);
+
+#if FILE_METHODS
+    unsigned int print_array(FILE *out, unsigned int index,
+                             unsigned int dims, unsigned int shape[]);
+#endif
+    unsigned int print_array(ostream &out, unsigned int index,
+                             unsigned int dims, unsigned int shape[]);
+
+public:
+    /** A constant iterator used to access the various dimensions of an
+        Array.
+
+        @see dim_begin()
+        @see dim_end() */
+    typedef std::vector<dimension>::const_iterator Dim_citer ;
+    /** An iterator used to access the various dimensions of an
+        Array. Most of the methods that access various properties of a
+        dimension use an instance of Dim_iter.
+
+        @see dim_begin()
+        @see dim_end() */
+    typedef std::vector<dimension>::iterator Dim_iter ;
+
+    Array(const string &n, BaseType *v);
+    Array(const string &n, const string &d, BaseType *v);
+    Array(const Array &rhs);
+    virtual ~Array();
+
+    Array &operator=(const Array &rhs);
+    virtual BaseType *ptr_duplicate();
+
+    void add_var(BaseType *v, Part p = nil);
+
+    void append_dim(int size, string name = "");
+    void prepend_dim(int size, const string& name = "");
+
+    virtual void add_constraint(Dim_iter i, int start, int stride, int stop);
+    virtual void reset_constraint();
+
+    virtual void clear_constraint();
+
+    virtual void update_length(int size);
+
+    Dim_iter dim_begin() ;
+    Dim_iter dim_end() ;
+
+    virtual int dimension_size(Dim_iter i, bool constrained = false);
+    virtual int dimension_start(Dim_iter i, bool constrained = false);
+    virtual int dimension_stop(Dim_iter i, bool constrained = false);
+    virtual int dimension_stride(Dim_iter i, bool constrained = false);
+    virtual string dimension_name(Dim_iter i);
+
+    virtual unsigned int dimensions(bool constrained = false);
+
+    virtual void print_decl(ostream &out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+
+    virtual void print_xml(ostream &out, string space = "    ",
+                           bool constrained = false);
+
+#if FILE_METHODS
+    virtual void print_xml_core(FILE *out, string space, bool constrained, string tag);
+#endif
+    virtual void print_xml_core(ostream &out, string space, bool constrained, string tag);
+
+    // not used (?)
+    virtual void print_as_map_xml(ostream &out, string space = "    ",
+                                  bool constrained = false);
+
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+#if FILE_METHODS
+    virtual void print_xml(FILE *out, string space = "    ",
+                           bool constrained = false);
+    virtual void print_as_map_xml(FILE *out, string space = "    ",
+                                  bool constrained = false);
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+    virtual void print_decl(FILE *out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+#endif
+
+    virtual bool check_semantics(string &msg, bool all = false);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _array_h
diff --git a/ArrayGeoConstraint.cc b/ArrayGeoConstraint.cc
new file mode 100644
index 0000000..ef4905d
--- /dev/null
+++ b/ArrayGeoConstraint.cc
@@ -0,0 +1,212 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// The Grid Selection Expression Clause class.
+
+
+#include "config.h"
+
+static char id[] not_used =
+    { "$Id: ArrayGeoConstraint.cc 21922 2010-01-07 18:23:57Z jimg $"
+    };
+
+#include <cmath>
+#include <iostream>
+#include <sstream>
+
+//#define DODS_DEBUG
+
+#include "debug.h"
+#include "dods-datatypes.h"
+#include "ArrayGeoConstraint.h"
+#include "Float64.h"
+
+#include "Error.h"
+#include "InternalErr.h"
+#include "ce_functions.h"
+
+using namespace std;
+
+namespace libdap {
+
+/** Private initialization code. */
+void ArrayGeoConstraint::m_init()
+{
+    if (d_array->dimensions() < 2 || d_array->dimensions() > 3)
+        throw Error("The geoarray() function works only with Arrays of two or three dimensions.");
+
+    build_lat_lon_maps();
+}
+
+// In the other methods the ds_name parameter defaults to "" but that's not
+// possible here. Remove ds_name
+ArrayGeoConstraint::ArrayGeoConstraint(Array *array, double top, double left,
+        double bottom, double right)
+        : GeoConstraint(), d_array(array),
+        d_extent(top, left, bottom, right), d_projection("plat-carre", "wgs84")
+
+{
+    m_init();
+}
+
+ArrayGeoConstraint::ArrayGeoConstraint(Array *array,
+                                       double top, double left, double bottom, double right,
+                                       const string &projection, const string &datum)
+        : GeoConstraint(), d_array(array),
+        d_extent(top, left, bottom, right), d_projection(projection, datum)
+
+{
+    m_init();
+}
+
+/** Build the longitude and latitude maps for this Array. This either builds
+    the maps using the extent, projection and datum given or reads the maps
+    from the data source somehow.
+
+    The d_lon and d_lon_length (and matching lat) fields are modified.
+
+    @note Rules used to find Maps:<ul><li>None, currently the extent must
+    be given.</li>
+    </ul>
+
+    @return True if the maps are built, otherwise False */
+bool ArrayGeoConstraint::build_lat_lon_maps()
+{
+    // Find the longitude dimension: Assume it is the rightmost
+    set_longitude_rightmost(true);
+    set_lon_dim(d_array->dim_begin() + (d_array->dimensions() - 1));
+
+    int number_elements_longitude = d_array->dimension_size(get_lon_dim());
+    double *lon_map = new double[number_elements_longitude];
+    for (int i = 0; i < number_elements_longitude; ++i) {
+        lon_map[i] = ((d_extent.d_right - d_extent.d_left) / (number_elements_longitude - 1)) * i + d_extent.d_left;
+    }
+    set_lon(lon_map);
+    set_lon_length(number_elements_longitude);
+
+    // Find the latitude dimension: Assume it is the next-rightmost
+    set_lat_dim(d_array->dim_begin() + (d_array->dimensions() - 2));
+
+    int number_elements_latitude = d_array->dimension_size(get_lat_dim());
+    double *lat_map = new double[number_elements_latitude];
+    for (int i = 0; i < number_elements_latitude; ++i) {
+        lat_map[i] = ((d_extent.d_bottom - d_extent.d_top) / (number_elements_latitude - 1)) * i + d_extent.d_top;
+    }
+    set_lat(lat_map);
+    set_lat_length(number_elements_latitude);
+
+    return get_lat() && get_lon();
+}
+
+/** Are the latitude and longitude dimensions ordered so that this class can
+    properly constrain the data?
+
+    @note This version always returns true because geoarray() assumes the
+    dimensions are ordered properly.
+
+    @return Always returns True. */
+bool
+ArrayGeoConstraint::lat_lon_dimensions_ok()
+{
+    return true;
+}
+
+/** Once the bounding box is set, apply the constraint. If the data can be sent
+    using Vector::serialize(), do so. If they cannot, read and organize the
+    data so that Vector::serialize() will be able to send the data when asked
+    to.
+
+    How can it be that Vector::serialize() would not be able to read the data?
+    If the longitude extent of the bounding box for the constraint wraps around
+    the edge of the data/array, then two reads are required to get the data.
+    This method performs those reads (using the constraints and the read()
+    method so that the data server's type-specific and optimized code will be
+    used to read actual data values) and then loads the combined result
+    back into the object, marking it as having been read. Vector::serialize()
+    will then see the object is loaded with data values, skip the regular read
+    call and send all the data in the buffer. */
+void ArrayGeoConstraint::apply_constraint_to_data()
+{
+    if (!is_bounding_box_set())
+        throw InternalErr(
+            "The Latitude and Longitude constraints must be set before calling\n\
+            apply_constraint_to_data().");
+
+    if (get_latitude_sense() == inverted) {
+        int tmp = get_latitude_index_top();
+        set_latitude_index_top(get_latitude_index_bottom());
+        set_latitude_index_bottom(tmp);
+    }
+
+    // It's easy to flip the Latitude values; if the bottom index value
+    // is before/above the top index, return an error explaining that.
+    if (get_latitude_index_top() > get_latitude_index_bottom())
+        throw Error("The upper and lower latitude indexes appear to be reversed. Please provide\nthe latitude bounding box numbers giving the northern-most latitude first.");
+
+    d_array->add_constraint(get_lat_dim(),
+                            get_latitude_index_top(), 1,
+                            get_latitude_index_bottom());
+
+    // Does the longitude constraint cross the edge of the longitude vector?
+    // If so, reorder the data (array).
+    if (get_longitude_index_left() > get_longitude_index_right()) {
+        reorder_data_longitude_axis(*d_array, get_lon_dim());
+
+        // Now the data are all in local storage
+
+        // alter the indexes; the left index has now been moved to 0, and the right
+        // index is now at lon_vector_length-left+right.
+        set_longitude_index_right(get_lon_length() - get_longitude_index_left()
+                                  + get_longitude_index_right());
+        set_longitude_index_left(0);
+    }
+    // If the constraint used the -180/179 (neg_pos) notation, transform
+    // the longitude map s it uses the -180/179 notation. Note that at this
+    // point, d_longitude always uses the pos notation because of the earlier
+    // conditional transformation.
+
+    // Apply constraint; stride is always one
+    d_array->add_constraint(get_lon_dim(),
+                            get_longitude_index_left(), 1,
+                            get_longitude_index_right());
+
+    // Load the array if it has been read, which will be the case if
+    // reorder_data_longitude_axis() has been called.
+    if (get_array_data()) {
+
+        int size = d_array->val2buf(get_array_data());
+
+        if (size != get_array_data_size())
+            throw InternalErr
+            ("Expected data size not copied to the Grid's buffer.");
+        d_array->set_read_p(true);
+    }
+    else {
+        d_array->read();
+    }
+}
+
+} // namespace libdap
+
diff --git a/ArrayGeoConstraint.h b/ArrayGeoConstraint.h
new file mode 100644
index 0000000..6bb3e3f
--- /dev/null
+++ b/ArrayGeoConstraint.h
@@ -0,0 +1,140 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _array_geo_constraint_h
+#define _array_geo_constraint_h 1
+
+#include <string>
+#include <sstream>
+#include <set>
+
+#ifndef _geo_constraint_h
+#include "GeoConstraint.h"
+#endif
+
+#ifndef _util_h
+#include "util.h"
+#endif
+
+namespace libdap
+{
+
+extern bool unit_or_name_match(set < string > units, set < string > names,
+			       const string & var_units,
+			       const string & var_name);
+
+/** Geographical constraint applied to an Array.
+
+    @note This class assumes that the Longitude dimension varies fastest, as
+    does the COARDS conventions.
+
+    @author James Gallagher */
+
+class ArrayGeoConstraint : public GeoConstraint
+{
+
+private:
+    struct Extent
+    {
+        double d_left;
+        double d_top;
+        double d_right;
+        double d_bottom;
+
+        Extent() : d_left(0.0), d_top(0.0), d_right(0.0), d_bottom(0.0)
+        {}
+        Extent(double t, double l, double b, double r)
+                : d_left(l), d_top(t), d_right(r), d_bottom(b)
+        {}
+    };
+
+    struct Projection
+    {
+        string d_name;
+        string d_datum;
+
+        Projection()
+        {}
+        Projection(const string &n, const string &d)
+                : d_name(n), d_datum(d)
+        {
+            downcase(d_name);
+            if (d_name != "plat-carre")
+                throw Error(
+                    "geoarray(): Only the Plat-Carre projection is supported by this version of\n\
+                    geoarray().");
+            downcase(d_datum);
+            if (d_datum != "wgs84")
+                throw Error(
+                    "geoarray(): Only the wgs84 datum is supported by this version of geoarray().");
+        }
+    };
+
+    Array *d_array;
+
+    Extent d_extent;
+    Projection d_projection;
+
+    bool build_lat_lon_maps();
+    bool lat_lon_dimensions_ok();
+
+    void m_init();
+
+    friend class ArrayGeoConstraintTest; // Unit tests
+
+public:
+    /** @name Constructors */
+    //@{
+    ArrayGeoConstraint(Array *)
+            : GeoConstraint(), d_array(0)
+    {
+        // See ce_finctions.cc:function_geoarray() to put this message in
+        // context.
+        throw Error(
+            "Bummer. The five-argument version of geoarray() is not currently implemented.");
+    }
+
+    ArrayGeoConstraint(Array *array,
+                       double left, double top, double right, double bottom);
+
+    ArrayGeoConstraint(Array *array,
+                       double left, double top, double right, double bottom,
+                       const string &projection, const string &datum);
+    //@}
+
+    virtual ~ArrayGeoConstraint()
+    {}
+
+    virtual void apply_constraint_to_data();
+
+    virtual Array *get_constrained_array() const
+    {
+        return d_array;
+    }
+};
+
+} // namespace libdap
+
+#endif // _array_geo_constraint_h
diff --git a/AttrTable.cc b/AttrTable.cc
new file mode 100644
index 0000000..12eae40
--- /dev/null
+++ b/AttrTable.cc
@@ -0,0 +1,1370 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// jhrg 7/29/94
+
+#include "config.h"
+
+// #define DODS_DEBUG
+
+static char rcsid[]not_used =
+        "$Id: AttrTable.cc 24370 2011-03-28 16:21:32Z jimg $";
+
+#include <cassert>
+
+#include "AttrTable.h"
+
+#include "util.h"
+#include "escaping.h"
+
+#include "debug.h"
+
+using std::cerr;
+using std::string;
+using std::endl;
+using std::vector;
+
+namespace libdap {
+
+/** Convert an AttrType to it's string representation.
+ @param at The Attribute Type.
+ @return The type's string representation */
+string AttrType_to_String(const AttrType at)
+{
+    switch (at) {
+        case Attr_container:
+            return "Container";
+        case Attr_byte:
+            return "Byte";
+        case Attr_int16:
+            return "Int16";
+        case Attr_uint16:
+            return "UInt16";
+        case Attr_int32:
+            return "Int32";
+        case Attr_uint32:
+            return "UInt32";
+        case Attr_float32:
+            return "Float32";
+        case Attr_float64:
+            return "Float64";
+        case Attr_string:
+            return "String";
+        case Attr_url:
+            return "Url";
+        case Attr_other_xml:
+            return "OtherXML";
+        default:
+            return "";
+    }
+}
+
+AttrType String_to_AttrType(const string &s)
+{
+    string s2 = s;
+    downcase(s2);
+
+    if (s2 == "container")
+        return Attr_container;
+    else if (s2 == "byte")
+        return Attr_byte;
+    else if (s2 == "int16")
+        return Attr_int16;
+    else if (s2 == "uint16")
+        return Attr_uint16;
+    else if (s2 == "int32")
+        return Attr_int32;
+    else if (s2 == "uint32")
+        return Attr_uint32;
+    else if (s2 == "float32")
+        return Attr_float32;
+    else if (s2 == "float64")
+        return Attr_float64;
+    else if (s2 == "string")
+        return Attr_string;
+    else if (s2 == "url")
+        return Attr_url;
+    else if (s2 == "otherxml")
+        return Attr_other_xml;
+    else
+        return Attr_unknown;
+}
+
+/** Clone the given attribute table in <tt>this</tt>.
+ Protected. */
+void AttrTable::clone(const AttrTable &at)
+{
+    d_name = at.d_name;
+    d_is_global_attribute = at.d_is_global_attribute;
+
+    // Set the parent to null (no parent, not in container)
+    // since using at.d_parent is semantically incorrect
+    // and potentially dangerous.
+    d_parent = 0;
+
+    Attr_citer i = at.attr_map.begin();
+    Attr_citer ie = at.attr_map.end();
+    for (; i != ie; ++i) {
+        // this deep-copies containers recursively
+        entry *e = new entry(*(*i));
+        attr_map.push_back(e);
+
+        // If the entry being added was a container,
+        // set its parent to this to maintain invariant.
+        if (e->type == Attr_container) {
+          assert(e->attributes);
+          e->attributes->d_parent = this;
+        }
+    }
+}
+
+/** @name Instance management functions */
+
+//@{
+AttrTable::AttrTable()
+  : DapObj()
+  , d_name("")
+  , d_parent(0)
+  , attr_map()
+  , d_is_global_attribute(true)
+{
+}
+
+AttrTable::AttrTable(const AttrTable &rhs)
+: DapObj()
+{
+    clone(rhs);
+}
+
+// Private
+void AttrTable::delete_attr_table()
+{
+    for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
+        delete *i;
+        *i = 0;
+    }
+    attr_map.clear();
+}
+
+AttrTable::~AttrTable()
+{
+    DBG(cerr << "Entering ~AttrTable (" << this << ")" << endl);
+    delete_attr_table();DBG(cerr << "Exiting ~AttrTable" << endl);
+}
+
+AttrTable &
+AttrTable::operator=(const AttrTable &rhs)
+{
+    if (this != &rhs) {
+        delete_attr_table();
+        clone(rhs);
+    }
+
+    return *this;
+}
+//@}
+
+/** Attributes that are containers count one attribute, as do
+ attributes with both scalar and vector values.
+ @return The number of entries.
+ @brief Get the number of entries in this attribute table.
+ */
+unsigned int
+AttrTable::get_size() const
+{
+    return attr_map.size();
+}
+
+/** @brief Get the name of this attribute table.
+ @return A string containing the name. */
+string
+AttrTable::get_name() const
+{
+    return d_name;
+}
+
+/** @brief Set the name of this attribute table.
+ @param n The new name of the attribute table. */
+void
+AttrTable::set_name(const string &n)
+{
+    d_name = www2id(n);
+}
+
+/** If the given name already refers to an attribute, and the attribute has a
+ value, the given value is appended to the attribute vector. Calling this
+ function repeatedly is the way to append to an attribute vector.
+
+ The function throws an Error if the attribute is a container,
+ or if the type of the input value does not match the existing attribute's
+ type. Use <tt>append_container()</tt> to add container attributes.
+
+ This method performs a simple search for <tt>name</tt> in this attribute
+ table only; sub-tables are not searched and the dot notation is not
+ recognized.
+
+ @brief Add an attribute to the table.
+ @return Returns the length of the added attribute value.
+ @param name The name of the attribute to add or modify.
+ @param type The type of the attribute to add or modify.
+ @param attribute The value to add to the attribute table. */
+unsigned int
+AttrTable::append_attr(const string &name, const string &type,
+        const string &attribute)
+{
+    DBG(cerr << "Entering AttrTable::append_attr" << endl);
+    string lname = www2id(name);
+
+    Attr_iter iter = simple_find(lname);
+
+    // If the types don't match OR this attribute is a container, calling
+    // this mfunc is an error!
+    if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
+    throw Error(string("An attribute called `") + name
+            + string("' already exists but is of a different type"));
+    if (iter != attr_map.end() && (get_type(iter) == "Container"))
+    throw Error(string("An attribute called `") + name
+            + string("' already exists but is a container."));
+
+    if (iter != attr_map.end()) { // Must be a new attribute value; add it.
+        (*iter)->attr->push_back(attribute);
+        return (*iter)->attr->size();
+    }
+    else { // Must be a completely new attribute; add it
+        entry *e = new entry;
+
+        e->name = lname;
+        e->is_alias = false;
+        e->type = String_to_AttrType(type); // Record type using standard names.
+        e->attr = new vector<string>;
+        e->attr->push_back(attribute);
+
+        attr_map.push_back(e);
+
+        return e->attr->size(); // return the length of the attr vector
+    }
+}
+
+/** This version of append_attr() takes a vector<string> of values.
+ If the given name already refers to an attribute, and the attribute has
+ values, append the new values to the existing ones.
+
+ The function throws an Error if the attribute is a container,
+ or if the type of the input value does not match the existing attribute's
+ type. Use <tt>append_container()</tt> to add container attributes.
+
+ This method performs a simple search for <tt>name</tt> in this attribute
+ table only; sub-tables are not searched and the dot notation is not
+ recognized.
+
+ @brief Add an attribute to the table.
+ @return Returns the length of the added attribute value.
+ @param name The name of the attribute to add or modify.
+ @param type The type of the attribute to add or modify.
+ @param values A vector of values. Note: The vector is COPIED, not stored. */
+
+unsigned int
+AttrTable::append_attr(const string &name, const string &type,
+        vector<string> *values)
+{
+    DBG(cerr << "Entering AttrTable::append_attr(..., vector)" << endl);
+    string lname = www2id(name);
+
+    Attr_iter iter = simple_find(lname);
+
+    // If the types don't match OR this attribute is a container, calling
+    // this mfunc is an error!
+    if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
+    throw Error(string("An attribute called `") + name
+            + string("' already exists but is of a different type"));
+    if (iter != attr_map.end() && (get_type(iter) == "Container"))
+    throw Error(string("An attribute called `") + name
+            + string("' already exists but is a container."));
+
+    if (iter != attr_map.end()) { // Must be new attribute values; add.
+        vector<string>::iterator i = values->begin();
+        while (i != values->end())
+        (*iter)->attr->push_back(*i++);
+
+        return (*iter)->attr->size();
+    }
+    else { // Must be a completely new attribute; add it
+        entry *e = new entry;
+
+        e->name = lname;
+        e->is_alias = false;
+        e->type = String_to_AttrType(type); // Record type using standard names.
+        e->attr = new vector<string>(*values);
+
+        attr_map.push_back(e);
+
+        return e->attr->size(); // return the length of the attr vector
+    }
+}
+
+/** Create and append an attribute container to this AttrTable. If this
+ attribute table already contains an attribute container called
+ <tt>name</tt> an exception is thrown. Return a pointer to the new container.
+
+ @brief Add a container to the attribute table.
+ @param name The name of the container to create.
+ @return A pointer to the new AttrTable object.
+ */
+
+AttrTable *
+AttrTable::append_container(const string &name)
+{
+    AttrTable *new_at = new AttrTable;
+    AttrTable *ret = NULL;
+    try {
+        ret = append_container(new_at, name);
+    }
+    catch (Error &e) {
+        // an error occurred, attribute with that name already exists
+        delete new_at; new_at = 0;
+        throw ;
+    }
+    return ret;
+}
+
+/** Append a new attribute container to this attribute table. The new
+ container is <tt>at</tt> and its name is set to
+ <tt>name</tt>. If this attribute
+ table already contains an attribute container called
+ <tt>name</tt> an exception is thrown.
+
+ @note The value of \e name will override the name of \e at set using the
+ set_name() method.
+
+ @brief Add a container to the attribute table.
+ @param at A pointer to the new attribute table to append.
+ @param name The name of the new attribute table.
+ @return A pointer to the new AttrTable object.
+ */
+AttrTable *
+AttrTable::append_container(AttrTable *at, const string &name)
+{
+    string lname = www2id(name);
+
+    if (simple_find(name) != attr_end())
+    throw Error(string("There already exists a container called `")
+            + name + string("' in this attribute table."));
+    DBG(cerr << "Setting appended attribute container name to: "
+            << lname << endl);
+    at->set_name(lname);
+
+    entry *e = new entry;
+    e->name = lname;
+    e->is_alias = false;
+    e->type = Attr_container;
+    e->attributes = at;
+
+    attr_map.push_back(e);
+
+    at->d_parent = this;
+
+    return e->attributes;
+}
+
+/** Look for an attribute or an attribute container. If used to search
+ for an attribute container, this method returns the container's \e
+ parent using the value-result parameter \c at and a reference to the
+ container using the iterator value-result parameter \c iter. If used
+ to search for an attribute, the attribute's container is returned using
+ \c at; the attribute itself can be accessed using the iterator \c iter.
+
+ @param target The name (using dot notation) of the attribute or
+ container to find.
+ @param at A value-result used to return the attribute container in
+ which \c target was found. Null if \c target was not found.
+ @param iter The iterator which will reference the attribute found.
+ Can be used to access \c target from within \c at. References
+ dim_end() within \c at if the attribute or container does not exist. */
+void
+AttrTable::find(const string &target, AttrTable **at, Attr_iter *iter)
+{
+    string::size_type dotpos = target.rfind('.');
+    if (dotpos != string::npos) {
+        string container = target.substr(0, dotpos);
+        string field = target.substr(dotpos + 1);
+
+        *at = find_container(container);
+        if (*at) {
+            *iter = (*at)->simple_find(field);
+        }
+        else {
+            *iter = attr_map.end();
+        }
+    }
+    else {
+        *at = recurrsive_find(target, iter);
+    }
+}
+
+/** This method scans for attributes using recursion to look inside containers
+ even when the name of the attribute is not fully qualified. It starts
+ looking in itself and descends into its children depth first. It will find
+ attributes and attribute containers.
+
+ @param target Look for the attribute with this name.
+ @param location A value-result parameter. This returns an iterator to the
+ attribute within the returned AttrTable object
+ @return Returns a pointer to the AttrTable which holds \e target, or null
+ if \e target is not found. In the latter case, the value of \e location is
+ attr_end() for this AttrTable. */
+AttrTable *
+AttrTable::recurrsive_find(const string &target, Attr_iter *location)
+{
+    //*location = attr_begin();
+    Attr_iter i = attr_begin();
+    while (i != attr_end()) {
+        if (target == (*i)->name) {
+            *location = i;
+            return this;
+        }
+        else if ((*i)->type == Attr_container) {
+            AttrTable *at = (*i)->attributes->recurrsive_find(target, location);
+            if (at)
+            return at;
+        }
+
+        ++i;
+    }
+
+    *location = i;
+    return 0;
+}
+
+// Made public for callers that want non-recursive find.  [mjohnson 6 oct 09]
+/** Look in this AttrTable for the attribute called \c name. If found return
+ an Attr_iter which references it, otherwise return the end iterator for
+ this AttrTable.
+
+ @param target The name of the attribute.
+ @return An Attr_iter which references \c target. */
+AttrTable::Attr_iter
+AttrTable::simple_find(const string &target)
+{
+    Attr_iter i;
+    for (i = attr_map.begin(); i != attr_map.end(); ++i) {
+        if (target == (*i)->name) {
+            break;
+        }
+    }
+    return i;
+}
+
+/** Look in this attribute table for an attribute container named
+ <tt>target</tt>. The search starts at this attribute table;
+ <tt>target</tt> should
+ use the dot notation to name containers held within children of this
+ attribute table.
+
+ To search the entire DAS object, make sure to invoke this method from
+ that object.
+
+ @brief Find an attribute with a given name.
+ @param target The attribute container to find.
+ @return A pointer to the attribute table or null if the container
+ cannot be found. */
+AttrTable *
+AttrTable::find_container(const string &target)
+{
+    string::size_type dotpos = target.find('.');
+    if (dotpos != string::npos) {
+        string container = target.substr(0, dotpos);
+        string field = target.substr(dotpos + 1);
+
+        AttrTable *at = simple_find_container(container);
+        return (at) ? at->find_container(field) : 0;
+    }
+    else {
+        return simple_find_container(target);
+    }
+}
+
+// Made public for callers that want non-recursive find.  [mjohnson 6 oct 09]
+AttrTable *
+AttrTable::simple_find_container(const string &target)
+{
+    if (get_name() == target)
+    return this;
+
+    for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
+        if (is_container(i) && target == (*i)->name) {
+            return (*i)->attributes;
+        }
+    }
+
+    return 0;
+}
+
+/** Each of the following accessors get information using the name of an
+ attribute. They perform a simple search for the name in this
+ attribute table only; sub-tables are not searched and the dot
+ notation is not recognized.
+
+ @name Accessors using an attribute name */
+//@{
+
+/** @brief Get an attribute container. */
+AttrTable *
+AttrTable::get_attr_table(const string &name)
+{
+    return find_container(name);
+}
+
+/** @brief Get the type name of an attribute within this attribute table. */
+string
+AttrTable::get_type(const string &name)
+{
+    Attr_iter p = simple_find(name);
+    return (p != attr_map.end()) ? get_type(p) : (string)"";
+}
+
+/** @brief Get the type of an attribute.
+ @return The <tt>AttrType</tt> value describing the attribute. */
+AttrType
+AttrTable::get_attr_type(const string &name)
+{
+    Attr_iter p = simple_find(name);
+    return (p != attr_map.end()) ? get_attr_type(p) : Attr_unknown;
+}
+
+/** If the indicated attribute is a container attribute, this function
+ returns the number of attributes in <i>its</i> attribute table. If the
+ indicated attribute is not a container, the method returns the number
+ of values for the attribute (1 for a scalar attribute, N for a vector
+ attribute value).
+ @brief Get the number of attributes in this container.
+ */
+unsigned int
+AttrTable::get_attr_num(const string &name)
+{
+    Attr_iter iter = simple_find(name);
+    return (iter != attr_map.end()) ? get_attr_num(iter) : 0;
+}
+
+/** Get a pointer to the vector of values associated with the attribute
+ referenced by Pix <tt>p</tt> or named <tt>name</tt>.
+
+ Note that all values in an attribute table are stored as string data.
+ They may be converted to a more appropriate internal format by the
+ calling program.
+
+ @return If the indicated attribute is a container, this function
+ returns the null pointer.  Otherwise returns a pointer to the
+ the attribute vector value.
+ @brief Get a vector-valued attribute.
+ */
+vector<string> *
+AttrTable::get_attr_vector(const string &name)
+{
+    Attr_iter p = simple_find(name);
+    return (p != attr_map.end()) ? get_attr_vector(p) : 0;
+}
+
+/** Delete the attribute named <tt>name</tt>. If <tt>i</tt> is given, and
+ the attribute has a vector value, delete the <tt>i</tt>$^th$
+ element of the vector.
+
+ You can use this function to delete container attributes, although
+ the <tt>i</tt> parameter has no meaning for that operation.
+
+ @brief Deletes an attribute.
+ @param name The name of the attribute to delete.  This can be an
+ attribute of any type, including containers. However, this method
+ looks only in this attribute table and does not recognize the dot
+ notation.
+ @param i If the named attribute is a vector, and <tt>i</tt> is
+ non-negative, the i-th entry in the vector is deleted, and the
+ array is repacked.  If <tt>i</tt> equals -1 (the default), the
+ entire attribute is deleted. */
+void
+AttrTable::del_attr(const string &name, int i)
+{
+    string lname = www2id(name);
+
+    Attr_iter iter = simple_find(lname);
+    if (iter != attr_map.end()) {
+        if (i == -1) { // Delete the whole attribute
+            entry *e = *iter;
+            attr_map.erase(iter);
+            delete e; e = 0;
+        }
+        else { // Delete one element from attribute array
+            // Don't try to delete elements from the vector of values if the
+            // map is a container!
+            if ((*iter)->type == Attr_container)
+            return;
+
+            vector<string> *sxp = (*iter)->attr;
+
+            assert(i >= 0 && i < (int)sxp->size());
+            sxp->erase(sxp->begin() + i); // rm the element
+        }
+    }
+}
+
+//@} Accessors using an attribute name
+
+/** @name get information using an iterator */
+//@{
+/** Get an iterator to the first entry in this attribute table.
+ @return Attr_iter; references the end of the array if empty list. */
+AttrTable::Attr_iter
+AttrTable::attr_begin()
+{
+    return attr_map.begin();
+}
+
+/** Get an iterator to the end attribute table. Does not point to
+ the last attribute in the table
+ @return Attr_iter */
+AttrTable::Attr_iter
+AttrTable::attr_end()
+{
+    return attr_map.end();
+}
+
+/** Given an index \c i, return the \c Attr_iter to the corresponding
+ element. This method provides a way to use all the methods that take an
+ \c Attr_iter using a simple integer index. Use the get_attr_num() or
+ get_size() methods to determine how many items the AttrTable contains.
+
+ @param i The index
+ @return The corresponding Attr_iter
+ @see get_attr_num, get_size */
+AttrTable::Attr_iter
+AttrTable::get_attr_iter(int i)
+{
+    return attr_map.begin() + i;
+}
+
+/** Returns the name of the attribute referenced by \e iter. */
+string
+AttrTable::get_name(Attr_iter iter)
+{
+    assert(iter != attr_map.end());
+
+    return (*iter)->name;
+}
+
+/** Returns true if the attribute referenced by \e i is a container. */
+bool
+AttrTable::is_container(Attr_iter i)
+{
+    return (*i)->type == Attr_container;
+}
+
+/** Get the attribute container referenced by \e iter. If no
+ such container exists, then return a reference to the end of the
+ table.
+ @param iter Reference to a table contained by this object.
+ @return The child attribute table. */
+AttrTable *
+AttrTable::get_attr_table(Attr_iter iter)
+{
+    assert(iter != attr_map.end());
+    return (*iter)->type == Attr_container ? (*iter)->attributes : 0;
+}
+
+/** Delete the iterator.  Since AttrTable stores pointers to AttrTable
+    objects, the caller should be sure to delete the AttrTable itself.
+    The caller will gain control of the AttrTable* located at
+    get_attr_table(iter) prior to this call.
+
+ @note calling this method <b>invalidates</b> the iterator \e iter.
+ @param iter points to the entry to be deleted.
+ @return The Attr_iter for the element following \e iter */
+AttrTable::Attr_iter
+AttrTable::del_attr_table(Attr_iter iter)
+{
+    if ((*iter)->type != Attr_container)
+    return ++iter;
+
+    // the caller intends to delete/reuse the contained AttrTable,
+    // so zero it out so it doesn't get deleted before we delete the entry
+    // [mjohnson]
+    struct entry* e = *iter;
+    // container no longer has a parent.
+    if (e->attributes) {
+      e->attributes->d_parent = 0;
+    }
+    e->attributes = 0;
+    delete e;
+
+    return attr_map.erase(iter);
+}
+
+/** Get the type name of an attribute referenced by \e iter.
+ @param iter Reference to the Attribute.
+ @return A string with the name of this attribute datatype. */
+string
+AttrTable::get_type(Attr_iter iter)
+{
+    assert(iter != attr_map.end());
+    return AttrType_to_String((*iter)->type);
+}
+
+/** Get the type of the attribute referenced by \e iter.
+ @param iter
+ @return The datatype of this attribute in an instance of AttrType. */
+AttrType
+AttrTable::get_attr_type(Attr_iter iter)
+{
+    return (*iter)->type;
+}
+
+/** If the attribute referenced by \e iter is a container attribute, this
+ method returns the number of attributes in its attribute table.
+ If the indicated attribute is not a container, the method returns the
+ number of values for the attribute (1 for a scalar attribute, N for a
+ vector attribute value).
+ @param iter Reference to an attribute
+ @return The number of elements in the attribute. */
+unsigned int
+AttrTable::get_attr_num(Attr_iter iter)
+{
+    assert(iter != attr_map.end());
+    return ((*iter)->type == Attr_container)
+    ? (*iter)->attributes->get_size()
+    : (*iter)->attr->size();
+}
+
+/** Returns the value of an attribute. If the attribute has a vector
+ value, you can indicate which is the desired value with the index
+ argument, \e i. If the argument is omitted, the first value is
+ returned. If the attribute has only a single value, the index
+ argument is ignored. If \e i is greater than the number of
+ elements in the attribute, an error is produced.
+
+ All values in an attribute table are stored as string data. They may
+ be converted to a more appropriate internal format by the calling
+ program.
+
+ @param iter Reference to an attribute
+ @param i The attribute value index, zero-based. Default value: 0
+ @return If the indicated attribute is a container, this function
+ returns the string ``None''. If using a name to refer to the attribute
+ and the named attribute does not exist, return the empty string. */
+string
+AttrTable::get_attr(Attr_iter iter, unsigned int i)
+{
+    assert(iter != attr_map.end());
+#if 1
+    return (*iter)->type == Attr_container ? (string)"None" : (*(*iter)->attr)[i];
+#else
+    if ((*iter)->type == Attr_container) {
+        return "None";
+    }
+    else {
+        cerr << "(*iter)->attr: " << (*iter)->attr << endl;
+        cerr << "(*iter)->name: " << (*iter)->name << endl;
+        cerr << "(*iter)->type: " << (*iter)->type << endl;
+        //cerr << "get_attr: return value: [" << i << "]: " << (*(*iter)->attr)[i]<< endl;
+        if ((*iter)->name == "SIS_ID")
+        return "SIS_ID_value";
+        else
+        return (*(*iter)->attr)[i];
+    }
+#endif
+}
+
+string
+AttrTable::get_attr(const string &name, unsigned int i)
+{
+    Attr_iter p = simple_find(name);
+    return (p != attr_map.end()) ? get_attr(p, i) : (string)"";
+}
+
+/** Returns a pointer to the vector of values associated with the
+ attribute referenced by iterator \e iter.
+
+ Note that all values in an attribute table are stored as string data.
+ They may be converted to a more appropriate internal format by the
+ calling program.
+
+ @param iter Reference to the Attribute.
+ @return If the indicated attribute is a container, this function
+ returns the null pointer.  Otherwise returns a pointer to the
+ the attribute vector value. */
+vector<string> *
+AttrTable::get_attr_vector(Attr_iter iter)
+{
+    assert(iter != attr_map.end());
+    return (*iter)->type != Attr_container ? (*iter)->attr : 0;
+}
+
+bool
+AttrTable::is_global_attribute(Attr_iter iter)
+{
+    assert(iter != attr_map.end());
+    if ((*iter)->type == Attr_container)
+	return (*iter)->attributes->is_global_attribute();
+    else
+	return (*iter)->is_global;
+}
+
+void
+AttrTable::set_is_global_attribute(Attr_iter iter, bool ga)
+{
+    assert(iter != attr_map.end());
+    if ((*iter)->type == Attr_container)
+	(*iter)->attributes->set_is_global_attribute(ga);
+    else
+	(*iter)->is_global = ga;
+}
+
+//@} Accessors that use an iterator
+
+// Alias an attribute table. The alias should be added to this object.
+/** @brief Add an alias to a container held by this attribute table.
+ @param name The name of the alias. May <i>not</i> use dot notation.
+ @param src The existing attribute container to alias.
+ @exception Error if an attribute, container or alias called
+ <tt>name</tt> already exists in this attribute table. */
+void
+AttrTable::add_container_alias(const string &name, AttrTable *src)
+{
+    string lname = www2id(name);
+
+    if (simple_find(lname) != attr_end())
+    throw Error(string("There already exists a container called `")
+            + name + string("in this attribute table."));
+
+    entry *e = new entry;
+    e->name = lname;
+    e->is_alias = true;
+    e->aliased_to = src->get_name();
+    e->type = Attr_container;
+
+    e->attributes = src;
+
+    attr_map.push_back(e);
+}
+
+/** Assume \e source names an attribute value in some container. Add an alias
+ \e name for that value in this object.
+
+ @brief Add an alias for an attribute.
+
+ @param das
+ @param name The name of the alias. May <i>not</i> use dot notation.
+ @param source The name of the attribute to alias. May use dot
+ notation.
+ @exception Error if the attribute table already contains an
+ attribute, container or alias called <tt>name</tt> or if an
+ attribute called <tt>source</tt> does not exist. */
+void
+AttrTable::add_value_alias(AttrTable *das, const string &name,
+        const string &source)
+{
+    string lname = www2id(name);
+    string lsource = www2id(source);
+
+    // find the container that holds source and its (sources's) iterator
+    // within that container. Search at the uppermost level of the attribute
+    // object to find values defined `above' the current container.
+    AttrTable *at;
+    Attr_iter iter;
+    das->find(lsource, &at, &iter);
+
+    // If source is not found by looking at the topmost level, look in the
+    // current table (i.e., alias z x where x is in the current container
+    // won't be found by looking for `x' at the top level). See test case 26
+    // in das-testsuite.
+    if (!at || (iter == at->attr_end()) || !*iter) {
+        find(lsource, &at, &iter);
+        if (!at || (iter == at->attr_end()) || !*iter)
+        throw Error(string("Could not find the attribute `")
+                + source + string("' in the attribute object."));
+    }
+
+    // If we've got a value to alias and it's being added at the top level of
+    // the DAS, that's an error.
+    if (at && !at->is_container(iter) && this == das)
+    throw Error(string("A value cannot be aliased to the top level of the DAS;\nOnly containers may be present at that level of the DAS."));
+
+    if (simple_find(lname) != attr_end())
+    throw Error(string("There already exists a container called `")
+            + name + string("in this attribute table."));
+
+    entry *e = new entry;
+    e->name = lname;
+    e->is_alias = true;
+    e->aliased_to = lsource;
+    e->type = get_attr_type(iter);
+    if (at && e->type == Attr_container)
+    e->attributes = at->get_attr_table(iter);
+    else
+    e->attr = (*iter)->attr;
+
+    attr_map.push_back(e);
+}
+
+// Deprecated
+/** Once an alias is
+ inserted into an attribute table, reading the attributes for
+ <i>alias</i> will return those stored for <i>name</i>.
+
+ Two forms for this function exist: one searches for <i>name</i>
+ in the AttrTable referenced by <i>at</i> while the other uses
+ <tt>this</tt>. You can use <tt>DAS::get_attr_table()</tt> to
+ get the attribute table for an arbitrary name.
+
+ @brief Adds an alias to the set of attributes.
+ @see get_attr_table
+ @deprecated The current alias design is flawed. It is impossible to map
+ this onto the XML implementation where the DAS and DDS information are
+ combined in one object.
+ @param alias The alias to insert into the attribute table.
+ @param name The name of the already-existing attribute to which
+ the alias will refer.
+ @param at An attribute table in which to insert the alias. */
+bool
+AttrTable::attr_alias(const string &alias, AttrTable *at, const string &name)
+{
+    add_value_alias(at, alias, name);
+    return true;
+}
+
+/** @deprecated The current alias design is flawed. It is impossible to map
+ this onto the XML implementation where the DAS and DDS information are
+ combined in one object.
+
+ @param alias The alias to insert into the attribute table.
+ @param name The name of the already-existing attribute to which
+ the alias will refer. */
+bool
+AttrTable::attr_alias(const string &alias, const string &name)
+{
+    return attr_alias(alias, this, name);
+}
+
+/** Erase the entire attribute table. This returns an AttrTable to the empty
+ state that's the same as the object generated by the null constructor.
+ @brief Erase the attribute table. */
+void
+AttrTable::erase()
+{
+    for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
+        delete *i; *i = 0;
+    }
+
+    attr_map.erase(attr_map.begin(), attr_map.end());
+
+    d_name = "";
+}
+
+const string double_quote = "\"";
+
+// This is here as a result of the problem described in ticket #1163 where
+// the data handlers are adding quotes to string attributes so the DAS will
+// be printed correctly. But that has the affect of adding the quotes to the
+// attribute's _value_ not just it's print representation. As part of the fix
+// I made the code here add the quotes if the handlers are fixed (but not if
+// handlers are still adding them). The other part of 1163 is to fix all of
+// the handlers... What this fix means is that attributes whose values really
+// do contain bracketing quotes might be misunderstood, since we're assuming
+// those quotes were added by the handlers as a hack to get the output
+// formatting correct for the DAS. jhrg 7/30/08
+
+static void
+write_string_attribute_for_das(ostream &out, const string &value, const string &term)
+{
+    if (is_quoted(value))
+    out << value << term;
+    else
+    out << double_quote << value << double_quote << term;
+}
+
+static void
+write_string_attribute_for_das(FILE *out, const string &value, const string &term)
+{
+    if (is_quoted(value))
+    fprintf(out, "%s%s", value.c_str(), term.c_str());
+    else
+    fprintf(out, "\"%s\"%s", value.c_str(), term.c_str());
+}
+
+// Special treatment for XML: Make sure to escape double quotes when XML is
+// printed in a DAS.
+static void
+write_xml_attribute_for_das(ostream &out, const string &value, const string &term)
+{
+    if (is_quoted(value))
+    out << escape_double_quotes(value) << term;
+    else
+    out << double_quote << escape_double_quotes(value) << double_quote << term;
+}
+
+static void
+write_xml_attribute_for_das(FILE *out, const string &value, const string &term)
+{
+    if (is_quoted(value))
+    fprintf(out, "%s%s", escape_double_quotes(value).c_str(), term.c_str());
+    else
+    fprintf(out, "\"%s\"%s", escape_double_quotes(value).c_str(), term.c_str());
+}
+
+/** A simple printer that does nothing fancy with aliases.
+ Protected. */
+void
+AttrTable::simple_print(FILE *out, string pad, Attr_iter i,
+        bool dereference)
+{
+    switch ((*i)->type) {
+        case Attr_container:
+        fprintf(out, "%s%s {\n", pad.c_str(), id2www(get_name(i)).c_str());
+
+        (*i)->attributes->print(out, pad + "    ", dereference);
+
+        fprintf(out, "%s}\n", pad.c_str());
+        break;
+
+        case Attr_string: {
+            fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
+                    id2www(get_name(i)).c_str());
+
+            vector<string> *sxp = (*i)->attr;
+            vector<string>::iterator last = sxp->end() - 1;
+            for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
+                write_string_attribute_for_das(out, *i, ", ");
+            }
+            write_string_attribute_for_das(out, *last, ";\n");
+        }
+        break;
+
+        case Attr_other_xml: {
+            fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
+                    id2www(get_name(i)).c_str());
+
+            vector<string> *sxp = (*i)->attr;
+            vector<string>::iterator last = sxp->end() - 1;
+            for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
+                write_xml_attribute_for_das(out, *i, ", ");
+            }
+            write_xml_attribute_for_das(out, *last, ";\n");
+        }
+        break;
+
+        default: {
+            fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
+                    id2www(get_name(i)).c_str());
+
+            vector<string> *sxp = (*i)->attr;
+            vector<string>::iterator last = sxp->end() - 1;
+            for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
+                fprintf(out, "%s%s", (*i).c_str(), ", ");
+            }
+            fprintf(out, "%s%s", (*last).c_str(), ";\n");
+        }
+        break;
+    }
+}
+
+/** A simple printer that does nothing fancy with aliases.
+ Protected. */
+void
+AttrTable::simple_print(ostream &out, string pad, Attr_iter i,
+        bool dereference)
+{
+    switch ((*i)->type) {
+        case Attr_container:
+        out << pad << id2www(get_name(i)) << " {\n";
+
+        (*i)->attributes->print(out, pad + "    ", dereference);
+
+        out << pad << "}\n";
+        break;
+
+        case Attr_string: {
+            out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
+
+            vector<string> *sxp = (*i)->attr;
+            vector<string>::iterator last = sxp->end() - 1;
+            for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
+                write_string_attribute_for_das(out, *i, ", ");
+            }
+            write_string_attribute_for_das(out, *last, ";\n");
+        }
+        break;
+
+        case Attr_other_xml: {
+            out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
+
+            vector<string> *sxp = (*i)->attr;
+            vector<string>::iterator last = sxp->end() - 1;
+            for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
+                write_xml_attribute_for_das(out, *i, ", ");
+            }
+            write_xml_attribute_for_das(out, *last, ";\n");
+        }
+        break;
+
+        default: {
+            out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
+
+            vector<string> *sxp = (*i)->attr;
+            vector<string>::iterator last = sxp->end() - 1;
+            for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
+                out << *i <<", ";
+            }
+            out << *last << ";\n";
+        }
+        break;
+    }
+}
+
+/** Prints an ASCII representation of the attribute table to the
+ indicated FILE pointer. The \c pad argument is prefixed to each
+ line of the output to provide control of indentation.
+
+ @brief Prints the attribute table.
+ @param out Print to the given output FILE.
+ @param pad Indent elements of a table using this string of spaces. By
+ default this is a string of four spaces
+ @param dereference If true, follow aliases. Default is false. */
+
+void
+AttrTable::print(FILE *out, string pad, bool dereference)
+{
+    for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
+        if ((*i)->is_alias) {
+            if (dereference) {
+                simple_print(out, pad, i, dereference);
+            }
+            else {
+                fprintf(out, "%sAlias %s %s;\n",
+                        pad.c_str(),
+                        id2www(get_name(i)).c_str(),
+                        id2www((*i)->aliased_to).c_str());
+            }
+        }
+        else {
+            simple_print(out, pad, i, dereference);
+        }
+    }
+}
+
+/** Prints an ASCII representation of the attribute table to the
+ indicated output stream. The \c pad argument is prefixed to each
+ line of the output to provide control of indentation.
+
+ @brief Prints the attribute table.
+ @param out Print to the given output stream.
+ @param pad Indent elements of a table using this string of spaces. By
+ default this is a string of four spaces
+ @param dereference If true, follow aliases. Default is false. */
+
+void
+AttrTable::print(ostream &out, string pad, bool dereference)
+{
+    for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
+        if ((*i)->is_alias) {
+            if (dereference) {
+                simple_print(out, pad, i, dereference);
+            }
+            else {
+                out << pad << "Alias " << id2www(get_name(i))
+                << " " << id2www((*i)->aliased_to) << ";\n";
+            }
+        }
+        else {
+            simple_print(out, pad, i, dereference);
+        }
+    }
+}
+
+/** Print the attribute table in XML.
+ @param out Destination
+ @param pad Indent lines of text/xml this much. Default is four spaces.
+ @param constrained Not used */
+void
+AttrTable::print_xml(FILE *out, string pad, bool /*constrained*/)
+{
+    // Why this works: AttrTable is really a hacked class that used to
+    // implement a single-level set of attributes. Containers
+    // were added several years later by dropping in the 'entry' structure.
+    // It's not a class in its own right; instead accessors from AttrTable
+    // are used to access information from entry. So... the loop below
+    // actually iterates over the entries of *this* (which is an instance of
+    // AttrTable). A container is an entry whose sole value is an AttrTable
+    // instance. 05/19/03 jhrg
+    for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
+        if ((*i)->is_alias) {
+            fprintf(out, "%s<Alias name=\"%s\" Attribute=\"%s\"/>\n",
+                    pad.c_str(), id2xml(get_name(i)).c_str(),
+                    (*i)->aliased_to.c_str());
+
+        }
+        else if (is_container(i)) {
+            fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
+                    pad.c_str(), id2xml(get_name(i)).c_str(),
+                    get_type(i).c_str());
+
+            get_attr_table(i)->print_xml(out, pad + "    "/*, constrained*/);
+
+            fprintf(out, "%s</Attribute>\n", pad.c_str());
+        }
+        else {
+            fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
+                    pad.c_str(), id2xml(get_name(i)).c_str(), get_type(i).c_str());
+
+            string value_pad = pad + "    ";
+            // Special handling for the OtherXML attribute type - don't escape
+            // the XML and don't include the <value> element. Note that there
+            // cannot be an vector of XML things as can be with the other types.
+            if (get_attr_type(i) == Attr_other_xml) {
+                if (get_attr_num(i) != 1)
+                    throw Error("OtherXML attributes cannot be vector-valued.");
+                fprintf(out, "%s%s\n", value_pad.c_str(), get_attr(i, 0).c_str());
+            }
+            else {
+                for (unsigned j = 0; j < get_attr_num(i); ++j) {
+                    fprintf(out, "%s<value>%s</value>\n", value_pad.c_str(),
+                	    id2xml(get_attr(i, j)).c_str());
+                }
+            }
+            fprintf(out, "%s</Attribute>\n", pad.c_str());
+        }
+    }
+}
+
+/** Print the attribute table in XML.
+ @param out Destination stream
+ @param pad Indent lines of text/xml this much. Default is four spaces.
+ @param constrained Not used */
+void
+AttrTable::print_xml(ostream &out, string pad, bool /*constrained*/)
+{
+    for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
+        if ((*i)->is_alias) {
+            out << pad << "<Alias name=\"" << id2xml(get_name(i))
+            << "\" Attribute=\"" << (*i)->aliased_to << "\"/>\n";
+
+        }
+        else if (is_container(i)) {
+            out << pad << "<Attribute name=\"" << id2xml(get_name(i))
+            << "\" type=\"" << get_type(i) << "\">\n";
+
+            get_attr_table(i)->print_xml(out, pad + "    "/*, constrained*/);
+
+            out << pad << "</Attribute>\n";
+        }
+        else {
+            out << pad << "<Attribute name=\"" << id2xml(get_name(i))
+            << "\" type=\"" << get_type(i) << "\">\n";
+
+            string value_pad = pad + "    ";
+            if (get_attr_type(i) == Attr_other_xml) {
+                if (get_attr_num(i) != 1)
+                    throw Error("OtherXML attributes cannot be vector-valued.");
+                out << value_pad << get_attr(i, 0) << "\n";
+            }
+            else {
+                string value_pad = pad + "    ";
+                for (unsigned j = 0; j < get_attr_num(i); ++j) {
+                    out << value_pad << "<value>" << id2xml(get_attr(i, j)) << "</value>\n";
+                }
+            }
+            out << pad << "</Attribute>\n";
+        }
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and all attributes stored
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+AttrTable::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "AttrTable::dump - ("
+    << (void *)this << ")" << endl;
+    DapIndent::Indent();
+    strm << DapIndent::LMarg << "table name: " << d_name << endl;
+    if (attr_map.size()) {
+        strm << DapIndent::LMarg << "attributes: " << endl;
+        DapIndent::Indent();
+        Attr_citer i = attr_map.begin();
+        Attr_citer ie = attr_map.end();
+        for (; i != ie; ++i) {
+            entry *e = (*i);
+            string type = AttrType_to_String(e->type);
+            if (e->is_alias) {
+                strm << DapIndent::LMarg << "alias: " << e->name
+                << " aliased to: " << e->aliased_to
+                << endl;
+            }
+            else if (e->type == Attr_container) {
+                strm << DapIndent::LMarg << "attr: " << e->name
+                << " of type " << type
+                << endl;
+                DapIndent::Indent();
+                e->attributes->dump(strm);
+                DapIndent::UnIndent();
+            }
+            else {
+                strm << DapIndent::LMarg << "attr: " << e->name
+                << " of type " << type
+                << endl;
+                DapIndent::Indent();
+                strm << DapIndent::LMarg;
+                vector<string>::const_iterator iter = e->attr->begin();
+                vector<string>::const_iterator last = e->attr->end() - 1;
+                for (; iter != last; ++iter) {
+                    strm << (*iter) << ", ";
+                }
+                strm << (*(e->attr->end() - 1)) << endl;
+                DapIndent::UnIndent();
+            }
+        }
+        DapIndent::UnIndent();
+    }
+    else {
+        strm << DapIndent::LMarg << "attributes: empty" << endl;
+    }
+    if (d_parent) {
+        strm << DapIndent::LMarg << "parent table:"
+        << d_name << ":" << (void *)d_parent << endl;
+    }
+    else {
+        strm << DapIndent::LMarg << "parent table: none" << d_name << endl;
+    }
+    DapIndent::UnIndent();
+}
+
+} // namespace libdap
+
diff --git a/AttrTable.h b/AttrTable.h
new file mode 100644
index 0000000..8a22b5a
--- /dev/null
+++ b/AttrTable.h
@@ -0,0 +1,346 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// An AttrTable is a table of attributes (type-name-value tuples).
+
+#ifndef _attrtable_h
+#define _attrtable_h 1
+
+
+#include <string>
+#include <vector>
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+using std::vector;
+using std::string;
+using std::vector;
+
+#ifndef A_DapObj_h
+#include "DapObj.h"
+#endif
+
+namespace libdap
+{
+
+/** <b>AttrType</b> identifies the data types which may appear in an
+    attribute table object.
+
+    \code
+    enum AttrType {
+ Attr_unknown,
+ Attr_container,
+ Attr_byte,
+ Attr_int16,
+ Attr_uint16,
+ Attr_int32,
+ Attr_uint32,
+ Attr_float32,
+ Attr_float64,
+ Attr_string,
+ Attr_url,
+ Attr_other_xml
+    };
+    \endcode
+
+    @see AttrTable */
+enum AttrType {
+    Attr_unknown,
+    Attr_container,
+    Attr_byte,
+    Attr_int16,
+    Attr_uint16,
+    Attr_int32,
+    Attr_uint32,
+    Attr_float32,
+    Attr_float64,
+    Attr_string,
+    Attr_url,
+    Attr_other_xml
+};
+
+string AttrType_to_String(const AttrType at);
+AttrType String_to_AttrType(const string &s);
+
+/** An AttrTable (``Attribute Table'') stores a set of names and, for
+    each name, either a type and a value, or another attribute table.
+    The attribute value can be a vector containing many values of the
+    same type.  The attributes can have any of the types listed in the
+    <tt>AttrType</tt> list.  However, all attribute types are stored as
+    string data, except for the container type, which is stored as a
+    pointer to another attribute table.
+
+    Each element in the attribute table can itself be an attribute
+    table.  The table can also contain ``alias'' attributes whose
+    value is given by the value of another attribute to which it is
+    linked.
+
+    The attribute tables have a standard printed representation.
+    There is a member function <tt>print()</tt> for writing this form.  Use
+    the <tt>DAS::parse()</tt> function to read the printed form.
+
+    An attribute table might look something like this:
+
+    \verbatim
+    string long_name "Weekly Means of Sea Surface Temperature";
+    actual_range {
+        Float64 min -1.8;
+        Float64 max 35.09;
+    }
+    string units "degC";
+    conversion_data {
+        Float64 add_offset 0.;
+        Float64 scale_factor 0.0099999998;
+    }
+    Int32 missing_value 32767;
+    \endverbatim
+
+    Here, <tt>long_name</tt>, <tt>units</tt>, and
+    <tt>missing_value</tt> are simple
+    attributes, and <tt>actual_range</tt> and <tt>conversion_data</tt>
+    are container attributes containing other attribute tables.
+
+    @todo Look at refactoring this by splitting it into three classes. Move
+    the struct entry into its own calls (maybe called Attribute?), make
+    AttrTable a child of that class and then make aliases a separate class,
+    also a child of Attribute. Look at the design of the Java code.
+
+    @todo A problem with this class is that Attr_iter objects cannot be
+    dereferenced to return attributes. Instead they must be passed to methods
+    which require that you have access to the AttrTable object into which
+    they point.03/09/04 jhrg
+
+    @brief Contains the attributes for a dataset.
+    @see DAS
+    @see AttrType */
+class AttrTable : public DapObj
+{
+    // entry needs to be made public to make up for issues with this class'
+    // design. It should probably be moved to it's own class. 05/22/03 jhrg
+public:
+    /** Each AttrTable has zero or more entries. Instead of accessing this
+    struct's members directly, use AttrTable methods.
+
+    This struct is public because its type is used in public typedefs. */
+    struct entry
+    {
+        string name;
+        AttrType type;
+
+        bool is_alias;
+        string aliased_to;
+
+        bool is_global; // use this to mark non-container attributes. see below.
+
+        // If type == Attr_container, use attributes to read the contained
+        // table, otherwise use attr to read the vector of values.
+        AttrTable *attributes;
+        std::vector<string> *attr; // a vector of values. jhrg 12/5/94
+
+        entry(): name(""), type(Attr_unknown), is_alias(false),
+                aliased_to(""), is_global(true), attributes(0), attr(0) {}
+
+        entry(const entry &rhs)
+        {
+            clone(rhs);
+        }
+
+        void delete_entry()
+        {
+            if (is_alias) // alias copies the pointers.
+                return;
+            if (type == Attr_container) {
+                delete attributes; attributes = 0;
+            }
+            else {
+                delete attr; attr = 0;
+            }
+        }
+
+        virtual ~entry()
+        {
+            delete_entry();
+        }
+
+        void clone(const entry &rhs)
+        {
+            name = rhs.name;
+            type = rhs.type;
+            is_alias = rhs.is_alias;
+            aliased_to = rhs.aliased_to;
+            is_global = rhs.is_global;
+            switch (rhs.type) {
+            case Attr_unknown:
+                break;
+            case Attr_container: {
+                if (rhs.is_alias)
+                    attributes = rhs.attributes;
+                else
+                    attributes = new AttrTable(*rhs.attributes);
+                break;
+            }
+            default: {
+                if (rhs.is_alias)
+                    attr = rhs.attr;
+                else
+                    attr = new std::vector<string>(*rhs.attr);
+                break;
+            }
+            }
+        }
+
+        entry &operator=(const entry &rhs)
+        {
+            if (this != &rhs) {
+                delete_entry();
+                clone(rhs);
+            }
+            return *this;
+        }
+    };
+
+    typedef std::vector<entry *>::const_iterator Attr_citer ;
+    typedef std::vector<entry *>::iterator Attr_iter ;
+
+private:
+    string d_name;
+    AttrTable *d_parent;
+    std::vector<entry *> attr_map;
+
+    // Use this to mark container attributes. Look at the methods
+    // is_global_attribute() and set_is_...., esp. at the versions that take
+    // an iterator. This code is tricky because it has to track both whole
+    // containers that are global and individual attributes that are 'global'
+    // relative to a constructor. That is, there are some attributes that are
+    // bound to a container and not any of the container's children.
+    bool d_is_global_attribute;
+
+    void delete_attr_table();
+
+    friend class AttrTableTest;
+
+protected:
+    void clone(const AttrTable &at);
+
+    void simple_print(FILE *out, string pad, Attr_iter i,
+                      bool dereference);
+    void simple_print(ostream &out, string pad, Attr_iter i,
+                      bool dereference);
+
+public:
+    AttrTable();
+    AttrTable(const AttrTable &rhs);
+    virtual ~AttrTable();
+    AttrTable & operator=(const AttrTable &rhs);
+
+    virtual void erase();
+
+    virtual unsigned int get_size() const;
+    virtual string get_name() const;
+    virtual void set_name(const string &n);
+
+    /** Return a pointer to the AttrTable which holds this table (aka, its
+        parent. If this AttrTable has no parent, this returns null.
+        @return A pointer to the parent AttrTable. */
+    virtual AttrTable *get_parent() const
+    {
+        return d_parent;
+    }
+
+    virtual bool is_global_attribute() const { return d_is_global_attribute; }
+    virtual void set_is_global_attribute(bool ga) { d_is_global_attribute = ga; }
+
+    virtual unsigned int append_attr(const string &name, const string &type,
+				     const string &value);
+    virtual unsigned int append_attr(const string &name, const string &type,
+				     vector<string> *values);
+
+    virtual AttrTable *append_container(const string &name);
+    virtual AttrTable *append_container(AttrTable *at, const string &name);
+
+    virtual void find(const string &target, AttrTable **at, Attr_iter *iter);
+    virtual AttrTable *find_container(const string &target);
+    virtual AttrTable *recurrsive_find(const string &target,
+				       Attr_iter *location);
+
+    Attr_iter simple_find(const string &target);
+    AttrTable *simple_find_container(const string &target);
+
+
+    virtual AttrTable *get_attr_table(const string &name);
+    virtual string get_type(const string &name);
+    virtual AttrType get_attr_type(const string &name);
+    virtual unsigned int get_attr_num(const string &name);
+    virtual string get_attr(const string &name, unsigned int i = 0);
+    virtual vector<string> *get_attr_vector(const string &name);
+    virtual void del_attr(const string &name, int i = -1);
+
+    virtual Attr_iter attr_begin();
+    virtual Attr_iter attr_end();
+    virtual Attr_iter get_attr_iter(int i);
+    virtual string get_name(Attr_iter iter);
+    virtual bool is_container(Attr_iter iter);
+    virtual AttrTable *get_attr_table(Attr_iter iter);
+    virtual Attr_iter del_attr_table(Attr_iter iter);
+    virtual string get_type(Attr_iter iter);
+    virtual AttrType get_attr_type(Attr_iter iter);
+    virtual unsigned int get_attr_num(Attr_iter iter);
+    virtual string get_attr(Attr_iter iter, unsigned int i = 0);
+    virtual std::vector<string> *get_attr_vector(Attr_iter iter);
+    virtual bool is_global_attribute(Attr_iter iter);
+    virtual void set_is_global_attribute(Attr_iter iter, bool ga);
+
+    virtual void add_container_alias(const string &name, AttrTable *src);
+    virtual void add_value_alias(AttrTable *at, const string &name,
+                         const string &source);
+    virtual bool attr_alias(const string &alias,
+			    AttrTable *at,
+			    const string &name);
+    virtual bool attr_alias(const string &alias, const string &name);
+
+    virtual void print(FILE *out, string pad = "    ",
+		       bool dereference = false);
+    virtual void print(ostream &out, string pad = "    ",
+		       bool dereference = false);
+
+    virtual void print_xml(FILE *out, string pad = "    ",
+			   bool constrained = false);
+    virtual void print_xml(ostream &out, string pad = "    ",
+			   bool constrained = false);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _attrtable_h
diff --git a/BaseType.cc b/BaseType.cc
new file mode 100644
index 0000000..422385d
--- /dev/null
+++ b/BaseType.cc
@@ -0,0 +1,1090 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for BaseType.
+//
+// jhrg 9/6/94
+
+#include "config.h"
+
+#include <cstdio>  // for stdin and stdout
+
+#include <sstream>
+#include <string>
+
+//#define DODS_DEBUG
+
+#include "BaseType.h"
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "InternalErr.h"
+
+#include "util.h"
+#include "escaping.h"
+
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+// Protected copy mfunc
+
+/** Perform a deep copy. Copies the values of \e bt into \c *this. Pointers
+    are dereferenced and their values are copied into a newly allocated
+    instance.
+
+    @brief Perform a deep copy.
+    @param bt The source object. */
+void
+BaseType::_duplicate(const BaseType &bt)
+{
+    DBG(cerr << "BaseType::_duplicate: " << bt._name << " send_p: "
+            << bt._send_p << endl);
+    _name = bt._name;
+    _type = bt._type;
+    _dataset = bt._dataset;
+    _read_p = bt._read_p; // added, reza
+    _send_p = bt._send_p; // added, reza
+    d_in_selection = bt.d_in_selection;
+    _synthesized_p = bt._synthesized_p; // 5/11/2001 jhrg
+
+    d_parent = bt.d_parent; // copy pointers 6/4/2001 jhrg
+
+    d_attr = bt.d_attr;  // Deep copy.
+}
+
+// Public mfuncs
+
+/** The BaseType constructor needs a name  and a type.
+    The BaseType class exists to provide data to
+    type classes that inherit from it.  The constructors of those
+    classes call the BaseType constructor; it is never called
+    directly.
+
+    @brief The BaseType constructor.
+    @param n A string containing the name of the new variable.
+    @param t The type of the variable.
+    data in this variable to a client DODS process.
+    @see Type */
+BaseType::BaseType(const string &n, const Type &t)
+        : _name(n), _type(t), _dataset(""), _read_p(false), _send_p(false),
+        d_in_selection(false), _synthesized_p(false), d_parent(0)
+{}
+
+/** The BaseType constructor needs a name, a dataset, and a type.
+    The BaseType class exists to provide data to
+    type classes that inherit from it.  The constructors of those
+    classes call the BaseType constructor; it is never called
+    directly.
+
+    @brief The BaseType constructor.
+    @param n A string containing the name of the new variable.
+    @param d A string containing the dataset name from which this variable
+    is created
+    @param t The type of the variable.
+    data in this variable to a client DODS process.
+    @see Type */
+BaseType::BaseType(const string &n, const string &d, const Type &t)
+        : _name(n), _type(t), _dataset(d), _read_p(false), _send_p(false),
+        d_in_selection(false), _synthesized_p(false), d_parent(0)
+{}
+
+/** @brief The BaseType copy constructor. */
+BaseType::BaseType(const BaseType &copy_from) : DapObj()
+{
+    _duplicate(copy_from);
+}
+
+BaseType::~BaseType()
+{
+    DBG(cerr << "Entering ~BaseType (" << this << ")" << endl);
+    DBG(cerr << "Exiting ~BaseType" << endl);
+}
+
+BaseType &
+BaseType::operator=(const BaseType &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+/** Write out the object's internal fields in a string. To be used for
+    debugging when regular inspection w/ddd or gdb isn't enough.
+
+    @return A string which shows the object's internal stuff. */
+string
+BaseType::toString()
+{
+    ostringstream oss;
+    oss << "BaseType (" << this << "):" << endl
+    << "          _name: " << _name << endl
+    << "          _type: " << type_name() << endl
+    << "          _dataset: " << _dataset << endl
+    << "          _read_p: " << _read_p << endl
+    << "          _send_p: " << _send_p << endl
+    << "          _synthesized_p: " << _synthesized_p << endl
+    << "          d_parent: " << d_parent << endl
+    << "          d_attr: " << hex << &d_attr << dec << endl;
+
+    return oss.str();
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and then displays information
+ * about this base type.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+BaseType::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "BaseType::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+
+    strm << DapIndent::LMarg << "name: " << _name << endl ;
+    strm << DapIndent::LMarg << "type: " << type_name() << endl ;
+    strm << DapIndent::LMarg << "dataset: " << _dataset << endl ;
+    strm << DapIndent::LMarg << "read_p: " << _read_p << endl ;
+    strm << DapIndent::LMarg << "send_p: " << _send_p << endl ;
+    strm << DapIndent::LMarg << "synthesized_p: " << _synthesized_p << endl ;
+    strm << DapIndent::LMarg << "parent: " << (void *)d_parent << endl ;
+    strm << DapIndent::LMarg << "attributes: " << endl ;
+    DapIndent::Indent() ;
+    d_attr.dump(strm) ;
+    DapIndent::UnIndent() ;
+
+    DapIndent::UnIndent() ;
+}
+
+/** @brief Returns the name of the class instance.
+ */
+string
+BaseType::name() const
+{
+    return _name;
+}
+
+/** @brief Sets the name of the class instance. */
+void
+BaseType::set_name(const string &n)
+{
+    string name = n;
+    _name = www2id(name); // www2id writes into its param.
+}
+
+/** @brief Returns the name of the dataset used to create this instance
+
+    A dataset from which the data is to be read. The meaning of this string
+    will vary among different types of data sources. It \e may be the name
+    of a data file or an identifier used to read data from a relational
+    database.
+ */
+string
+BaseType::dataset() const
+{
+    return _dataset;
+}
+
+/** @brief Returns the type of the class instance. */
+Type
+BaseType::type() const
+{
+    return _type;
+}
+
+/** @brief Sets the type of the class instance. */
+void
+BaseType::set_type(const Type &t)
+{
+    _type = t;
+}
+
+/** @brief Returns the type of the class instance as a string. */
+string
+BaseType::type_name() const
+{
+    switch (_type) {
+    case dods_null_c:
+        return string("Null");
+    case dods_byte_c:
+        return string("Byte");
+    case dods_int16_c:
+        return string("Int16");
+    case dods_uint16_c:
+        return string("UInt16");
+    case dods_int32_c:
+        return string("Int32");
+    case dods_uint32_c:
+        return string("UInt32");
+    case dods_float32_c:
+        return string("Float32");
+    case dods_float64_c:
+        return string("Float64");
+    case dods_str_c:
+        return string("String");
+    case dods_url_c:
+        return string("Url");
+    case dods_array_c:
+        return string("Array");
+    case dods_structure_c:
+        return string("Structure");
+    case dods_sequence_c:
+        return string("Sequence");
+    case dods_grid_c:
+        return string("Grid");
+    default:
+        cerr << "BaseType::type_name: Undefined type" << endl;
+        return string("");
+    }
+}
+
+/** @brief Returns true if the instance is a numeric, string or URL
+    type variable.
+    @return True if the instance is a scalar numeric, String or URL variable,
+    False otherwise. Arrays (even of simple types) return False.
+    @see is_vector_type() */
+bool
+BaseType::is_simple_type()
+{
+    switch (type()) {
+    case dods_null_c:
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+    case dods_str_c:
+    case dods_url_c:
+        return true;
+
+    case dods_array_c:
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+        return false;
+    }
+
+    return false;
+}
+
+/** @brief Returns true if the instance is a vector (i.e., array) type
+    variable.
+    @return True if the instance is an Array, False otherwise. */
+bool
+BaseType::is_vector_type()
+{
+    switch (type()) {
+    case dods_null_c:
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+    case dods_str_c:
+    case dods_url_c:
+        return false;
+
+    case dods_array_c:
+        return true;
+
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+        return false;
+    }
+
+    return false;
+}
+
+/** @brief Returns true if the instance is a constructor (i.e., Structure,
+    Sequence or Grid) type variable.
+    @return True if the instance is a Structure, Sequence or Grid, False
+    otherwise. */
+bool
+BaseType::is_constructor_type()
+{
+    switch (type()) {
+    case dods_null_c:
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+    case dods_str_c:
+    case dods_url_c:
+    case dods_array_c:
+        return false;
+
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+        return true;
+    }
+
+    return false;
+}
+
+/** Return a count of the total number of variables in this variable.
+    This is used to count the number of variables held by a constructor
+    variable - for simple type and vector variables it always
+    returns 1.
+
+    For compound data types, there are two ways to count members.
+    You can count the members, or you can count the simple members
+    and add that to the count of the compound members.  For
+    example, if a Structure contains an Int32 and another
+    Structure that itself contains two Int32 members, the element
+    count of the top-level structure could be two (one Int32 and
+    one Structure) or three (one Int32 by itself and two Int32's
+    in the subsidiary Structure).  Use the <i>leaves</i> parameter
+    to control which kind of counting you desire.
+
+    @brief Count the members of constructor types.
+    @return Returns 1 for simple
+    types.  For compound members, the count depends on the
+    <i>leaves</i> argument.
+    @param leaves This parameter is only relevant if the object
+    contains other compound data types.  If FALSE, the function
+    counts only the data variables mentioned in the object's
+    declaration.  If TRUE, it counts the simple members, and adds
+    that to the sum of the counts for the compound members.
+    This parameter has no effect for simple type variables. */
+int
+BaseType::element_count(bool)
+{
+    return 1;
+}
+
+/** Returns true if the variable is a synthesized variable. A synthesized
+    variable is one that is added to the dataset by the server (usually
+    with a `projection function'. */
+bool
+BaseType::synthesized_p()
+{
+    return _synthesized_p;
+}
+
+/** Set the synthesized flag. Before setting this flag be sure to set the
+    <tt>read_p()</tt> state. Once this flag is set you cannot
+    alter the state of the <tt>read_p</tt> flag!
+
+    @see synthesized_p() */
+void
+BaseType::set_synthesized_p(bool state)
+{
+    _synthesized_p = state;
+}
+
+// Return the state of _read_p (true if the value of the variable has been
+// read (and is in memory) false otherwise).
+
+/** Returns true if the value(s) for this variable have been read from the
+    data source, otherwise returns false. This method is used to determine
+    when values need to be read using the read() method. When read_p()
+    returns true, this library assumes that buf2val() (and other methods
+    such as get_vec()) can be used to access the value(s) of a variable.
+
+    @brief Has this variable been read?
+    @return True if the variable's value(s) have been read, false otherwise. */
+bool
+BaseType::read_p()
+{
+    return _read_p;
+}
+
+/** Sets the value of the <tt>read_p</tt> property. This indicates that the
+    value(s) of this variable has/have been read. An implementation of the
+    read() method would typically use this to set the \c read_p property to
+    true.
+
+    @note For most of the types the default implementation of this method is
+    fine. However, if you're building a server which must handle data
+    represented using nested sequences, then you may need to provide a
+    specialization of Sequence::set_read_p(). By default Sequence::set_read_()
+    recursively sets the \e read_p property for all child variables to
+    \e state. For servers where one Sequence reads an outer set of values
+    and another reads an inner set, this is cumbersome. In such a case, it is
+    easier to specialize Sequence::set_read_p() so that it does \e not
+    recursively set the \e read_p property for the inner Sequence. Be sure
+    to see the documentation for the read() method!
+
+    @note For synthesized variables, this method does nothing. Thus, if a
+    synthesized variable is added to a Sequence, the Sequence can iteratively
+    reset the \e read_p property without affecting the value of that property
+    for the synthesized variable. That's important since a synthesized
+    variable's value is calculated, not read.
+
+    @todo Look at making synthesized variables easier to implement and at
+    making them more integrated into the overall CE evaluation process.
+    Maybe the code that computes the synthesized var's value should be in the
+    that variable's read() method? This might provide a way to get rid of the
+    awkward 'projection functions' by replacing them with real children of
+    BaseType. It would also provide a way to clean up the way the
+    \e synthesized_p prop intrudes on the \e read_p prop.
+
+    @see BaseType::read()
+    @brief Sets the value of the \e read_p property.
+    @param state Set the \e read_p property to this state. */
+void
+BaseType::set_read_p(bool state)
+{
+    if (! _synthesized_p) {
+        DBG(cerr << "Changing read_p state of " << name() << " to "
+	         << state << endl);
+        _read_p = state;
+    }
+}
+
+/** Returns the state of the \c send_p property. If true, this variable
+    should be sent to the client, if false, it should not. If no constraint
+    expression (CE) has been evaluated, this property is true for all
+    variables in a data source (i.e., for all the variables listed in a DDS).
+    If a CE has been evaluated, this property is true only for those
+    variables listed in the <em>projection part</em> of the CE.
+
+    @brief Should this variable be sent?
+    @return True if the variable should be sent to the client, false
+    otherwise. */
+bool
+BaseType::send_p()
+{
+    return _send_p;
+}
+
+/** Sets the value of the <tt>send_p</tt> flag.  This
+    function is meant to be called from within the constraint evaluator of
+    other code which determines that this variable should be returned to the
+    client.  Data are ready to be sent when <i>both</i> the <tt>_send_p</tt>
+    and <tt>_read_p</tt> flags are set to TRUE.
+
+    @param state The logical state to set the <tt>send_p</tt> flag.
+*/
+void
+BaseType::set_send_p(bool state)
+{
+    DBG(cerr << "Calling BaseType::set_send_p() for: " << this->name()
+        << endl);
+    _send_p = state;
+}
+
+
+/** Get this variable's AttrTable. It's generally a bad idea to return a
+    reference to a contained object, but in this case it seems that building
+    an interface inside BaseType is overkill.
+
+    Use the AttrTable methods to manipulate the table. */
+AttrTable &
+BaseType::get_attr_table()
+{
+    return d_attr;
+}
+
+/** Set this variable's attribute table.
+    @param at Source of the attributes. */
+void
+BaseType::set_attr_table(const AttrTable &at)
+{
+    d_attr = at;
+}
+
+/**
+ * Transfer attributes from a DAS object into this variable. Because of the
+ * rough history of the DAS object and the way that various server code built
+ * the DAS, this is necessarily a heuristic process. The intent is that this
+ * method will be overridden by handlers that need to look for certain patterns
+ * in the DAS (e.g., hdf4's odd variable_dim_n; where n = 0, 1, 2, ...)
+ * attribute containers.
+ *
+ * There should be a one-to-one
+ * mapping between variables and attribute containers. However, in some cases
+ * one variable has attributes spread across several top level containers and
+ * in some cases one container is used by several variables
+ *
+ * @note This method is technically \e unnecessary because a server (or
+ * client) can easily add attributes directly using the DDS::get_attr_table
+ * or BaseType::get_attr_table methods and then poke values in using any
+ * of the methods AttrTable provides. This method exists to ease the
+ * transition to DDS objects which contain attribute information for the
+ * existing servers (Since they all make DAS objects separately from the
+ * DDS). They could be modified to use the same AttrTable methods but
+ * operate on the AttrTable instances in a DDS/BaseType instead of those in
+ * a DAS.
+  *
+ * @param at_container Transfer attributes from this container.
+ * @return void
+ */
+void
+BaseType::transfer_attributes(AttrTable *at_container)
+{
+    AttrTable *at = at_container->get_attr_table(name());
+
+    DBG(cerr << "In BaseType::transfer_attributes; processing " << name() << endl);
+
+    if (at) {
+	at->set_is_global_attribute(false);
+	DBG(cerr << "Processing AttrTable: " << at->get_name() << endl);
+
+	AttrTable::Attr_iter at_p = at->attr_begin();
+	while (at_p != at->attr_end()) {
+	    DBG(cerr << "About to append "  << endl);
+	    DBG(cerr << "attr name,type:" << at->get_name(at_p) << ", " << at->get_type(at_p) << endl);
+
+	    if (at->get_attr_type(at_p) == Attr_container)
+		get_attr_table().append_container(new AttrTable(*at->get_attr_table(at_p)),
+			at->get_name(at_p));
+	    else
+		get_attr_table().append_attr(at->get_name(at_p),
+			at->get_type(at_p), at->get_attr_vector(at_p));
+
+	    at_p++;
+	}
+    }
+}
+
+/** Does this variable appear in either the selection part or as a function
+    argument in the current constrain expression. If this property is set
+    (true) then implementations of the read() method should read this
+    variable.
+
+    @note This method does not check, nor does it know about the semantics of,
+    string arguments passed to functions. Those functions might include
+    variable names in strings; they are responsible for reading those variables.
+    See the grid (func_grid_select()) for an example.
+    @see BaseType::read()
+    @brief Is this variable part of the current selection? */
+bool
+BaseType::is_in_selection()
+{
+    return d_in_selection;
+}
+
+/** Set the \e in_selection property to \e state. This property indicates
+    that the variable is used as a parameter to a constraint expression
+    function or that it appears as an argument in a selection sub-expression.
+    If set (true), implementations of the BaseType::read() method should read
+    this variable.
+
+    @param state Set the \e in_selection property to this state.
+    @see BaseType::read()
+    @see BaseType::is_in_selection() for more information. */
+void
+BaseType::set_in_selection(bool state)
+{
+    d_in_selection = state;
+}
+
+// Protected method.
+/** Set the <tt>parent</tt> property for this variable. Only instances of
+    Constructor or Vector should call this method.
+
+    @param parent Pointer to the Constructor of Vector parent variable.
+    @exception InternalErr thrown if called with anything other than a
+    Constructor or Vector. */
+void
+BaseType::set_parent(BaseType *parent)
+{
+    if (!dynamic_cast<Constructor *>(parent)
+        && !dynamic_cast<Vector *>(parent))
+        throw InternalErr("Call to set_parent with incorrect variable type.");
+
+    d_parent = parent;
+}
+
+// Public method.
+
+/** Return a pointer to the Constructor or Vector which holds (contains)
+    this variable. If this variable is at the top level, this method
+    returns null.
+
+    @return A BaseType pointer to the variable's parent. */
+BaseType *
+BaseType::get_parent()
+{
+    return d_parent;
+}
+
+// Documented in the header file.
+BaseType *
+BaseType::var(const string &/*name*/, bool /*exact_match*/, btp_stack */*s*/)
+{
+    return static_cast<BaseType *>(0);
+}
+
+/** This version of var(...) searches for <i>name</i> and returns a
+    pointer to the BaseType object if found. It uses the same search
+    algorithm as BaseType::var(const string &, bool, btp_stack *) when
+    <i>exact_match</i> is false. In addition to returning a pointer to
+    the variable, it pushes onto <i>s</i> a BaseType pointer to each
+    constructor type that ultimately contains <i>name</i>.
+
+    @note The BaseType implementation always returns null. There are no default
+    values for the parameters. If var() is called w/o any params, the three
+    parameter version will be used.
+
+    @deprecated This method is deprecated because it tries first to use
+    exact_match and, if that fails, then tries leaf_match. It's better to use
+    the alternate form of var(...) and specify exactly what you'd like to do.
+
+    @return A pointer to the named variable. */
+BaseType *
+BaseType::var(const string &, btp_stack &)
+{
+    return static_cast<BaseType *>(0);
+}
+
+/** Adds a variable to an instance of a constructor class, such as Array,
+    Structure <em>et cetera</em>. This function is only used by those
+    classes. For constructors with more than one variable, the variables
+    appear in the same order in which they were added (i.e., the order in
+    which add_var() was called). Since this method is only for use by Vectors
+    and Constructors, the BaseType implementation throws InternalErr.
+
+    @note For the implementation of this method in Structure, Sequence, et c.,
+    first copy \e bt and then insert the copy. If \e bt is itself a constructor
+    type you must either use the var() method to get a pointer to the actual
+    instance added to \c *this or you must first add all of <em>bt</em>'s
+    children to it before adding it to \c *this. The implementations should use
+    _duplicate() to perform a deep copy of \e bt.
+
+    @brief Add a variable.
+
+    @todo We should get rid of the Part parameter and adopt the convention
+    that the first variable is the Array and all subsequent ones are Maps
+    (when dealing with a Grid, the only time Part matters). This would enable
+    several methods to migrate from Structure, Sequence and Grid to
+    Constructor.
+
+    @param bt The variable to be added to this instance. The caller of this
+    method <i>must</i> free memory it allocates for <tt>v</tt>. This method
+    will make a deep copy of the object pointed to by <tt>v</tt>.
+    @param part The part of the constructor data to be modified. Only
+    meaningful for Grid variables.
+
+    @see Part */
+void
+BaseType::add_var(BaseType *, Part)
+{
+    throw InternalErr(__FILE__, __LINE__, "BaseType::add_var unimplemented");
+}
+
+/** This method should be implemented for each of the data type classes (Byte,
+    ..., Grid) when using the DAP class library to build a server. This
+    method is only for DAP servers. The library provides a default
+    definition here which throws an InternalErr exception \e unless the read_p
+    property has been set. In that case it returns false, indicating that all
+    the data have been read. The latter case can happen when building a
+    constant value that needs to be passed to a function. The variable/constant
+    is loaded with a value when it is created.
+
+    When implementing a new DAP server, the Byte, ..., Grid data type classes
+    are usually specialized. In each of those specializations read() should
+    be defined to read values from the data source and store them in the
+    object's local buffer. The read() method is called by other methods in
+    this library. When writing read(), follow these rules:
+
+    <ul>
+    <li> read() should throw Error if it encounters an error. The message
+   should be verbose enough to be understood by someone running a
+   client on a different machine.</li>
+    <li> The value(s) should be read if and only if either send_p() or
+          is_in_selection() return true. If neither of these return true, the
+   value(s) should not be read. This is important when writing read()
+   for a Constructor type such as Grid where a client may ask for only
+   the map vectors (and thus reading the much larger Array part is not
+   needed).</li>
+    <li> For each specialization of read(), the method should first test
+          the value of the \c read_p property (using the read_p() method)
+          and read values only if the value of read_p() is false. Once the
+          read() method reads data and stores it in the instance, it must
+          set the value of the \c read_p property to true using set_read_p().
+          If your read() methods fail to do this data may not serialize
+          correctly.</li>
+    <li> The Array::read() and Grid::read() methods should take into account
+   any restrictions on Array sizes.</li>
+    <li> If you are writing Sequence::read(), be sure to check the
+          documentation for Sequence::read_row() and Sequence::serialize()
+          so you understand how Sequence::read() is being called.</li>
+    <li> For Sequence::read(), your specialization must correctly manage the
+          \c unsent_data property and row count in addition to the \c read_p
+          property (handle the \c read_p property as describe above). For a
+          Sequence to serialize correctly, once all data from the Sequence
+          has been read, \c unsent_data property must be set to false (use
+          Sequence::set_unsent_data()). Also, at that time the row number
+          counter must be reset (use Sequence::reset_row_counter()). Typically
+          the correct time to set \c unsent_data to false and reset the row
+          counter is the time when Sequence::read() return false indicating
+          that all the data for the Sequence have been read. Failure to
+          handle these tasks will break serialization of nested Sequences. Note
+          that when Sequence::read() returns with a result of true (indicating
+          there is more data to send, the value of the \c unsent_data property
+          should be true.
+
+          Also, if you server must handle nested sequences, be sure to read
+          about subclassing set_read_p().</li>
+    </ul>
+
+    @brief Read data into a local buffer.
+
+    @return The return value of this method for all types except Sequence
+    should always be false. Sequences should return true to indicate more
+    values remain in the Sequence, false to indicate no more values remain.
+    (see Sequence::serialize() and Sequence::read_row()).
+
+    @see BaseType
+    @see Sequence  */
+bool
+BaseType::read()
+{
+    if (_read_p)
+        return false;
+
+    throw InternalErr("Unimplemented BaseType::read() method called.");
+}
+
+void
+BaseType::intern_data(ConstraintEvaluator &, DDS &dds)
+{
+    dds.timeout_on();
+    DBG(cerr << "BaseType::intern_data: " << name() << endl);
+    if (!read_p())
+        read();          // read() throws Error and InternalErr
+
+    dds.timeout_off();
+}
+
+#if FILE_METHODS
+/** Write the variable's declaration in a C-style syntax. This
+    function is used to create textual representation of the Data
+    Descriptor Structure (DDS).  See <i>The DODS User Manual</i> for
+    information about this structure.
+
+    A simple array declaration might look like this:
+    \verbatim
+    Float64 lat[lat = 180];
+    \endverbatim
+    While a more complex declaration (for a Grid, in this case),
+    would look like this:
+    \verbatim
+    Grid {
+    ARRAY:
+    Int32 sst[time = 404][lat = 180][lon = 360];
+    MAPS:
+    Float64 time[time = 404];
+    Float64 lat[lat = 180];
+    Float64 lon[lon = 360];
+    } sst;
+    \endverbatim
+
+    @brief Print an ASCII representation of the variable structure.
+    @param out The output stream on which to print the
+    declaration.
+    @param space Each line of the declaration will begin with the
+    characters in this string.  Usually used for leading spaces.
+    @param print_semi A boolean value indicating whether to print a
+    semicolon at the end of the declaration.
+    @param constraint_info A boolean value indicating whether
+    constraint information is to be printed with the declaration.
+    If the value of this parameter is TRUE, <tt>print_decl()</tt> prints
+    the value of the variable's <tt>send_p()</tt> flag after the
+    declaration.
+    @param constrained If this boolean value is TRUE, the variable's
+    declaration is only printed if is the <tt>send_p()</tt> flag is TRUE.
+    If a constraint expression is in place, and this variable is not
+    requested, the <tt>send_p()</tt> flag is FALSE.
+
+    @see DDS
+    @see DDS::CE
+*/
+void
+BaseType::print_decl(FILE *out, string space, bool print_semi,
+                     bool constraint_info, bool constrained)
+{
+    // if printing the constrained declaration, exit if this variable was not
+    // selected.
+    if (constrained && !send_p())
+        return;
+
+    fprintf(out, "%s%s %s", space.c_str(), type_name().c_str(),
+            id2www(_name).c_str()) ;
+
+    if (constraint_info) {
+        if (send_p())
+            fprintf(out, ": Send True") ;
+        else
+            fprintf(out, ": Send False") ;
+    }
+
+    if (print_semi)
+        fprintf(out, ";\n") ;
+}
+#endif
+
+/** Write the variable's declaration in a C-style syntax. This
+    function is used to create textual representation of the Data
+    Descriptor Structure (DDS).  See <i>The DODS User Manual</i> for
+    information about this structure.
+
+    A simple array declaration might look like this:
+    \verbatim
+    Float64 lat[lat = 180];
+    \endverbatim
+    While a more complex declaration (for a Grid, in this case),
+    would look like this:
+    \verbatim
+    Grid {
+    ARRAY:
+    Int32 sst[time = 404][lat = 180][lon = 360];
+    MAPS:
+    Float64 time[time = 404];
+    Float64 lat[lat = 180];
+    Float64 lon[lon = 360];
+    } sst;
+    \endverbatim
+
+    @brief Print an ASCII representation of the variable structure.
+    @param out The output stream on which to print the
+    declaration.
+    @param space Each line of the declaration will begin with the
+    characters in this string.  Usually used for leading spaces.
+    @param print_semi A boolean value indicating whether to print a
+    semicolon at the end of the declaration.
+    @param constraint_info A boolean value indicating whether
+    constraint information is to be printed with the declaration.
+    If the value of this parameter is TRUE, <tt>print_decl()</tt> prints
+    the value of the variable's <tt>send_p()</tt> flag after the
+    declaration.
+    @param constrained If this boolean value is TRUE, the variable's
+    declaration is only printed if is the <tt>send_p()</tt> flag is TRUE.
+    If a constraint expression is in place, and this variable is not
+    requested, the <tt>send_p()</tt> flag is FALSE.
+
+    @see DDS
+    @see DDS::CE
+*/
+void
+BaseType::print_decl(ostream &out, string space, bool print_semi,
+                     bool constraint_info, bool constrained)
+{
+    // if printing the constrained declaration, exit if this variable was not
+    // selected.
+    if (constrained && !send_p())
+        return;
+
+    out << space << type_name() << " " << id2www(_name) ;
+
+    if (constraint_info) {
+        if (send_p())
+            out << ": Send True" ;
+        else
+            out << ": Send False" ;
+    }
+
+    if (print_semi)
+	out << ";\n" ;
+}
+
+#if FILE_METHODS
+/** Write the XML representation of this variable. This method is used to
+    build the DDX XML response.
+    @param out Destination.
+    @param space Use this to indent child declarations. Default is "".
+    @param constrained If true, only print this if it's part part of the
+    current projection. Default is False. */
+void
+BaseType::print_xml(FILE *out, string space, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
+    if (!_name.empty())
+        fprintf(out, " name=\"%s\"", id2xml(_name).c_str());
+
+    if (get_attr_table().get_size() > 0) {
+        fprintf(out, ">\n"); // close the variable's tag
+        get_attr_table().print_xml(out, space + "    ", constrained);
+        // After attributes, print closing tag
+        fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
+    }
+    else {
+        fprintf(out, "/>\n"); // no attributes; just close tag.
+    }
+}
+#endif
+
+/** Write the XML representation of this variable. This method is used to
+    build the DDX XML response.
+    @param out Destination output stream
+    @param space Use this to indent child declarations. Default is "".
+    @param constrained If true, only print this if it's part part of the
+    current projection. Default is False. */
+void
+BaseType::print_xml(ostream &out, string space, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    out << space << "<" << type_name() ;
+    if (!_name.empty())
+	out << " name=\"" << id2xml(_name) << "\"" ;
+
+    if (get_attr_table().get_size() > 0) {
+	out << ">\n" ;
+        get_attr_table().print_xml(out, space + "    ", constrained);
+        // After attributes, print closing tag
+	out << space << "</" << type_name() << ">\n" ;
+    }
+    else {
+	out << "/>\n" ;
+    }
+}
+
+// Compares the object's current state with the semantics of a particular
+// type. This will typically be defined in ctor classes (which have
+// complicated semantics). For BaseType, an object is semantically correct if
+// it has both a non-null name and type.
+//
+// NB: This is not the same as an invariant -- during the parse objects exist
+// but have no name. Also, the bool ALL defaults to false for BaseType. It is
+// used by children of CtorType.
+//
+// Returns: true if the object is semantically correct, false otherwise.
+
+/** This function checks the class instance for internal
+    consistency.  This is important to check for complex constructor
+    classes.  For BaseType, an object is semantically correct if it
+    has both a non-null name and type.
+
+    For example, an Int32 instance would return FALSE if it had no
+    name or no type defined.  A Grid instance might return FALSE for
+    more complex reasons, such as having Map arrays of the wrong
+    size or shape.
+
+    This function is used by the DDS class, and will rarely, if
+    ever, be explicitly called by a DODS application program.  A
+    variable must pass this test before it is sent, but there may be
+    many other stages in a retrieve operation where it would fail.
+
+    @brief Compare an object's current state with the semantics of its
+    type.
+    @return Returns FALSE when the current state violates some
+    aspect of the type semantics, TRUE otherwise.
+
+    @param msg A returned string, containing a message indicating
+    the source of any problem.
+    @param all For complex constructor types (Grid,
+    Sequence, Structure), this flag indicates whether to check the
+    semantics of the member variables, too.
+
+    @see DDS::check_semantics
+*/
+bool
+BaseType::check_semantics(string &msg, bool)
+{
+    bool sem = (_type != dods_null_c && _name.length());
+
+    if (!sem)
+        msg = "Every variable must have both a name and a type\n";
+
+    return sem;
+}
+
+/** This method contains the relational operators used by the constraint
+    expression evaluator in the DDS class. Each class that wants to be able
+    to evaluate relational expressions must overload this function. The
+    implementation in BaseType throws an InternalErr exception. The DAP
+    library classes Byte, ..., Url provide specializations of this method. It
+    is not meaningful for classes such as Array because relational
+    expressions using Array are not supported.
+
+    The <i>op</i> argument refers to a table generated by bison from
+    the constraint expression parser.  Use statements like the
+    following to correctly interpret its value:
+
+    \verbatim
+    switch (op) {
+        case EQUAL: return i1 == i2;
+        case NOT_EQUAL: return i1 != i2;
+        case GREATER: return i1 > i2;
+        case GREATER_EQL: return i1 >= i2;
+        case LESS: return i1 < i2;
+        case LESS_EQL: return i1 <= i2;
+        case REGEXP: throw Error("Regular expressions are not supported for integer values");
+        default: throw Error("Unknown operator");
+    }
+    \endverbatim
+
+    This function is used by the constraint expression evaluator.
+
+    @brief Evaluate relational operators.
+    @param b Compare the value of this instance with \e b.
+    @param op An integer index indicating which relational operator
+    is implied. Choose one from the following: <tt>EQUAL</tt>,
+    <tt>NOT_EQUAL</tt>, <tt>GREATER</tt>, <tt>GREATER_EQL</tt>,
+    <tt>LESS</tt>, <tt>LESS_EQL</tt>, and <tt>REGEXP</tt>.
+    @return The boolean value of the comparison. */
+bool
+BaseType::ops(BaseType *, int)
+{
+    // Even though ops is a public method, it can never be called because
+    // they will never have a BaseType object since this class is abstract,
+    // however any of the child classes could by mistake call BaseType::ops
+    // so this is an internal error. Jose Garcia
+    throw InternalErr(__FILE__, __LINE__, "Unimplemented operator.");
+}
+
+} // namespace libdap
diff --git a/BaseType.h b/BaseType.h
new file mode 100644
index 0000000..5d74743
--- /dev/null
+++ b/BaseType.h
@@ -0,0 +1,513 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//         Dan Holloway <dan at hollywood.gso.uri.edu>
+//         Reza Nekovei <reza at intcomm.net>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+//      dan             Dan Holloway <dan at hollywood.gso.uri.edu>
+//      reza            Reza Nekovei <reza at intcomm.net>
+
+// Abstract base class for the variables in a dataset. This is used to store
+// the type-invariant information that describes a variable as given in the
+// DODS API.
+//
+// jhrg 9/6/94
+
+#ifndef _basetype_h
+#define _basetype_h 1
+
+
+#include <vector>
+#include <stack>
+#include <iostream>
+#include <string>
+
+#ifndef _attrtable_h
+#include "AttrTable.h"
+#endif
+
+#ifndef _internalerr_h
+#include "InternalErr.h"
+#endif
+
+#ifndef __DODS_DATATYPES_
+#include "dods-datatypes.h"
+#endif
+
+#ifndef A_DapObj_h
+#include "DapObj.h"
+#endif
+
+#include "Marshaller.h"
+#include "UnMarshaller.h"
+
+#define FILE_METHODS 1
+
+using namespace std;
+
+namespace libdap
+{
+
+class DDS;
+class ConstraintEvaluator;
+
+/** <b>Part</b> names the parts of multi-section constructor types.
+    For example, the <b>Grid</b> class has an <i>array</i> and
+    the array <i>maps</i>. Use the <tt>nil</tt> value for data types that
+    don't have separate parts.
+
+    \code
+    enum Part {
+    nil,
+    array,
+    maps
+    };
+    \endcode
+
+    @brief Names the parts of multi-section constructor data types.
+    @see Grid
+    @see BaseType
+*/
+
+enum Part {
+    nil,   // nil is for types that don't have parts...
+    array,
+    maps
+};
+
+/** <b>Type</b> identifies the data type stored in a particular type
+    class.  All the DODS Data Access Protocol (DAP) types inherit from
+    the BaseType class.
+
+    \code
+    enum Type {
+    dods_null_c,
+    dods_byte_c,
+    dods_int16_c,
+    dods_uint16_c,
+    dods_int32_c,
+    dods_uint32_c,
+    dods_float32_c,
+    dods_float64_c,
+    dods_str_c,
+    dods_url_c,
+    dods_array_c,
+    dods_structure_c,
+    dods_sequence_c,
+    dods_grid_c
+    };
+    \endcode
+
+    @brief Identifies the data type.
+    @see BaseType
+*/
+
+enum Type {
+    dods_null_c,
+    dods_byte_c,
+    dods_int16_c,
+    dods_uint16_c,
+    dods_int32_c,  // Added `dods_' to fix clash with IRIX 5.3.
+    dods_uint32_c,
+    dods_float32_c,
+    dods_float64_c,
+    dods_str_c,
+    dods_url_c,
+    dods_array_c,
+    dods_structure_c,
+    dods_sequence_c,
+    dods_grid_c
+};
+
+/** This defines the basic data type features for the DODS data access
+    protocol (DAP) data types. All the DAP type classes (Float64, Array,
+    etc.) subclass it. This class is an abstract one; no variables will ever
+    be stored as BaseType instances, only as instances of its child classes.
+
+    These classes and their methods give a user the capacity to set up
+    sophisticated data types. They do <i>not</i> provide sophisticated ways to
+    access and use this data. On the server side, in many cases, the class
+    instances will have no data in them at all until the
+    <tt>serialize</tt> function
+    is called to send data to the client. On the client side, most DODS
+    application programs will unpack the data promptly into whatever local
+    data structure the programmer deems the most useful.
+
+    In order to use these classes on the server side of a DODS
+    client/server connection, you must write a <tt>read</tt> method
+    for each of the data types you expect to encounter in the
+    application. This function, whose purpose is to read data from a
+    local source into the class instance data buffer, is called in
+    <tt>serialize</tt>, when the data is about to be sent to the
+    client.  The <tt>read</tt> function may be called earlier, in the
+    case of data subset requests (constraint expressions) whose
+    evaluation requires it. (For example, the constraint expression
+    ``<tt>a,b&b>c</tt>'' requires that <tt>c</tt> be read even though
+    it will not be sent.)
+
+    For some data types, the <tt>read</tt> function must be aware of
+    the constraints
+    to be returned. These cautions are outlined where they occur.
+
+    @todo We really need a better way to get values out of these types, esp.
+    the Float32, Int16, ..., types. In \e most cases we know the type, so a
+    type specific method (one that requires a downcast to use) is OK. For
+    example, Byte might have a method <tt>dods_byte Byte::value()</tt>. Sure
+    you have to downcast from BaseType to Byte in order to use it, but you
+    have to figure out you have a Byte to use Byte::buf2val() anyway, so
+    what's the big deal? Having a method that returns the \e value would
+    simplify code that reads from data sets to extract meta data (like
+    lat/lon corner points, et c.).
+
+    @brief The basic data type for the DODS DAP types.  */
+
+class BaseType : public DapObj
+{
+private:
+    string _name;  // name of the instance
+    Type _type;   // instance's type
+    string _dataset; // name of the dataset used to create this BaseType
+
+    bool _read_p;  // true if the value has been read
+    bool _send_p;  // Is the variable in the projection?
+    bool d_in_selection; // Is the variable in the selection?
+    bool _synthesized_p; // true if the variable is synthesized
+
+    // d_parent points to the Constructor or Vector which holds a particular
+    // variable. It is null for simple variables. The Vector and Constructor
+    // classes must maintain this variable.
+    BaseType *d_parent;
+
+    // Attributes for this variable. Added 05/20/03 jhrg
+    AttrTable d_attr;
+
+protected:
+    void _duplicate(const BaseType &bt);
+
+public:
+    typedef stack<BaseType *> btp_stack;
+
+    BaseType(const string &n, const Type &t);
+    BaseType(const string &n, const string &d, const Type &t);
+
+    BaseType(const BaseType &copy_from);
+    virtual ~BaseType();
+
+    virtual string toString();
+
+    virtual void dump(ostream &strm) const ;
+
+    BaseType &operator=(const BaseType &rhs);
+
+    /** Clone this instance. Allocate a new instance and copy \c *this into
+	it. This method must perform a deep copy.
+
+        @note This method should \e not copy data values, but must copy all
+        other fields in the object.
+	@return A newly allocated copy of \c this. */
+    virtual BaseType *ptr_duplicate() = 0;
+
+    string name() const;
+    virtual void set_name(const string &n);
+
+    Type type() const;
+    void set_type(const Type &t);
+    string type_name() const;
+
+    string dataset() const ;
+
+    virtual bool is_simple_type();
+    virtual bool is_vector_type();
+    virtual bool is_constructor_type();
+
+    virtual bool synthesized_p();
+    virtual void set_synthesized_p(bool state);
+
+    virtual int element_count(bool leaves = false);
+
+    virtual bool read_p();
+    virtual void set_read_p(bool state);
+
+    virtual bool send_p();
+    virtual void set_send_p(bool state);
+
+    virtual AttrTable &get_attr_table();
+    virtual void set_attr_table(const AttrTable &at);
+
+    virtual bool is_in_selection();
+    virtual void set_in_selection(bool state);
+
+    virtual void set_parent(BaseType *parent);
+    virtual BaseType *get_parent();
+
+    virtual void transfer_attributes(AttrTable *at);
+
+    // I put this comment here because the version in BaseType.cc does not
+    // include the exact_match or s variables since they are not used. Doxygen
+    // was gaging on the comment.
+
+    /** Returns a pointer to the contained variable in a composite class. The
+        composite classes are those made up of aggregated simple data types.
+        Array, Grid, and Structure are composite types, while Int and Float are
+        simple types. This function is only used by composite classes. The
+        BaseType implementation always returns null.
+
+        Several of the subclasses provide alternate access methods
+        that make sense for that particular data type. For example,
+        the Array class defines a <tt>*var(int i)</tt> method that
+        returns the ith entry in the Array data, and the Structure
+        provides a <tt>*var(Vars_iter)</tt> function using a
+        pseudo-index to access the different members of the structure.
+
+        @brief Returns a pointer to a member of a constructor class.
+        @param name The name of the class member.  Defaults to ""
+        @param exact_match True if only interested in variables whose
+        full names match \e n exactly. If false, returns the first
+        variable whose name matches \e name. For example, if \e name
+        is \c x and \c point.x is a variable, then var("x", false)
+        would return a BaseType pointer to \c point.x. If \e
+        exact_match was <tt>true</tt> then \e name would need to be \c
+        "point.x" for var to return that pointer. This feature
+        simplifies constraint expressions for datasets which have
+        complex, nested, constructor variables. Defaults to true.
+        @param s Record the path to \e name. Defaults to null, in
+        which case it is not used.
+        @return A pointer to the member named in the \e n argument. If
+        no name is given, the function returns the first (only)
+        variable. For example, an Array has only one variable, while a
+        Structure can have many. */
+    virtual BaseType *var(const string &name = "", bool exact_match = true,
+                          btp_stack *s = 0);
+    virtual BaseType *var(const string &name, btp_stack &s);
+
+    virtual void add_var(BaseType *bt, Part part = nil);
+
+    virtual bool read();
+
+    virtual bool check_semantics(string &msg, bool all = false);
+
+    virtual bool ops(BaseType *b, int op);
+#if FILE_METHODS
+    virtual void print_decl(FILE *out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+
+    virtual void print_xml(FILE *out, string space = "    ",
+                           bool constrained = false);
+#endif
+    virtual void print_decl(ostream &out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+
+    virtual void print_xml(ostream &out, string space = "    ",
+                           bool constrained = false);
+
+    /** @name Abstract Methods */
+    //@{
+
+    /** Return the number of bytes that are required to hold the
+	instance's value. In the case of simple types such as Int32,
+	this is the size of one Int32 (four bytes). For a String or
+	Url type, <tt>width()</tt> returns the number of bytes needed
+	for a <tt>String *</tt> variable, not the bytes needed for all
+	the characters, since that value cannot be determined from
+	type information alone. For Structure, and other constructor
+	types size() returns the number of bytes needed to store
+	pointers to the C++ objects.
+
+	@brief Returns the size of the class instance data. */
+    virtual unsigned int width() = 0;
+
+    /** Reads the class data into the memory referenced by <i>val</i>.
+	The caller should either allocate enough storage to <i>val</i>
+	to hold the class data or set \c *val to null. If <i>*val</i>
+	is NULL, memory will be allocated by this function with
+	<tt>new()</tt>. If the memory is allocated this way, the
+	caller is responsible for deallocating that memory. Array and
+	values for simple types are stored as C would store an array.
+
+    @deprecated Use value() in the leaf classes.
+
+	@brief Reads the class data.
+
+	@param val A pointer to a pointer to the memory into which the
+	class data will be copied. If the value pointed to is NULL,
+	memory will be allocated to hold the data, and the pointer
+	value modified accordingly. The calling program is responsible
+	for deallocating the memory references by this pointer.
+
+	@return The size (in bytes) of the information copied to <i>val</i>.
+    */
+    virtual unsigned int buf2val(void **val) = 0;
+
+    /** Store the value pointed to by <i>val</i> in the object's
+	internal buffer. This function does not perform any checks, so
+	users must be sure that the thing pointed to can actually be
+	stored in the object's buffer.
+
+	Only simple objects (Int, Float, Byte, and so on) and arrays
+	of these simple objects may be stored using this function. To
+	put data into more complex constructor types, use the
+	functions provided by that class.
+
+    @deprecated Use set_value() in the leaf classes.
+
+	@brief Loads class data.
+
+	@param val A pointer to the data to be inserted into the class
+	data buffer.
+
+	@param reuse A boolean value, indicating whether the class
+	internal data storage can be reused or not. If this argument
+	is TRUE, the class buffer is assumed to be large enough to
+	hold the incoming data, and it is <i>not</i> reallocated. If
+	FALSE, new storage is allocated. If the internal buffer has
+	not been allocated at all, this argument has no effect. This
+	is currently used only in the Vector class.
+
+	@return The size (in bytes) of the information copied from
+	<i>val</i>.
+	@see Grid
+	@see Vector::val2buf */
+    virtual unsigned int val2buf(void *val, bool reuse = false) = 0;
+
+    /** Similar to using serialize() and deserialize() together in one object.
+        Data are read as for serialize and those values are stored in the
+        objects as deserialize() does but does not write and then read data
+        to/from a stream.
+
+        This method is defined by the various data type classes. It calls the
+        read() abstract method.
+
+        @param eval Use this as the constraint expression evaluator.
+        @param dds The Data Descriptor Structure object corresponding
+        to this dataset. See <i>The DODS User Manual</i> for
+        information about this structure. */
+    virtual void intern_data(ConstraintEvaluator &eval, DDS &dds);
+
+    /** Sends the data from the indicated (local) dataset through the
+	connection identified by the <i>sink</i> parameter. If the
+	data is not already incorporated into the DDS object, read the
+	data from the dataset.
+
+	This function is only used on the server side of the
+	client/server connection, and is generally only called from
+	the ResponseBuilder functions. It has no BaseType
+	implementation; each datatype child class supplies its own
+	implementation.
+
+	@brief Move data to the net.
+
+        @param eval Use this as the constraint expression evaluator.
+	@param dds The Data Descriptor Structure object corresponding
+	to this dataset. See <i>The DODS User Manual</i> for
+	information about this structure.
+	@param m A marshaller used to serialize data types
+	@param ce_eval A boolean value indicating whether to evaluate
+	the DODS constraint expression that may accompany this
+	dataset. The constraint expression is stored in <i>dds</i>.
+	@return This method always returns true. Older versions used
+	the return value to signal success or failure.
+
+	@exception InternalErr.
+	@exception Error.
+	@see DDS */
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true) = 0;
+
+    /** Receives data from the network connection identified by the
+	<tt>source</tt> parameter. The data is put into the class data
+	buffer according to the input <tt>dds</tt>.
+
+	This function is only used on the client side of the DODS
+	client/server connection.
+
+	@brief Receive data from the net.
+
+	@param um An UnMarshaller that knows how to deserialize data types
+	@param dds The Data Descriptor Structure object corresponding
+	to this dataset. See <i>The DODS User Manual</i> for
+	information about this structure. This would have been
+	received from the server in an earlier transmission.
+	@param reuse A boolean value, indicating whether the class
+	internal data storage can be reused or not. If this argument
+	is TRUE, the class buffer is assumed to be large enough to
+	hold the incoming data, and it is <i>not</i> reallocated. If
+	FALSE, new storage is allocated. If the internal buffer has
+	not been allocated at all, this argument has no effect.
+	@return Always returns TRUE.
+	@exception Error when a problem reading from the UnMarshaller is
+	found.
+	@see DDS */
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false) = 0;
+
+#if FILE_METHODS
+    /** Prints the value of the variable, with its declaration. This
+	function is primarily intended for debugging DODS
+	applications. However, it can be overloaded and used to do
+	some useful things. Take a look at the asciival and writeval
+	clients, both of which overload this to output the values of
+	variables in different ways.
+
+	@brief Prints the value of the variable.
+
+	@param out The output stream on which to print the value.
+	@param space This value is passed to the print_decl()
+	function, and controls the leading spaces of the output.
+	@param print_decl_p A boolean value controlling whether the
+	variable declaration is printed as well as the value. */
+
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true) = 0;
+#endif
+
+    /** Prints the value of the variable, with its declaration. This
+	function is primarily intended for debugging DODS
+	applications. However, it can be overloaded and used to do
+	some useful things. Take a look at the asciival and writeval
+	clients, both of which overload this to output the values of
+	variables in different ways.
+
+	@brief Prints the value of the variable.
+
+	@param out The output ostream on which to print the value.
+	@param space This value is passed to the print_decl()
+	function, and controls the leading spaces of the output.
+	@param print_decl_p A boolean value controlling whether the
+	variable declaration is printed as well as the value. */
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true) = 0;
+    //@}
+};
+
+} // namespace libdap
+
+#endif // _basetype_h
diff --git a/BaseTypeFactory.cc b/BaseTypeFactory.cc
new file mode 100644
index 0000000..6c899e7
--- /dev/null
+++ b/BaseTypeFactory.cc
@@ -0,0 +1,128 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+
+#include <string>
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "BaseTypeFactory.h"
+#include "debug.h"
+
+namespace libdap {
+
+Byte *
+BaseTypeFactory::NewByte(const string &n) const
+{
+    return new Byte(n);
+}
+
+Int16 *
+BaseTypeFactory::NewInt16(const string &n) const
+{
+    return new Int16(n);
+}
+
+UInt16 *
+BaseTypeFactory::NewUInt16(const string &n) const
+{
+    return new UInt16(n);
+}
+
+Int32 *
+BaseTypeFactory::NewInt32(const string &n) const
+{
+    DBG(cerr << "Inside BaseTypeFactory::NewInt32" << endl);
+    return new Int32(n);
+}
+
+UInt32 *
+BaseTypeFactory::NewUInt32(const string &n) const
+{
+    return new UInt32(n);
+}
+
+Float32 *
+BaseTypeFactory::NewFloat32(const string &n) const
+{
+    return new Float32(n);
+}
+
+Float64 *
+BaseTypeFactory::NewFloat64(const string &n) const
+{
+    return new Float64(n);
+}
+
+Str *
+BaseTypeFactory::NewStr(const string &n) const
+{
+    return new Str(n);
+}
+
+Url *
+BaseTypeFactory::NewUrl(const string &n) const
+{
+    return new Url(n);
+}
+
+Array *
+BaseTypeFactory::NewArray(const string &n , BaseType *v) const
+{
+    return new Array(n, v);
+}
+
+Structure *
+BaseTypeFactory::NewStructure(const string &n) const
+{
+    return new Structure(n);
+}
+
+Sequence *
+BaseTypeFactory::NewSequence(const string &n) const
+{
+    DBG(cerr << "Inside BaseTypeFactory::NewSequence" << endl);
+    return new Sequence(n);
+}
+
+Grid *
+BaseTypeFactory::NewGrid(const string &n) const
+{
+    return new Grid(n);
+}
+
+} // namespace libdap
diff --git a/BaseTypeFactory.h b/BaseTypeFactory.h
new file mode 100644
index 0000000..7ce925f
--- /dev/null
+++ b/BaseTypeFactory.h
@@ -0,0 +1,104 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef base_type_factory_h
+#define base_type_factory_h
+
+#include <string>
+
+// Class declarations; Make sure to include the corresponding headers in the
+// implementation file.
+
+namespace libdap
+{
+
+class Byte;
+class Int16;
+class UInt16;
+class Int32;
+class UInt32;
+class Float32;
+class Float64;
+class Str;
+class Url;
+class Array;
+class Structure;
+class Sequence;
+class Grid;
+class BaseType;
+
+/** A factory to create instances of the leaf nodes of BaseType (Byte, ...
+    Grid). Clients of libdap++ which require special behavior for the types
+    should subclass this factory and provide an implementation which creates
+    instances of those specializations. Make sure to pass a reference to the
+    new factory to DDS's constructor since by default it uses this factory.
+
+    To define and use your own factory, first make sure that you are not
+    using the compile time constant 'DEFAULT_BASETYPE_FACTORY.' Then pass a
+    pointer to an instance of your factory to the DDS/DataDDS constructors.
+    When the parser is used to build a DDS from a DAP response, the factory
+    will be used to instantiate the different variable-type classes.
+
+    @note The easiest way to subclass this is to follow the pattern of using
+    a separate class declaration and implementation. It's possible to use one
+    file to hold
+    both, but that is complicated somewhat because DDS.h, which includes this
+    class, also includes many of the type classes (Array.h, ..., Grid.h) and
+    the order of their inclusion can create compilation problems where the
+    Vector and/or Constructor base classes are not defined. It's easiest to
+    split the declaration and implementation and include forward declarations
+    of the type classes in the declaration (\c .h) file and then include the
+    type class' headers in the implementation (\c .cc) file.
+
+    @author James Gallagher
+    @see DDS */
+class BaseTypeFactory
+{
+public:
+    BaseTypeFactory()
+    {}
+    virtual ~BaseTypeFactory()
+    {}
+
+    virtual Byte *NewByte(const string &n = "") const;
+    virtual Int16 *NewInt16(const string &n = "") const;
+    virtual UInt16 *NewUInt16(const string &n = "") const;
+    virtual Int32 *NewInt32(const string &n = "") const;
+    virtual UInt32 *NewUInt32(const string &n = "") const;
+    virtual Float32 *NewFloat32(const string &n = "") const;
+    virtual Float64 *NewFloat64(const string &n = "") const;
+
+    virtual Str *NewStr(const string &n = "") const;
+    virtual Url *NewUrl(const string &n = "") const;
+
+    virtual Array *NewArray(const string &n = "", BaseType *v = 0) const;
+    virtual Structure *NewStructure(const string &n = "") const;
+    virtual Sequence *NewSequence(const string &n = "") const;
+    virtual Grid *NewGrid(const string &n = "") const;
+};
+
+} // namespace libdap
+
+#endif // base_type_factory_h
diff --git a/Byte.cc b/Byte.cc
new file mode 100644
index 0000000..f654b85
--- /dev/null
+++ b/Byte.cc
@@ -0,0 +1,306 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Byte.
+//
+// jhrg 9/7/94
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    { "$Id: Byte.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "Operators.h"
+
+#include "util.h"
+#include "parser.h"
+#include "dods-limits.h"
+#include "InternalErr.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The Byte constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @brief The Byte constructor.
+    @param n A string containing the name of the variable to be
+    created.
+
+*/
+Byte::Byte(const string & n): BaseType(n, dods_byte_c)
+{}
+
+/** This Byte constructor requires the name of the variable to be created
+    and the name of the dataset from which this variable is being created.
+    This constructor is used in server-side processing, loading structure in
+    from a dataset.
+
+    @brief The Byte server-side constructor.
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which the
+    variable is being created.
+*/
+Byte::Byte(const string &n, const string &d): BaseType(n, d, dods_byte_c)
+{}
+
+Byte::Byte(const Byte & copy_from): BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *Byte::ptr_duplicate()
+{
+    return new Byte(*this);
+}
+
+Byte & Byte::operator=(const Byte & rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast < BaseType & >(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int Byte::width()
+{
+    return sizeof(dods_byte);
+}
+
+/** Serialize the contents of member _BUF (the object's internal
+    buffer, used to hold data) and write the result to stdout. If
+    FLUSH is true, write the contents of the output buffer to the
+    kernel. FLUSH is false by default. If CE_EVAL is true, evaluate
+    the current constraint expression; only send data if the CE
+    evaluates to true.
+
+    @return False if a failure to read, send or flush is detected, true
+    otherwise.
+*/
+bool Byte::serialize(ConstraintEvaluator & eval, DDS & dds,
+		     Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();          // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_byte( _buf ) ;
+
+    return true;
+}
+
+/** @brief Deserialize the char on stdin and put the result in
+    <tt>_BUF</tt>.
+*/
+bool Byte::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_byte( _buf ) ;
+
+    return false;
+}
+
+/** Store the value referenced by <i>val</i> in the object's internal
+    buffer. <i>reuse</i> has no effect because this class does not
+    dynamically allocate storage for the internal buffer.
+
+    @return The size (in bytes) of the value's representation.  */
+unsigned int Byte::val2buf(void *val, bool)
+{
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogate library,
+    // thus if the pointer val is NULL, is an Internal Error.
+    if (!val)
+        throw InternalErr("the incoming pointer does not contain any data.");
+
+    _buf = *(dods_byte *) val;
+
+    return width();
+}
+
+unsigned int Byte::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr("NULL pointer");
+
+    if (!*val)
+        *val = new dods_byte;
+
+    *(dods_byte *) * val = _buf;
+
+    return width();
+}
+
+/** Set the value of this instance.
+    @param value The value
+    @return Always returns true; the return type of bool is for compatibility
+    with the Passive* subclasses written by HAO. */
+bool Byte::set_value(dods_byte value)
+{
+    _buf = value;
+    set_read_p(true);
+
+    return true;
+}
+
+/** Get the value of this instance.
+    @return The value. */
+dods_byte Byte::value() const
+{
+    return _buf;
+}
+
+#if FILE_METHODS
+void Byte::print_val(FILE * out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %d;\n", (int) _buf);
+    }
+    else
+        fprintf(out, "%d", (int) _buf);
+}
+#endif
+
+void Byte::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << (int)_buf << ";\n" ;
+    }
+    else
+	out << (int)_buf ;
+}
+
+bool Byte::ops(BaseType * b, int op)
+{
+
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implementing read therefore it is an internal error.
+        throw InternalErr("This value not read!");
+    }
+    // Extract the second arg's value.
+    if (!b || !(b->read_p() || b->read())) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implementing read therefore it is an internal error.
+        throw InternalErr("This value not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops < dods_byte, dods_byte, Cmp < dods_byte, dods_byte > >
+               (_buf, dynamic_cast < Byte * >(b)->_buf, op);
+    case dods_int16_c:
+        return rops < dods_byte, dods_int16, USCmp < dods_byte,
+               dods_int16 > > (_buf, dynamic_cast < Int16 * >(b)->_buf, op);
+    case dods_uint16_c:
+        return rops < dods_byte, dods_uint16, Cmp < dods_byte,
+               dods_uint16 > > (_buf, dynamic_cast < UInt16 * >(b)->_buf, op);
+    case dods_int32_c:
+        return rops < dods_byte, dods_int32, USCmp < dods_byte,
+               dods_int32 > > (_buf, dynamic_cast < Int32 * >(b)->_buf, op);
+    case dods_uint32_c:
+        return rops < dods_byte, dods_uint32, Cmp < dods_byte,
+               dods_uint32 > > (_buf, dynamic_cast < UInt32 * >(b)->_buf, op);
+    case dods_float32_c:
+        return rops < dods_byte, dods_float32, Cmp < dods_byte,
+               dods_float32 > > (_buf, dynamic_cast < Float32 * >(b)->_buf,
+                                 op);
+    case dods_float64_c:
+        return rops < dods_byte, dods_float64, Cmp < dods_byte,
+               dods_float64 > > (_buf, dynamic_cast < Float64 * >(b)->_buf,
+                                 op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void Byte::dump(ostream & strm) const
+{
+    strm << DapIndent::LMarg << "Byte::dump - ("
+    << (void *) this << ")" << endl;
+    DapIndent::Indent();
+    BaseType::dump(strm);
+    strm << DapIndent::LMarg << "value: " << _buf << endl;
+    DapIndent::UnIndent();
+}
+
+} // namespace libdap
diff --git a/Byte.h b/Byte.h
new file mode 100644
index 0000000..9291674
--- /dev/null
+++ b/Byte.h
@@ -0,0 +1,119 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Byte type.
+//
+// jhrg 9/7/94
+
+#ifndef _byte_h
+#define _byte_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** This class is used to hold eight bits of information.  No sign
+    information is implied in its value.
+
+    @brief Holds a single byte.
+    @see BaseType
+    */
+class Byte: public BaseType
+{
+    /** This class allows Int16, ..., Float64 access to <tt>_buf</tt> to
+    simplify and speed up the relational operators.
+
+    NB: According to Stroustrup it does not matter where (public, private
+    or protected) friend classes are declared. */
+    friend class Int16;
+    friend class UInt16;
+    friend class Int32;
+    friend class UInt32;
+    friend class Float32;
+    friend class Float64;
+
+protected:
+    dods_byte _buf;
+
+public:
+    Byte(const string &n);
+    Byte(const string &n, const string &d);
+
+    virtual ~Byte()
+    {}
+
+    Byte(const Byte &copy_from);
+
+    Byte &operator=(const Byte &rhs);
+
+    virtual unsigned int width();
+
+    virtual BaseType *ptr_duplicate();
+
+    bool serialize(ConstraintEvaluator &eval, DDS &dds,
+		   Marshaller &m, bool ce_eval);
+    bool deserialize(UnMarshaller &um, DDS *, bool);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual bool set_value(const dods_byte value);
+    virtual dods_byte value() const;
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _byte_h
+
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..b1e3f5a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+

+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+

+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+

+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+

+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+

+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+

+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+

+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+

+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+

+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/COPYRIGHT_URI b/COPYRIGHT_URI
new file mode 100644
index 0000000..7580200
--- /dev/null
+++ b/COPYRIGHT_URI
@@ -0,0 +1,32 @@
+
+  $Id: COPYRIGHT_URI 11906 2005-08-08 19:51:43Z root $
+
+  (c) Copyright 1994-2000 by
+  The University of Rhode Island and The Massachusetts Institute of Technology
+
+  Portions of this software were developed by the Graduate School of
+  Oceanography (GSO) at the University of Rhode Island (URI) in collaboration
+  with The Massachusetts Institute of Technology (MIT).
+
+  Access and use of this software shall impose the following obligations and
+  understandings on the user. The user is granted the right, without any fee
+  or cost, to use, copy, modify, alter, enhance and distribute this software,
+  and any derivative works thereof, and its supporting documentation for any
+  purpose whatsoever, provided that this entire notice appears in all copies
+  of the software, derivative works and supporting documentation. The names
+  URI, MIT and/or GSO, may not be used in any advertising or publicity to
+  endorse or promote any products or commercial entity unless specific
+  written permission is obtained from URI/MIT. The user also understands that
+  URI/MIT is not obligated to provide the user with any support, consulting,
+  training or assistance of any kind with regard to the use, operation and
+  performance of this software nor to provide the user with any updates,
+  revisions, new versions or "bug fixes".
+
+  THIS SOFTWARE IS PROVIDED BY URI/MIT "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 URI/MIT BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
+  DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+  PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTUOUS
+  ACTION, ARISING OUT OF OR IN CONNECTION WITH THE ACCESS, USE OR PERFORMANCE
+  OF THIS SOFTWARE.
diff --git a/COPYRIGHT_W3C b/COPYRIGHT_W3C
new file mode 100644
index 0000000..1975516
--- /dev/null
+++ b/COPYRIGHT_W3C
@@ -0,0 +1,50 @@
+
+                     W3C� SOFTWARE NOTICE AND LICENSE
+
+Copyright � 1994-2002 World Wide Web Consortium, (Massachusetts Institute of
+Technology, Institut National de Recherche en Informatique et en Automatique,
+Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/
+
+This W3C work (including software, documents, or other related items) is
+being provided by the copyright holders under the following license. By
+obtaining, using and/or copying this work, you (the licensee) agree that you
+have read, understood, and will comply with the following terms and
+conditions:
+
+Permission to use, copy, modify, and distribute this software and its
+documentation, with or without modification, for any purpose and without fee
+or royalty is hereby granted, provided that you include the following on ALL
+copies of the software and documentation or portions thereof, including
+modifications, that you make:
+
+   1. The full text of this NOTICE in a location viewable to users of the
+      redistributed or derivative work.
+
+   2. Any pre-existing intellectual property disclaimers, notices, or terms
+      and conditions. If none exist, a short notice of the following form
+      (hypertext is preferred, text is permitted) should be used within the
+      body of any redistributed or derivative code: "Copyright �
+      [$date-of-software] World Wide Web Consortium, (Massachusetts Institute
+      of Technology, Institut National de Recherche en Informatique et en
+      Automatique, Keio University). All Rights Reserved.
+      http://www.w3.org/Consortium/Legal/"
+
+   3. Notice of any changes or modifications to the W3C files, including the
+      date changes were made. (We recommend you provide URIs to the location
+      from which the code is derived.)
+
+THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS
+MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR
+PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE
+ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.
+
+COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR
+DOCUMENTATION.
+
+The name and trademarks of copyright holders may NOT be used in advertising
+or publicity pertaining to the software without specific, written prior
+permission. Title to copyright in this software and any associated
+documentation will at all times remain with copyright holders.
+
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..ad0457b
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,8453 @@
+2011-04-25  James Gallagher <jgallagher at opendap.org>
+
+	Removed doc rpm - this breaks when the build hosts lacks dot or
+	dot does not make inamges.
+
+	M    libdap.spec
+
+2011-04-20  James Gallagher <jgallagher at opendap.org>
+
+	Hyrax 1.7 releaseHyrax 1.7 release
+
+	A    http://scm.opendap.org/svn/branch/libdap/3.11.1
+
+2011-04-08  James Gallagher <jgallagher at opendap.org>
+
+	Build fixes for h 1.7 osx meta package
+
+	M    Makefile.am
+
+2011-03-28  James Gallagher <jgallagher at opendap.org>
+
+	Loop/Race-condition in HTTPCacheTable.h fixed
+
+2011-03-28  James Gallagher <jgallagher at opendap.org>
+
+	1.7RC1
+
+2011-03-17  Nathan Potter <ndp at coas.oregonstate.edu>
+
+	libdap: Automated change of version number for OSX package builds.
+
+2011-03-08  James Gallagher <jgallagher at opendap.org>
+
+	Merge for hyrax 1.7 from the hyrax_1.6.2_release branch of shrew
+	to the trunk
+
+	_M   .
+	M    RValue.cc
+	M    DODSFilter.cc
+	M    OSX_Resources/InstallationCheck
+	M    OSX_Resources/update_mac_package_contents.pl
+	R  + OSX_Resources/Info.plist
+	A  + OSX_Resources/Info.plist.proto
+	M    DDS.cc
+	M    Array.cc
+	_M   tests/old_tests/grid-func-testsuite
+	_M   tests/old_tests/server-testsuite
+	M    DDXParserSAX2.cc
+	M    AlarmHandler.h
+	M    libdap.spec
+	M    BaseType.cc
+	M    Makefile.am
+	_M   mime_util.h
+	M    Vector.cc
+	M    ce_functions.cc
+	MM   mime_util.cc
+	M    GridGeoConstraint.cc
+	M    Constructor.cc
+	M    DAS.cc
+	M    Grid.cc
+	M    escaping.cc
+	_M   unit-tests/MIMEUtilTest.cc
+	_M   unit-tests/fdiostreamTest.cc
+	_M   fdiostream.h
+	M    Clause.cc
+
+2011-03-03  Patrick West <pwest at ucar.edu>
+
+	These files are generated
+	D    gl/alloca.h
+	D    gl/arg-nonnull.h
+	D    gl/langinfo.h
+	D    gl/stdint.h
+	D    gl/c++defs.h
+	D    gl/wctype.h
+	D    gl/warn-on-use.h
+	D    gl/wchar.h
+	D    gl/unistd.h
+
+2011-03-03  James Gallagher <jgallagher at opendap.org>
+
+	All tests back in.
+
+	M    unit-tests/HTTPConnectTest.cc
+
+2011-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Fixed HTTPCache hack that provides access to the cached response
+	body. Also fixed an error in Keywords that broke a gazillion
+	tests.
+
+2011-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Eh - ctor fix for Keywords
+
+2011-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Keywords2 was modified so it'll build on older (4.1) gcc
+	compilers (with an older stl implementation).
+
+2011-03-02  James Gallagher <jgallagher at opendap.org>
+
+	Modified HTTPConnect to store the filename of the cached body when
+	returning cached responses. Use the HTTPResponse::get_file()
+	method to use this. Once the HTTPResponse is deleted, the name is
+	no loner valid.
+
+2011-03-01  James Gallagher <jgallagher at opendap.org>
+
+	Added Keywords to DDS and modified the behavior of set_dap_version
+	so that '2' parses as '2.0' (really 'x' --> 'x.0').
+
+2011-03-01  Patrick West <pwest at ucar.edu>
+
+	Created from .in file.
+	D    gl/stdlib.h
+
+2011-02-28  Patrick West <pwest at ucar.edu>
+
+	added include of cstring for strlen and strncpy
+	M    ResponseBuilder.cc
+
+2011-02-25  James Gallagher <jgallagher at opendap.org>
+
+	Removed old Keywords impl.
+
+2011-02-25  James Gallagher <jgallagher at opendap.org>
+
+	Keywords2 now tests for legal values.
+
+2011-02-25  James Gallagher <jgallagher at opendap.org>
+
+	Keywords2 works - this syntax looks like functions but is to be parsed before the CE is formally processed.
+
+2011-02-25  James Gallagher <jgallagher at opendap.org>
+
+	Keywrods2Test.cc...
+
+2011-02-25  James Gallagher <jgallagher at opendap.org>
+
+	Keywords2...
+
+2011-02-24  James Gallagher <jgallagher at opendap.org>
+
+	new Keywords implementations started.
+
+2011-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Next version of Keywords - This implements the version where keywords are bound to a pair made up of a kind and a value. Probably won't use this because of potential problems with ambiguity - it's not possible to guarantee that 'dap3.2' won't be an identifier in a data set.
+
+2011-02-24  James Gallagher <jgallagher at opendap.org>
+
+	g++ 4.? warnings about char* conversion in HTTPConnectTest
+
+2011-02-24  James Gallagher <jgallagher at opendap.org>
+
+	New Keywords class first version working/tested
+
+2011-02-23  James Gallagher <jgallagher at opendap.org>
+
+	Factored keywords out of ResponseBuilder and into their own class (Keywords).
+
+2011-02-15  Patrick West <pwest at ucar.edu>
+
+	This file is automatically generated
+	D    gl/configmake.h
+
+2011-02-08  James Gallagher <jgallagher at opendap.org>
+
+	Initial cut at support for Version information in the CE.
+
+2011-02-08  James Gallagher <jgallagher at opendap.org>
+
+	I modified the documentation for mime_util and ResponseBuilder so that they describe a truer version of the world - most of the MIME header code is no longer used by libdap or the BES/handlers (instead the headers are added by the OLFS). Some of the mime_util code is used by the client side, however, and a tiny bit is used by the parts of ResponseBuilder I added so that the BES can use ResponseBuilder in those cases where there is no OLFS.
+
+2011-02-08  James Gallagher <jgallagher at opendap.org>
+
+	Reverted to pre-DAP4 hack versions of these... The new features are
+	implemented in ResponseBuilder.
+
+	M    DODSFilter.cc
+	M    DODSFilter.h
+
+2011-02-07  James Gallagher <jgallagher at opendap.org>
+
+	ResponseBuilder now assumes that the default protocol for a response is the DAP_PROTOCOL_VERSION read from config.h. This can be overridden using a parameter to the various set_mime_*() methods it defines (which are different from those in mime_util.cc). NB: These are not used by Hyrax, but the BES might use these sometimes and I've got mods pending in the BES to use this code.
+
+2011-02-07  James Gallagher <jgallagher at opendap.org>
+
+	Comments about ResponseBuilder
+
+2011-02-07  James Gallagher <jgallagher at opendap.org>
+
+	Comments about ResponseBuilder
+
+2011-02-07  James Gallagher <jgallagher at opendap.org>
+
+	Comments about ResponseBuilder
+
+2011-02-07  James Gallagher <jgallagher at opendap.org>
+
+	Added comment about ResponseBuilder
+
+2011-02-07  James Gallagher <jgallagher at opendap.org>
+
+	Added comment about ResponseBuilder
+
+2011-02-03  James Gallagher <jgallagher at opendap.org>
+
+	These are templates needed by the code in 'gl.' I think ...
+
+	A    conf/c++defs.h
+	A    conf/warn-on-use.h
+	A    conf/arg-nonnull.h
+
+2011-02-02  James Gallagher <jgallagher at opendap.org>
+
+	Removed these files as a result of the massive commit
+
+	D    gl/m4/wchar.m4
+	D    gl/m4/ulonglong.m4
+	D    gl/m4/absolute-header.m4
+	D    gl/m4/wctype.m4
+	D    gl/alloca_.h
+	D    gl/wchar_.h
+	D    gl/stdint_.h
+	D    gl/stdbool_.h
+	D    gl/unistd_.h
+	D    gl/wctype_.h
+	D    gl/stdlib_.h
+	D    gl/alloca.c
+
+2011-02-02  James Gallagher <jgallagher at opendap.org>
+
+	Added as part of the massive update.
+
+	A    gl/m4/fcntl-o.m4
+	A    gl/m4/configmake.m4
+	A    gl/m4/btowc.m4
+	A    gl/m4/00gnulib.m4
+	A    gl/m4/locale-fr.m4
+	A    gl/m4/langinfo_h.m4
+	A    gl/m4/mbsinit.m4
+	A    gl/m4/warn-on-use.m4
+	A    gl/m4/wchar_h.m4
+	A    gl/m4/wcrtomb.m4
+	A    gl/m4/locale-zh.m4
+	A    gl/m4/stddef_h.m4
+	A    gl/m4/mbstate_t.m4
+	A    gl/m4/wctype_h.m4
+	A    gl/m4/nl_langinfo.m4
+	A    gl/m4/locale-ja.m4
+	A    gl/m4/wchar_t.m4
+	A    gl/m4/multiarch.m4
+	A    gl/alloca.h
+	A    gl/arg-nonnull.h
+	A    gl/langinfo.h
+	A    gl/mbsinit.c
+	A    gl/stdint.h
+	A    gl/wcrtomb.c
+	A    gl/btowc.c
+	A    gl/c++defs.h
+	A    gl/warn-on-use.h
+	A    gl/wctype.h
+	A    gl/streq.h
+	A    gl/alloca.in.h
+	A    gl/langinfo.in.h
+	A    gl/configmake.h
+	A    gl/verify.h
+	A    gl/wchar.h
+	A    gl/iswblank.c
+	A    gl/mbrtowc.c
+	A    gl/wchar.in.h
+	A    gl/stdint.in.h
+	A    gl/stdbool.in.h
+	A    gl/unistd.in.h
+	A    gl/stddef.in.h
+	A    gl/wctype.in.h
+	A    gl/nl_langinfo.c
+	A    gl/stdlib.in.h
+
+2011-02-02  James Gallagher <jgallagher at opendap.org>
+
+	Massive (and massively overdue) updates - this may be the fix for ticket #1702
+	But regardless, it's certainly needed.
+
+	M    gl/m4/wint_t.m4
+	M    gl/m4/localcharset.m4
+	M    gl/m4/stdint.m4
+	M    gl/m4/stdbool.m4
+	M    gl/m4/gnulib-common.m4
+	M    gl/m4/malloc.m4
+	M    gl/m4/regex.m4
+	M    gl/m4/gnulib-comp.m4
+	M    gl/m4/mbrtowc.m4
+	M    gl/m4/unistd_h.m4
+	M    gl/m4/longlong.m4
+	M    gl/m4/ssize_t.m4
+	M    gl/m4/include_next.m4
+	M    gl/m4/gnulib-cache.m4
+	M    gl/m4/glibc21.m4
+	M    gl/m4/codeset.m4
+	M    gl/m4/stdlib_h.m4
+	M    gl/m4/gnulib-tool.m4
+	M    gl/m4/alloca.m4
+	M    gl/m4/extensions.m4
+	M    gl/localcharset.c
+	M    gl/regex_internal.c
+	M    gl/malloc.c
+	M    gl/localcharset.h
+	M    gl/regex_internal.h
+	M    gl/regexec.c
+	M    gl/ref-del.sin
+	M    gl/stdlib.h
+	M    gl/regcomp.c
+	M    gl/ref-add.sin
+	M    gl/regex.c
+	M    gl/unistd.h
+	M    gl/config.charset
+	M    gl/regex.h
+	M    gl/Makefile.am
+	M    gl/gettext.h
+
+2011-02-02  James Gallagher <jgallagher at opendap.org>
+
+	Corrected
+
+2011-01-31  James Gallagher <jgallagher at opendap.org>
+
+	Expanded DDS so that it's easier to get the protocol version string; moved the relevant MIME header code into ResponseBuilder on the assumption that someone might be using this still (like CEDAR). Updated the unit tests.
+
+2011-01-29  James Gallagher <jgallagher at opendap.org>
+
+	Leaner version of ResponseBuilder - the new replacement for DODSFilter.
+
+2011-01-28  James Gallagher <jgallagher at opendap.org>
+
+	Commented out test code that got in SVN by mistake (in expr-test.cc)
+
+2011-01-28  James Gallagher <jgallagher at opendap.org>
+
+	Changes/Additions for Version via Projection Functions and/or Keywords.
+
+2010-10-28  mjohnson
+
+	Merge from Hyrax 1.6.2 Shrew Release Branch.
+
+	Not clear what the property modifications are, the ones I checked seem the same.  I'm just letting them go since they seem harmless.
+
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a bug in the www2id() function of escaping.cc that was causing symbols that start with a percent sign to be mangled. It's not clear why the server was/is using this, but this fixes the function and we'll have to sort out whether using the function is correct later. It may be that the BES is routing the DAS through an unnecessary cycle of print/parse/print operations.
+
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Added tests for www2id() and the case where an attribute starts with a percent sign.
+
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Spelling errors in GeoConstraint.cc
+
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an error in calling long_to_string with doubles in exception handling code - found during testing.
+
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Updated for fixes to a problem foud in initial testing of the server for the 1.6.2 release.
+
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Added a second version of eval_function_clauses() that takes and returns a DataDDS instead of a DDS. This enables easier use of the method in handlers that are using subclasses of the types and building responses from DataDDS objects passed around in the BES. I also updated some of the library version information in configure.ac to match more closely the addition to ConstraintEvaluator's interface.
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2010-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Added a second version of eval_function_clauses() that takes and
+	returns a DataDDS instead of a DDS. This enables easier use of the
+	method in handlers that are using subclasses of the types and
+	building responses from DataDDS objects passed around in the BES.
+	I also updated some of the library version information in
+	configure.ac to match more closely the addition to
+	ConstraintEvaluator's interface.
+
+2010-09-13  James Gallagher <jgallagher at opendap.org>
+
+	Changes for 3.11.0 release
+
+	M    configure.ac
+	M    ChangeLog
+	M    INSTALL
+	M    libdap.spec
+	M    README
+	M    NEWS
+	M    ce_functions.cc
+
+2010-09-07  James Gallagher <jgallagher at opendap.org>
+
+	Added to doc comments
+
+2010-09-03  James Gallagher <jgallagher at opendap.org>
+
+	Updated the version number for geogrid.
+
+2010-09-02  James Gallagher <jgallagher at opendap.org>
+
+	Constraint expressions can now include multiple function calls.
+	Two tests included. Some fixes were added to expr-test.cc which
+	was looking a little long in the tooth... 
+
+2010-09-01  James Gallagher <jgallagher at opendap.org>
+
+	Added new functions to ConstraintEvaluator. Untested.
+
+2010-09-01  mjohnson
+
+	o Fix for memory bug in ticket #1637.
+
+2010-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Grid now prints the XML declaration correctly when a constrained
+	Grid variable's type decays to a Structure. The expr-test program
+	now has an XML option (-x) for use with constrained DDS/DDX
+	output.
+
+2010-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the Grid projection bug - should clean up the code a bit.
+	The error was in projection yields grid which was not correctly
+	testing that each Grid dimension had a matching Map vector that
+	was in the current projection.
+
+2010-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Added regression tests for the new version of geogrid().
+	Removed some old stuff from the dejagnu days.
+
+2010-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Added more tests (unit tests) for GridGeoConstraint for the Grid,
+	Array, Array, ..., version of the constructor.
+
+2010-08-27  James Gallagher <jgallagher at opendap.org>
+
+	geogrid() now takes both (grid, <box points>) and (grid, lat
+	array, lon array <box points>). This includes some minimal testing
+	of the new code.
+
+2010-08-26  James Gallagher <jgallagher at opendap.org>
+
+	Changes to the geogrid function so that it can take lat/lon maps
+	as explicit arguments.
+
+2010-07-16  James Gallagher <jgallagher at opendap.org>
+
+	I removed the AIS functions in libdap 3.8 but failed to correctly
+	set the Age of the library in libdap 3.10. Fixed.
+
+2010-06-17  mjohnson
+
+	Removed debug AM_CXXFLAGS entries.
+
+2010-05-24  James Gallagher <jgallagher at opendap.org>
+
+	Updated tests given that the nph-dods alias is no longer supported by
+	test.opendap.org
+
+	M    unit-tests/HTTPCacheTest.cc
+	M    unit-tests/generalUtilTest.cc
+
+2010-05-19  Patrick West <pwest at ucar.edu>
+
+	Seems to fix bug #1563. When adding an attribute table to the DAS when a
+	container is currently set, set that new attribute table to not be
+	global using set_is_global_attribute(false)
+	
+	M    DAS.cc
+
+2010-05-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed etag for 304 response test - the etag changed when the server was
+	updated.
+
+	M    unit-tests/HTTPConnectTest.cc
+
+2010-05-11  James Gallagher <jgallagher at opendap.org>
+
+	Merge from the shrew-1.6 branch (which was tagged 3.10.2)
+
+	_M   .
+	M    SignalHandler.cc
+	M    configure.ac
+	M    ChangeLog
+	M    conf/libdap.m4
+	M    DDS.cc
+	M    BaseType.h
+	_M   tests/old_tests/grid-func-testsuite
+	_M   tests/old_tests/server-testsuite
+	M    tests/das-test.cc
+	M    tests/package.m4
+	M    tests/DASTest.at
+	M    tests/DDSTest.at
+	M    tests/expr-test.cc
+	M    tests/EXPRTest.at
+	M    tests/Makefile.am
+	M    tests/dds-test.cc
+	M    INSTALL
+	M    DDXParserSAX2.cc
+	M    libdap.spec
+	M    README
+	M    DDS.h
+	M    BaseType.cc
+	M    Makefile.am
+	M    Constructor.h
+	M    RCReader.cc
+	M    parser-util.cc
+	M    AttrTable.cc
+	_M   mime_util.h
+	M    Grid.h
+	M    NEWS
+	M    ce_functions.cc
+	M    AttrTable.h
+	_M   mime_util.cc
+	M    Constructor.cc
+	M    Grid.cc
+	M    Connect.cc
+	M    escaping.cc
+	M    unit-tests/DODSFilterTest.cc
+	M    unit-tests/DDSTest.cc
+	_M   unit-tests/MIMEUtilTest.cc
+	MM   unit-tests/fdiostreamTest.cc
+	M    unit-tests/generalUtilTest.cc
+	M    unit-tests/dds-testsuite/test.19b.das
+	M    unit-tests/dds-testsuite/test.19e.das
+	M    unit-tests/dds-testsuite/test.19g.das
+	A  + unit-tests/dds-testsuite/coads_climatology.nc.dds
+	A  + unit-tests/dds-testsuite/coads_climatology.nc.das
+	M    unit-tests/Makefile.am
+	M    unit-tests/RCReaderTest.cc
+	M    unit-tests/MarshallerTest.cc
+	_M   fdiostream.h
+
+2010-05-11  James Gallagher <jgallagher at opendap.org>
+
+	ci prior to merge
+
+	M    tests/DASTest.at
+	M    tests/DDSTest.at
+	M    tests/EXPRTest.at
+
+2010-04-30  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an error in AttrTable::is_global_attribute() where the function did not
+	always return a value.
+
+	M    AttrTable.cc
+
+2010-04-30  James Gallagher <jgallagher at opendap.org>
+
+	Commented the fdiostreamTest stuff - automake was complaining. Removed a
+	bunch of AIS-related things that are no longer needed.
+
+2010-04-30  mjohnson
+
+	AttrTable.cc, AttrTable.h: Changes for #1544. clone() wasn't
+	preserving parent/child ptrs properly leading to dangling
+	pointers.
+
+2010-04-26  Patrick West <pwest at ucar.edu>
+
+	Fixed version check when a (alpha) or b (beta) at the end of the version
+
+	M    conf/libdap.m4
+
+2010-04-22  James Gallagher <jgallagher at opendap.org>
+
+	Modified the transfer_attributes code so that it checks the
+	is_global property for individual attributes and
+	containers (before it was just containers). This entailed a change
+	to AttrTable in both the way it tracks and sets that property.
+	Fixed the unit tests. Several tests became invalid because they
+	tested handler-specific features that are now dealt with in the
+	handlers themselves.
+
+2010-04-22  mjohnson
+
+	Added version update to INSTALL as well for #1540
+
+2010-04-22  Patrick West <pwest at ucar.edu>
+
+	Requires libxml2 2.6.16
+	M    libdap.spec
+
+2010-04-21  James Gallagher <jgallagher at opendap.org>
+
+	Initial check in of the new methods to handle the transfer (copy)
+	of attributes from the DAS to the DDS object. The new approach
+	includes a new set of methods that are defined in BaseType and
+	Constructor that are designed to be subclassed by handlers that
+	build odd DAS objects. The default methods handle merging a DAS
+	the follows the DAP 2.0 and later specs. The method in DDS calls
+	these 'type-based' methods. The old approach is commented out
+	using #if 0 ... #endif.
+
+2010-04-21  mjohnson
+
+	Added #include <cstdarg> for va_start and va_end Some systems
+	don't find it by default.
+
+2010-04-16  mjohnson
+
+	Fixed invalid memory and broken invariant problem with using
+	deleted copy in Grid::add_var(). Ticket #1530 revealed this.
+
+2010-04-15  James Gallagher <jgallagher at opendap.org>
+
+	Added dist-hook target to remove the .svn subdirs that were being included in
+	the dist files.
+
+	M    libdap/Makefile.am
+	M    bes/Makefile.am
+
+2010-04-15  James Gallagher <jgallagher at opendap.org>
+
+	Added Requires: lines to the .spec files for libdap and bes.
+
+2010-03-23  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for distcheck build on 64-bit linux (FC 11)
+
+	M    SignalHandler.cc
+	M    RCReader.cc
+	M    parser-util.cc
+	M    unit-tests/MarshallerTest.cc
+
+2010-03-23  James Gallagher <jgallagher at opendap.org>
+
+	Fixes from the 64-bit linux build. Includes fix for the DAS value issue where
+	values larger than 32-bits were being allowed in int32 attributes.
+
+	M    tests/das-test.cc
+	M    tests/dds-test.cc
+	M    libdap.spec
+	M    Makefile.am
+	M    parser-util.cc
+	M    unit-tests/RCReaderTest.cc
+
+2010-03-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed fdiostream from libdap and from the tests. Changed
+	generalUtilTest to match the new version of id2xml()
+
+2010-03-19  James Gallagher <jgallagher at opendap.org>
+
+	More changes for ticket 1521. Modified the id2xml() function so
+	that it no longer encodes the stuff in an octal escape sequence.
+	However, the value of the <value> element in the DDX _is_ encoded
+	so that things like '<' will be escaped for the XML parser. Also,
+	bumped the version in configure.ac to 3.10.1b. One unit test fails
+	- this is a stop-gap fix so we can come back to that test and this
+	fix later.
+
+2010-03-19  James Gallagher <jgallagher at opendap.org>
+
+	Modified Connect.cc so that the FILE_METHODS are used, which
+	effectively removed the fdiostream.h header from the compilation.
+	Also, the DAP version has been bumped to 3.3 - a fix since libdap
+	included in the hyrax 1.6 beta release said 3.2 by mistake.
+
+2010-03-19  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for ticket 1512. The function id2xml() was being used to
+	encode String (DAP) Attribute values and this was causing problems
+	when those values were not valid UTF-8 characters (e.g., when they
+	were less than 0x20). As a fix we dropped the encoding altogether
+	and fell back to the same encoding used by the DAS for the
+	values (that encoding represents all non ASCII values using octal
+	escape codes). I also fixed one of the unit tests that was
+	explicitly testing for the XDAP header to be 3.2 and made it
+	accept any value.
+
+2010-02-10  Patrick West <pwest at ucar.edu>
+
+	fdiostreamtest.txt file added to EXTRA_DIST
+	M    unit-tests/Makefile.am
+
+2010-02-07  Patrick West <pwest at ucar.edu>
+
+	EXPRTest.at wasn't included in EXTRA_DIST
+	M    tests/Makefile.am
+
+2010-02-05  Patrick West <pwest at ucar.edu>
+
+	Added DISTCLEANFILES to both of these to clean up unit-tests and tests
+	files left around.
+	M    tests/Makefile.am
+	M    unit-tests/Makefile.am
+
+2010-02-05  Patrick West <pwest at ucar.edu>
+
+	Including test_config.h, which has the local definition of abs_srcdir
+	and can be used to find files to load.
+	M    fdiostreamTest.cc
+
+2010-02-05  Patrick West <pwest at ucar.edu>
+
+	Using abs_srcdir instead of just srcdir. This fixes this part of the
+	distcheck problem.
+	M    tests/DASTest.at
+	M    tests/DDSTest.at
+	M    tests/EXPRTest.at
+
+2010-02-05  Patrick West <pwest at ucar.edu>
+
+	README.AIS has been removed
+	M    libdap.spec
+
+2010-02-03  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for autotest that I forgot to check in to the branch.
+	$srcdir/<tool> --> $abs_builddir/<tool>
+
+2010-02-01  James Gallagher <jgallagher at opendap.org>
+
+	Branch for Hyrax 1.6
+
+	A    http://scm.opendap.org/svn/branch/libdap/3.10.0
+
+2010-02-01  James Gallagher <jgallagher at opendap.org>
+
+	Changes for version 3.10.0
+
+	M    configure.ac
+	M    ChangeLog
+	M    INSTALL
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+2010-02-01  James Gallagher <jgallagher at opendap.org>
+
+	Modified the way errors in attribute values are tested for. Now we
+	test errno first, then for values of 0.0 with ptr values non-null.
+	This matches the man page more closely then the old tests.
+
+2010-01-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed potential read beyond bounds in
+	XDRStreamUnMarshaller::get_vector.
+
+2010-01-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed return type in
+	Vector::set_value_slice_from_row_major_vector (changed to unsigned
+	int).
+
+2010-01-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a comment
+
+2010-01-08  Patrick West <pwest at ucar.edu>
+
+	--clean to clean build and src files for rpmbuild
+	M    Makefile.am
+
+2010-01-07  James Gallagher <jgallagher at opendap.org>
+
+	Changed the documentation for server-side functions so that the
+	bulk of the documentation is now on the web.
+
+2010-01-07  James Gallagher <jgallagher at opendap.org>
+
+	Fixes to geogrid() so that the longitude wrapping feature works
+	and so that if latitude is upside down in the data, it's returned
+	as 'north up' data.
+
+2009-12-29  James Gallagher <jgallagher at opendap.org>
+
+	Shrew build changes that will hopefully lead to a version that we
+	can build using NMI's B&T system. Also, I added 'cccc' targets so
+	that we can take a 'metrics snapshot' without undue pain.
+
+2009-12-23  rduncan
+
+	changes for win32 build
+
+2009-12-03  James Gallagher <jgallagher at opendap.org>
+
+	Added chmod of InstallationCheck script which seems to be needed
+	when buidling on osx 10.5.8.
+
+	M    update_mac_package_contents.pl
+
+2009-12-01  mjohnson
+
+	o Needed to add explicit #include <cstring> in order to find
+	memcpy for Red Hat Enterprise 5 using gcc-4.3.2. Seems they
+	cleaned up headers and you need to be explicit about the include
+	now.
+
+2009-11-30  mjohnson
+
+	Fix for link bug on some platforms: initializing variables in a
+	switch without declaring a local scope block is an error.
+
+2009-11-30  mjohnson
+
+	Fix for link bug on some platforms: initializing variables in a
+	switch without declaring a local scope block is an error.
+
+2009-11-24  mjohnson
+
+	DDS.cc: fixed minor memory leak
+
+	Array.cc, Array.h: added prepend_dim function for adding outer
+	dimensions.
+
+	Grid.h, Grid.cc: added function to set the array part explicitly
+	without copying it. fixed potential memory leaks. added a few
+	extra checks on proper types being set. added function to add maps
+	to (to beginning or end of map vector to support new outer
+	dimensions). made _duplicate protected for subclasses to be able
+	to call it.
+
+2009-11-19  James Gallagher <jgallagher at opendap.org>
+
+	ticket 1399 - Grids that have only one member after projection
+	still must be wrapped in a Structure (because there might be two
+	Grids so projected and they might have members with the same names
+	- this is a real case). The Structures provide for unique FQN as
+	the DAP requires.
+
+2009-11-10  James Gallagher <jgallagher at opendap.org>
+
+	Removed libdapserver from the getdap link.
+
+2009-11-05  James Gallagher <jgallagher at opendap.org>
+
+	I changed how the FILE_METHODS compile-time switch was defined,
+	Now it's defined in the headers and not, directly in the config.h
+	or *.cc files. That was a bug. All tests pass now. I'm going to
+	check this in and then run tests on the entire shrew project.
+
+2009-11-04  James Gallagher <jgallagher at opendap.org>
+
+	Removed lots of accumulated 'old code' and reinstated the
+	FILE_METHODS compilation flag.
+
+2009-11-04  James Gallagher <jgallagher at opendap.org>
+
+	Likely fixes for the win32 build. Test these on a vm.
+
+2009-11-04  James Gallagher <jgallagher at opendap.org>
+
+	tweaks to get the ddx and dataddx responses working with the trunk
+	BES. See getdap's -x (ddx) and -X (DataDDX) responses. These work
+	using the -p x.y switch to set the DAP Accept version to x.y. Also
+	added the -t option to turn on HTTP protocol tracing. The new
+	parser DDXParserSXA2 reads the dapVersion XML attribute and sets
+	the value in the DDS instance. I also modified the Connect class
+	to recognize the dods_ddx and dods-ddx values for
+	Content-Description.
+
+2009-10-22  mjohnson
+
+	Ticket #1442:
+
+	o Fixed several potential memory leaks.
+
+	o set_value now sets length.
+
+	o Refactored cut & pasted sections to use helper funcs.
+
+2009-10-07  mjohnson
+
+	Made simple_find() and simple_find_container() public for callers
+	that require non-recursing lookups.
+
+2009-10-06  James Gallagher <jgallagher at opendap.org>
+
+	I fixed problems with two sets of tests. First, the "Array of
+	structures with child arrays" test was failing because the
+	TestCommon and TestArray classes were not generating valid output
+	in the case where intern_data() was used. Second, the test for
+	String regexes where nothing matched was botched because when a
+	selection is applied to anything other than a Sequence and nothing
+	is selected the response from the server is broken. This will be
+	an issue for DAP4. In place of the test that used a Structure and
+	selected nothing, I added two tests of Sequences with strings and
+	tried both selections that return and don't return values. Both
+	cases work.
+
+2009-10-05  mjohnson
+
+	Vector.h, Vector.cc: Cleaned up and moved doxygen comments to impl
+	file.
+
+2009-10-02  Patrick West <pwest at ucar.edu>
+
+	This function is no longer used in libdap and is specific to usage in
+	dap-server. Moved the function.
+	M    mime_util.h
+
+2009-10-02  James Gallagher <jgallagher at opendap.org>
+
+	Regarding the previous commit: On the IOOS branch I removed a 'bad
+	fix' added at some point where includes within util.h supplied the
+	class definitions for Byte, ..., Grid. So it looked like the .cc
+	files were not including must at all, but in fact not only were
+	they (and they need those includes) but _everything_ that used
+	util.cc/h was too. So here are the includes, back in the .cc files
+	where they belong.
+
+2009-10-02  James Gallagher <jgallagher at opendap.org>
+
+	Merged code from ioos/src/libdap rev 20393 that contained the
+	'OtherXML' attribute implementation. This was apparently lost when
+	that branch was updated between the commit of that revision and
+	now. In addition to changes in AttrTable and the DAS and DDX
+	parsers, there are changes in tests/ and unit-tests/. There's also
+	a new function for converting octal escapes codes that is in
+	escaping.cc/h. I updated the DDX parser to use the SAX2 interface
+	and it now correctly processes namespaces and as a result, it's in
+	a new file 'DDXParserSAX2.cc/h'. Oddly, when I performed the
+	merge, an old 'feature' of the Type (Byte, ...) classes reemerged,
+	the 'include the world' feature. In testing I could not get a good
+	compile without these includes after the merge (but before the
+	merge it was fine). I'm going to leave those changes out of this
+	commit and see if the resulting code is OK. If not, I'l commit
+	those changes, too.
+
+2009-10-02  mjohnson
+
+	Vector.cc, Vector.h: Added support for reserving data buffer
+	storage in advance, clearing out data buffers, and for copying a
+	Vector into a subset of the value buffer of another Vector. In
+	support of aggregation to allow Vector's to be combined into a
+	larger Vector. Ticket #1427 has more information. This was a
+	monotonic interface addition and code change only --- no
+	interfaces removed or changed.
+
+2009-09-25  James Gallagher <jgallagher at opendap.org>
+
+	Removed XDRFileMarshaller.h from DODSFilter.cc
+
+2009-09-25  James Gallagher <jgallagher at opendap.org>
+
+	It just seem right to save things at this point. Most of the
+	configure.ac files have been updated. The libdap software has had
+	a number of the FILE* methods/functions commented out using #if
+	FILE_METHODS and then #undef FILE_METHODS. We'll see how much of
+	the redundant code can be removed before the next Hyrax 1.6
+	release.
+
+2009-09-25  James Gallagher <jgallagher at opendap.org>
+
+	Added fdiostream to the library because it seems we might be using
+	it someday soon. Modified expr-test to use temp. files and the
+	methods in DODSFilter and Connect - this is a better test of the
+	library. I modified XDRStreamUnMarshaller a fair amount but it's
+	still not work 100% and needs more error checking. This code still
+	uses XDRFileUnMarshaller.
+
+	M    DODSFilter.cc
+	A    fdiostream.cc
+	M    tests/expr-test.cc
+	M    tests/TestByte.cc
+	M    tests/Makefile.am
+	M    Marshaller.h
+	D    GNU/fdiostream_test.cc
+	D    GNU/fdiostream.h
+	M    Makefile.am
+	M    DODSFilter.h
+	M    XDRStreamUnMarshaller.cc
+	M    HTTPConnect.cc
+	M    XDRStreamMarshaller.cc
+	M    Connect.cc
+	A  + unit-tests/fdiostreamTest.cc
+	M    unit-tests/Makefile.am
+	M    unit-tests/MarshallerTest.cc
+	AM + fdiostream.h
+
+2009-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Removed the xstream code - if we need this it's available on the web.
+
+2009-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a bug in fdiostream and added support for a istream that
+	reads from a FILE* (ugh).
+
+2009-09-18  James Gallagher <jgallagher at opendap.org>
+
+	Uses the new file descriptor stream classes - that is, it tests
+	both input and output.
+
+2009-09-18  James Gallagher <jgallagher at opendap.org>
+
+	Added XDRStreamUnMarshaller to the Makefile.am
+
+2009-09-18  James Gallagher <jgallagher at opendap.org>
+
+	Added XDRStreamUnMarshaller
+
+2009-09-18  James Gallagher <jgallagher at opendap.org>
+
+	Minor fixes to the XDRStreamMarshaller class
+
+2009-09-17  James Gallagher <jgallagher at opendap.org>
+
+	Now includes the newly revamped stream buffer classes (fdiostream.h)
+
+2009-09-17  James Gallagher <jgallagher at opendap.org>
+
+	Added input stream buf for file descriptors and renamed the files.
+	Updated the README.
+
+2009-09-11  mjohnson
+
+	Grid.cc: Made Grid add it's array and map vectors to the
+	Constructor _vars list so they get iterated by the superclass
+	Vars_Iter calls. For ticket #1406
+
+2009-09-02  Nathan Potter <ndp at coas.oregonstate.edu>
+
+2009-09-02  Nathan Potter <ndp at coas.oregonstate.edu>
+
+	libdap: tweaked configure.ac to fix uuid lib problem
+
+2009-09-02  James Gallagher <jgallagher at opendap.org>
+
+	Updated the pkg-config and dap-config scripts so they contain the UUID
+	library when needed.
+
+	M    libdap.pc.in
+	M    libdapserver.pc.in
+	M    dap-config.in
+
+2009-09-02  James Gallagher <jgallagher at opendap.org>
+
+	Build fixes for linux. Linux uses libuuid for the uuid functions
+	while OSX does not - I added a test for that library to
+	configure.ac and the corrsponding changes to the Makefile.am. I
+	also found and fixed two other errors that were not showing up on
+	the OSX platform.
+
+	M    DODSFilter.cc
+	M    configure.ac
+	M    tests/Makefile.am
+	M    Makefile.am
+
+2009-09-02  mjohnson
+
+	o Fixed typo causing build error.
+
+2009-08-31  James Gallagher <jgallagher at opendap.org>
+
+	Replace fgetln with fgets in DDXParser.cc.  oddly package.m4 in
+	tests has the version number for the library. I changed that to 3.10.0
+	(we should have something for the trunk better than a version number
+	that looks like a release number) since I didn't think 3.9.2 was a
+	good value...
+
+2009-08-31  James Gallagher <jgallagher at opendap.org>
+
+	Configure fixes.
+
+	M    configure.ac
+
+2009-08-31  James Gallagher <jgallagher at opendap.org>
+
+	Updates for make dist.
+
+	M    tests/Makefile.am
+	M    INSTALL
+	M    Makefile.am
+
+2009-08-31  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2009-08-31  James Gallagher <jgallagher at opendap.org>
+
+	Added.
+
+2009-08-28  James Gallagher <jgallagher at opendap.org>
+
+	Refactor of libdap: AIS removed from build. In addition,
+	bug tickets addressed for Array, DDS, Vector and parser-util.cc
+
+2009-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Moved mime_util to libdap from libdapserver.
+
+2009-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Removed unnecessary libdapserver use for the unit-tests after moving cgi_util to mime_util
+	and putting the latter in libdap.
+
+2009-08-27  James Gallagher <jgallagher at opendap.org>
+
+	Added code to build and read the DataDDX response for DAP4.
+	Connect has request_data_ddx() and request_data_ddx_url()
+	methods that will ask a server for the DataDDX and parse
+	the returned response. Connect::read_data() can read a DataDDX
+	response from a file; getdap -M - can read the DataDDX returned
+	by besstandalone when it's asked to return a DataDDX. DODSFilter
+	now has a send_data_ddx() method and appropriate functions are
+	now in mime_util.cc/h to build and parse the multipart MIME
+	response. I also refactored the code somewhat renaming cgi_util to
+	mime_util and removing redundant MIME parsing code in Connect and
+	HTTPConnect - now all the MIME header parsing is done by functions
+	in mime_util. Since these are used by both client and server
+	operations, that should be moved to libdap (from libdapserver).
+
+2009-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Changed ID to Id to match the RFCs in the set_mime...() functions..
+	Also removed the set_client_dap_version() method and the matching get
+	methods - These were causing more confusion than anything else. Use
+	set_dap_version() and the matching get methods.
+
+	M    cgi_util.cc
+	M    DDS.cc
+	M    DDS.h
+
+2009-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Changed ID to Id in the set_mime...() code to match the RFCs; fixed here in
+	tests.
+
+	M    unit-tests/DODSFilterTest.cc
+
+2009-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an error where getdomainname() can return nothing
+	and not indicate and error. Now the default domain name
+	is opendap.org in that case.
+
+2009-08-20  James Gallagher <jgallagher at opendap.org>
+
+	Updates for the DataDDX response. New values were added
+	to the ObjectType and and EncodingType enums. DODSFilter
+	now has a send_data_ddx method that can either supply just
+	the body (as needed by the OLFS) or the complete message.
+	Unit tests added in unit-tests.DODSFilterTest. In HTTPConnect,
+	get_description_type() and get_object() were also updated.
+	Lastly, I change the values of Content-Description slightly
+	so they were a little less clunky and made the dap4 prefixed
+	values use dashes instead of underscores.
+
+2009-08-19  James Gallagher <jgallagher at opendap.org>
+
+	Interim version of autogen.sh for our projects - fix the --force option.
+
+	M    autogen.sh
+
+2009-08-19  James Gallagher <jgallagher at opendap.org>
+
+	Removed generated files.
+
+	D    conf/mkinstalldirs
+	D    conf/depcomp
+	D    conf/compile
+	D    conf/missing
+	D    conf/config.guess
+	D    conf/config.sub
+	D    conf/ltmain.sh
+	D    conf/install-sh
+
+2009-08-18  Nathan Potter <ndp at coas.oregonstate.edu>
+
+	libdap: Repaired bad string syntax and formatting.
+
+2009-08-18  mjohnson
+
+	Added set_name() override to set the name of the template var() as
+	well since this is what is output in a DDS and they didn't match.
+	Ticket #1346.
+
+2009-08-18  tomss
+
+	Changes to documentation only. Formatted ce function documentation
+	to be easier to read and removed a bad paragraph from the main
+	doxygen docs.
+
+2009-08-04  James Gallagher <jgallagher at opendap.org>
+
+	Added autogen.sh which is probably better than always running
+	autoreconf.
+
+	AM   autogen.sh
+
+2009-08-04  James Gallagher <jgallagher at opendap.org>
+
+	Changes for gcc 4.4: Removed warnings about misplaced or missing const
+	qualifiers and logic issues. Also fixed a missing header under FC 11
+	(util_mit.cc needs <cstdio> for sprintf).
+
+	M    Int16.cc
+	M    conf/mkinstalldirs
+	M    conf/depcomp
+	M    conf/missing
+	M    conf/config.guess
+	M    conf/config.sub
+	M    conf/ltmain.sh
+	M    conf/install-sh
+	M    INSTALL
+	M    UInt16.cc
+	M    Byte.cc
+	M    parser-util.cc
+	M    Float32.cc
+	M    HTTPConnect.cc
+	M    Str.cc
+	M    ce_functions.cc
+	M    das.y
+	M    UInt32.cc
+	M    util_mit.cc
+	M    dds.y
+	M    RCReader.h
+
+2009-07-28  James Gallagher <jgallagher at opendap.org>
+
+	Modified AISDataBaseParser.cc so that the library will build
+	with the --enable-debug=2 configure option. ticket 1318
+
+2009-07-21  mjohnson
+
+	del_attr_table needed to 0 out parent as well to preserve invariant.
+
+2009-07-21  mjohnson
+
+	Fixed memory leak in del_attr_table for Ticket #1326 and #1327.
+
+2009-07-21  mjohnson
+
+	Fixed several issues with the DAP type checking routines (which I re-used in NcML handler) failing to reject out of range Int32 and accepting a negative number as valid UInt32.
+
+2009-05-08  James Gallagher <jgallagher at opendap.org>
+
+	Merged changes for ticket 1301 from the tags/libdap/3.9.2 code.
+
+	M    Makefile.am
+	M    das.y
+	M    unit-tests/AISMergeTest.cc
+	M    unit-tests/DASTest.cc
+	M    unit-tests/DDSTest.cc
+
+2009-04-09  James Gallagher <jgallagher at opendap.org>
+
+	Changes for autoconf 2.63 (should work with 2.62 also).
+
+	M EXPRTest.at
+
+2009-04-08  James Gallagher <jgallagher at opendap.org>
+
+	Merged the 3.9.2 tagged code back into the trunk.
+
+	_M   .
+	M    RValue.cc
+	M    Int16.cc
+	M    configure.ac
+	M    DDXParser.cc
+	M    cgi_util.cc
+	M    ChangeLog
+	A  + conf/link-warning.h
+	M    DDS.cc
+	M    Array.cc
+	_M   tests/das-testsuite/test.1.das
+	_M   tests/expr-testsuite/test.2
+	_M   tests/expr-testsuite/test.3
+	_M   tests/expr-testsuite/test.c0
+	_M   tests/expr-testsuite/test.4
+	_M   tests/expr-testsuite/test.c1
+	_M   tests/expr-testsuite/test.c2
+	_M   tests/expr-testsuite/test.5
+	_M   tests/expr-testsuite/test.c3
+	_M   tests/expr-testsuite/test.6
+	_M   tests/expr-testsuite/test.c4
+	_M   tests/expr-testsuite/test.7
+	_M   tests/expr-testsuite/test.8
+	_M   tests/expr-testsuite/test.9
+	_M   tests/expr-testsuite/test.a
+	_M   tests/expr-testsuite/test.b
+	_M   tests/expr-testsuite/test.d
+	_M   tests/expr-testsuite/test.61
+	_M   tests/expr-testsuite/test.2a
+	_M   tests/expr-testsuite/test.cc0
+	_M   tests/expr-testsuite/test.cc1
+	_M   tests/expr-testsuite/test.1
+	M    tests/package.m4
+	M    INSTALL
+	M    UInt16.cc
+	M    libdap.spec
+	M    Byte.cc
+	M    GNU/GNURegex.cc
+	M    README
+	M    Makefile.am
+	M    HTTPCache.cc
+	M    ce_expr.y
+	M    Float32.cc
+	M    dds.lex
+	M    util.h
+	M    grammarfiles/ce_expr.tab.cc
+	M    NEWS
+	M    Str.cc
+	M    Sequence.cc
+	A  + gl/m4/absolute-header.m4
+	M    gl/m4/wchar.m4
+	M    gl/m4/stdint.m4
+	A  + gl/m4/malloc.m4
+	M    gl/m4/regex.m4
+	M    gl/m4/gnulib-comp.m4
+	A  + gl/m4/unistd_h.m4
+	M    gl/m4/include_next.m4
+	M    gl/m4/gnulib-cache.m4
+	D    gl/m4/onceonly_2_57.m4
+	A  + gl/m4/stdlib_h.m4
+	M    gl/m4/extensions.m4
+	M    gl/localcharset.c
+	M    gl/regex_internal.c
+	M    gl/malloc.c
+	M    gl/localcharset.h
+	M    gl/regex_internal.h
+	M    gl/regexec.c
+	A  + gl/stdlib.h
+	M    gl/regcomp.c
+	M    gl/alloca_.h
+	M    gl/wchar_.h
+	M    gl/stdint_.h
+	A  + gl/unistd_.h
+	M    gl/stdbool_.h
+	M    gl/regex.c
+	A  + gl/unistd.h
+	M    gl/regex.h
+	M    gl/wctype_.h
+	A  + gl/stdlib_.h
+	M    gl/Makefile.am
+	M    gl/gettext.h
+	M    gl/alloca.c
+	M    ce_functions.cc
+	M    expr.h
+	M    AttrTable.h
+	M    GridGeoConstraint.cc
+	M    util.cc
+	M    UInt32.cc
+	M    XDRStreamMarshaller.cc
+	M    Grid.cc
+	M    escaping.cc
+	M    unit-tests/HTTPCacheTest.cc
+	M    unit-tests/AttrTableTest.cc
+	M    unit-tests/generalUtilTest.cc
+	M    dds.y
+	M    Clause.cc
+	M    Array.h
+	M    ce_expr.lex
+
+2009-04-08  James Gallagher <jgallagher at opendap.org>
+
+	Bumped up the autoconf version to 2.61 which we need for the top_srcdir
+	variable. Other minor fixes like spelling errors in comments.
+
+	M    configure.ac
+	M    INSTALL
+	M    GNU/outbuf.h
+	M    ce_expr.y
+	M    Clause.cc
+	M    AISDatabaseParser.cc
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2009-04-06  James Gallagher <jgallagher at opendap.org>
+
+	Bug fix: entry::clone() was performing a deep copy in aliases when
+	the dtor expected aliases to use a shallow copy operation. This
+	resulted in a memory leak. See #1293.
+
+2009-03-16  James Gallagher <jgallagher at opendap.org>
+
+	Version 3.9.1
+
+	M    configure.ac
+	M    ChangeLog
+	M    INSTALL
+	M    libdap.spec
+	M    NEWS
+
+2009-03-10  James Gallagher <jgallagher at opendap.org>
+
+	Removed!
+
+	D    gl/alloca.h
+
+2009-03-10  James Gallagher <jgallagher at opendap.org>
+
+	Added.
+
+	AM   gl/alloca.h
+
+2009-03-05  James Gallagher <jgallagher at opendap.org>
+
+	Repaired a problem in the CE parser where the new test for
+	multiply projected arrays was failing because the test
+	was applied after the array was marked and so the projected
+	sizes differed, which looked like to different projections
+	but was actually two steps of the projection process.
+
+2009-03-05  James Gallagher <jgallagher at opendap.org>
+
+2009-03-05  James Gallagher <jgallagher at opendap.org>
+
+	Fixes from code review.
+
+	M    RValue.cc
+	M    Int16.cc
+	M    DDXParser.cc
+	M    cgi_util.cc
+	M    UInt16.cc
+	M    Byte.cc
+	M    GNU/GNURegex.cc
+	M    Makefile.am
+	M    Float32.cc
+	M    dds.lex
+	M    util.h
+	M    Str.cc
+	M    Sequence.cc
+	M    gl/localcharset.c
+	M    ce_functions.cc
+	M    GridGeoConstraint.cc
+	M    util.cc
+	M    UInt32.cc
+	M    XDRStreamMarshaller.cc
+	M    Grid.cc
+
+2009-02-26  James Gallagher <jgallagher at opendap.org>
+
+	I fixed a lingering problem with HTTPCache where its per-process
+	lock on the cache could not be obtained because the cache created
+	by a previous process was not writable. I used umask(0) to solve
+	that. I also made sure that sending a CE that constrains an array
+	of structures in two different ways returns an error. Lastly, I
+	removed old code from the Array class
+
+2009-02-20  James Gallagher <jgallagher at opendap.org>
+
+	Modified the ce_expr.y parser so that variable names can be
+	quoted (double quotes).
+
+2009-02-18  James Gallagher <jgallagher at opendap.org>
+
+	New version of www2id(). Now the third parameter can accept more than
+	one escape code to leave untouched.
+
+2009-01-30  James Gallagher <jgallagher at opendap.org>
+
+	Moved here to coalesce branches
+
+2009-01-30  James Gallagher <jgallagher at opendap.org>
+
+	Updated the 'CURRENT' revision for libdap and libdapserver.
+	Bummer, but we changed interfaces.
+
+2009-01-29  James Gallagher <jgallagher at opendap.org>
+
+	Move the code to a branch while we're in the beta period.
+
+	A    http://scm.opendap.org/svn/branch/libdap/3.9.0
+	D    http://scm.opendap.org/svn/tags/libdap/3.9.0
+
+2009-01-28  James Gallagher <jgallagher at opendap.org>
+
+	Changes for the distcheck target.
+
+	M    configure.ac
+	M    INSTALL
+	M    GNU/outbuf.h
+	M    ce_expr.y
+	M    dds.y
+	M    Clause.cc
+	M    AISDatabaseParser.cc
+
+2009-01-28  James Gallagher <jgallagher at opendap.org>
+
+	Release 3.9.0
+
+	A    http://scm.opendap.org/svn/tags/libdap/3.9.0
+
+2009-01-28  James Gallagher <jgallagher at opendap.org>
+
+	Updates for release 3.9.0
+
+	M    configure.ac
+	M    ChangeLog
+	M    libdap.spec
+	M    GNU/outbuf.h
+	M    README
+	M    Makefile.am
+	M    NEWS
+	M    unit-tests/Makefile.am
+
+2009-01-28  James Gallagher <jgallagher at opendap.org>
+
+	removed xstream references - we're not using this code although
+	I'd like to keep the source in the library since we might use it
+	at some point.
+
+	M Makefile.am
+
+2009-01-14  James Gallagher <jgallagher at opendap.org>
+
+	Patch from Patrice for missing string.h header.
+	Spelling errors in Makefile.am.
+
+	M    Makefile.amcon	
+	M    ce_expr.y
+
+2009-01-12  James Gallagher <jgallagher at opendap.org>
+
+	I changed the etag value used in the HTTPConnetTest so the test
+	will pass. The file changed and thus the etag changed when we
+	moved the test server.
+
+2008-12-04  Patrick West <pwest at ucar.edu>
+
+	curl.h is included in HTTPConnect.h, which is included in
+	AISMerge.h, which is included in getdap.cc. So need CURL_CFLAGS.
+	Not sure why this doesn't show up in other builds, however.
+
+	M    Makefile.am
+
+2008-12-03  James Gallagher <jgallagher at opendap.org>
+
+	Commented-out the #if FILE_METHODS ... #endif preprocessor lines.
+	For some reason these are breaking the library when FILE_METHODS
+	is one (but not when it's zero). Anyway, the FILE* methods are
+	needed for loaddap. I'm leaving the directives in as comments
+	since maybe someday I'll figure out _why_ these broke the library.
+
+	M    DODSFilter.cc
+	M    Int32.h
+	M    Int16.cc
+	M    Structure.h
+	M    Str.h
+	M    Sequence.h
+	M    Int16.h
+	M    DDS.cc
+	M    BaseType.h
+	M    Array.cc
+	M    Float64.h
+	M    UInt16.cc
+	M    AlarmHandler.h
+	M    Byte.cc
+	M    Byte.h
+	M    DDS.h
+	M    BaseType.cc
+	M    Constructor.h
+	M    Int32.cc
+	M    DODSFilter.h
+	M    Float32.cc
+	M    Grid.h
+	M    Structure.cc
+	M    Str.cc
+	M    Sequence.cc
+	M    Float32.h
+	M    Constructor.cc
+	M    UInt32.h
+	M    Float64.cc
+	M    UInt32.cc
+	M    Grid.cc
+	M    unit-tests/SequenceTest.cc
+	M    unit-tests/Makefile.am
+	AM   unit-tests/MarshallerTest.cc
+	M    Array.h
+	M    UInt16.h
+
+2008-11-25  James Gallagher <jgallagher at opendap.org>
+
+	Always build with the FILE_METHODS compile-time directive true. This
+	may cause problems...
+
+2008-11-25  James Gallagher <jgallagher at opendap.org>
+
+	Found more 'dataset' arguments, previously commented out, and
+	removed them. Makefile.am fixes that may address some build issues
+	seen by other people.
+
+2008-11-25  James Gallagher <jgallagher at opendap.org>
+
+	I had previously commented out all of the places where the data
+	set name was passed around to the various methods that evaluate a
+	CE. Patrick has moved information about the data set name into the
+	BaseType class so that a single DDS/DataDDS/DDX/... can be built
+	from multiple files/data sets. Passing the parameter was
+	redundant, so I commented it out. I completed the removal by
+	deleting those comments.
+
+	M    RValue.cc
+	M    DDXParser.h
+	M    DDXParser.cc
+	M    ce_functions.h
+	M    ConstraintEvaluator.cc
+	M    ArrayGeoConstraint.h
+	M    GeoConstraint.h
+	M    GridGeoConstraint.h
+	M    ce_expr.y
+	M    RValue.h
+	M    ce_functions.cc
+	M    expr.h
+	M    GridGeoConstraint.cc
+	M    ConstraintEvaluator.h
+	M    Clause.h
+	M    ArrayGeoConstraint.cc
+	M    unit-tests/ArrayGeoConstraintTest.cc
+	M    unit-tests/GridGeoConstraintTest.cc
+	M    Clause.cc
+	M    GeoConstraint.cc
+
+2008-11-17  James Gallagher <jgallagher at opendap.org>
+
+	Added check of C:\opendap when looking for .dodsrc on WIN32
+
+2008-11-14  James Gallagher <jgallagher at opendap.org>
+
+	Merged the xmlrequest branch to the trunk.
+
+	_M   .
+	M    RValue.cc
+	M    DDXParser.h
+	M    DODSFilter.cc
+	A  + xstream
+	A  + xstream/fd.h
+	A  + xstream/except_posix.h
+	A  + xstream/posix.cpp
+	A  + xstream/posix.h
+	A  + xstream/common.cpp
+	A  + xstream/fd.cpp
+	A  + xstream/common.h
+	A  + xstream/except.h
+	M    Int32.h
+	M    Int16.cc
+	M    Structure.h
+	M    Str.h
+	M    Sequence.h
+	M    configure.ac
+	M    Connect.h
+	M    DDXParser.cc
+	M    Ancillary.cc
+	M    ce_functions.h
+	M    Int16.h
+	D    docs/html.tar.gz
+	M    ConstraintEvaluator.cc
+	M    DDS.cc
+	M    BaseType.h
+	M    Array.cc
+	M    tests/das-testsuite/config/unix.exp
+	M    tests/expr-testsuite/expr-test.0/test.g.exp
+	M    tests/expr-testsuite/expr-test.0/test.6.exp
+	M    tests/expr-testsuite/config/unix.exp
+	M    tests/expr-test.cc
+	A  + tests/io_test.cc
+	M    tests/grid-func-testsuite/config/unix.exp
+	M    tests/Makefile.am
+	M    tests/dds-test.cc
+	M    Float64.h
+	M    UInt16.cc
+	M    AlarmHandler.h
+	M    Byte.cc
+	M    Byte.h
+	D    GNU/Pix.h.never
+	D    GNU/GNUerror.cc.never
+	A  + GNU/outbuf.cc
+	D    GNU/builtin.h.never
+	A  + GNU/outbuf.h
+	M    GNU/README
+	M    BaseType.cc
+	M    DDS.h
+	M    GeoConstraint.h
+	M    Makefile.am
+	M    GridGeoConstraint.h
+	M    Constructor.h
+	M    Int32.cc
+	M    DODSFilter.h
+	M    ce_expr.y
+	M    Float32.cc
+	M    Grid.h
+	M    HTTPConnect.cc
+	M    Structure.cc
+	M    RValue.h
+	M    getdap.cc
+	M    Str.cc
+	M    Sequence.cc
+	M    Float32.h
+	M    ce_functions.cc
+	M    expr.h
+	M    GridGeoConstraint.cc
+	M    Constructor.cc
+	M    UInt32.h
+	M    AISMerge.cc
+	M    ConstraintEvaluator.h
+	M    Clause.h
+	M    ArrayGeoConstraint.cc
+	M    Float64.cc
+	M    UInt32.cc
+	M    Grid.cc
+	M    Connect.cc
+	M    HTTPConnect.h
+	D    unit-tests/ais_testsuite/ais_database.xml
+	M    unit-tests/ais_testsuite/ais_database.xml.in
+	M    unit-tests/AISResourcesTest.cc
+	M    unit-tests/DDSTest.cc
+	M    unit-tests/test_config.h.in
+	M    unit-tests/HTTPConnectTest.cc
+	M    unit-tests/DDXParserTest.cc
+	M    unit-tests/ddsT.cc
+	M    unit-tests/ByteTest.cc
+	M    unit-tests/CEFunctionsTest.cc
+	A  + unit-tests/ddx-testsuite/error.06.ddx
+	A  + unit-tests/ddx-testsuite/test.0c.ddx
+	A  + unit-tests/ddx-testsuite/test.0d.ddx
+	A  + unit-tests/ddx-testsuite/test.00.ddx
+	M    unit-tests/Makefile.am
+	M    Clause.cc
+	M    GeoConstraint.cc
+	M    Array.h
+	M    UInt16.h
+
+2008-11-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the libcurl and libxml2 tests in confgure.ac - they now
+	test the values of the two programs correctly.
+
+2008-11-06  James Gallagher <jgallagher at opendap.org>
+
+	Minor changes that are part of a fix for ticket 975. The complete
+	changes are not done yet since the tests are not all passing for
+	the intern_data() methods (but do pass for the
+	serialize()/deserialize() methods and it might be that the problem
+	lies in the TestArray class and not in the libdap code outside the
+	tests. See svn/tags/libdap/partial_975_fix and the ticket itself
+	for more information.
+
+	M    Array.cc
+	M    tests/expr-test.cc
+	M    tests/TestStructure.cc
+	M    BaseType.cc
+	M    ce_expr.y
+	M    Structure.cc
+	M    Vector.cc
+	M    Array.h
+
+2008-10-30  James Gallagher <jgallagher at opendap.org>
+
+	Tests d1 and d3 will fail until I sort out just what is happening with
+	the array of structures and CEs in the Test* classes.
+
+2008-10-10  James Gallagher <jgallagher at opendap.org>
+
+	Added data file for Structure Array tests.
+
+2008-10-10  James Gallagher <jgallagher at opendap.org>
+
+	Modified ce_expr.y so that arrays of structure parse using the new
+	syntax. Example: s2[0:4].m[2:7]. See ticket 975.
+
+	M DDS.cc
+	M Vector.cc
+	M ce_expr.y
+
+2008-10-10  James Gallagher <jgallagher at opendap.org>
+
+	Added tests for Array of Structures fix - see ticket #975
+
+2008-10-08  James Gallagher <jgallagher at opendap.org>
+
+	Ticket 1188: can not --> cannot. This was for the a handful
+	of error messages, but I wound up changing it everywhere since
+	that was easier.
+
+2008-10-08  James Gallagher <jgallagher at opendap.org>
+
+	Fix for ticket 1121 - DDX not well formed for some HDF4 datasets
+	because the element Alias was not closed.
+
+	M AttrTable.cc
+
+2008-09-25  James Gallagher <jgallagher at opendap.org>
+
+	Added support for cookies to libdap. Cookies will be saved in a
+	'cookie jar' if that option/parameter is set int he .dodsrc file.
+
+	_M   tests
+	M    RCReader.cc
+	M    HTTPConnect.cc
+	M    HTTPConnect.h
+	_M   unit-tests/cache-testsuite
+	M    RCReader.h
+
+2008-09-25  James Gallagher <jgallagher at opendap.org>
+
+	Removed a test case fro AISResourceTest.cc since it was causing false
+	negatives when run as root on FC8.
+
+2008-09-19  James Gallagher <jgallagher at opendap.org>
+
+	Corrections for comments
+
+2008-09-18  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for tests after moving test.opendap.org - some of the
+	test files appear to be different (not sure I understand
+	that, but it's true, they are). Also, minor fixes for the
+	new DDX31 symbol and xml header info to fix build errors.
+
+2008-09-17  James Gallagher <jgallagher at opendap.org>
+
+	Merged multifile branch
+
+2008-09-17  James Gallagher <jgallagher at opendap.org>
+
+	Updated docs.
+
+	AM   docs/html.tar.gz
+
+2008-09-16  James Gallagher <jgallagher at opendap.org>
+
+	Check in simple changes before branching to start the bulk
+	of the DAP 3.2 changes.
+
+2008-08-26  James Gallagher <jgallagher at opendap.org>
+
+	Added a one option to getdap (-M) that enables it to
+	read from files that don't have MIME headers.
+
+2008-08-06  Patrick West <pwest at ucar.edu>
+
+	File accidentally added by eclipse
+
+	D    ais_database.xml
+
+2008-08-06  Patrick West <pwest at ucar.edu>
+
+	Deleting fines accidentally added by eclipse
+
+	D    ce_expr.tab.hh
+	D    3.8.1.diffs
+	D    libdap-3.8.1.tar.gz
+	D    tmp16780
+	D    deflate
+	D    ce_expr.output
+	D    .cproject
+	D    libdap-3.8.2.fpr
+	D    libdap.pc
+	D    tests/das-test.sum
+	D    tests/dds-test.sum
+	D    tests/expr-test
+	D    tests/das-test
+	D    tests/dds-test
+	D    tests/expr-test.sum
+	D    tmp16480
+	D    das.tab.hh
+	D    dds.tab.hh
+	D    ChangeLog.tmp
+	D    Error.tab.hh
+	D    gse.tab.hh
+	D    libdapclient.pc
+	D    das.output
+	D    dds.output
+	D    libdapserver.pc
+	D    Error.output
+	D    gse.output
+	D    unit-tests/CEFunctionsTest
+	D    unit-tests/cache-testsuite/cleanup.sh
+	D    unit-tests/parserUtilTest
+	D    unit-tests/sequenceT
+	D    unit-tests/marshT
+	D    unit-tests/DDSTest
+	D    unit-tests/generalUtilTest
+	D    unit-tests/ArrayTest
+	D    unit-tests/ArrayGeoConstraintTest
+	D    unit-tests/DDXParserTest
+	D    unit-tests/.dodsrc
+	D    unit-tests/cgiUtilTest
+	D    unit-tests/arrayT
+	D    unit-tests/DASTest
+	D    unit-tests/SequenceTest
+	D    unit-tests/AISDatabaseParserTest
+	D    unit-tests/ancT
+	D    unit-tests/HTTPConnectTest
+	D    unit-tests/test_config.h
+	D    unit-tests/AISMergeTest
+	D    unit-tests/ByteTest
+	D    unit-tests/structT
+	D    unit-tests/AttrTableTest
+	D    unit-tests/GridGeoConstraintTest
+	D    unit-tests/RCReaderTest
+	D    unit-tests/ddsT
+	D    unit-tests/DODSFilterTest
+	D    unit-tests/HTTPCacheTest
+	D    unit-tests/attrTableT
+	D    unit-tests/AISResourcesTest
+	D    unit-tests/RegexTest
+	D    unit-tests/SignalHandlerTest
+	D    svn-commit.tmp
+	D    getdap
+
+2008-08-04  James Gallagher <jgallagher at opendap.org>
+
+	Moved get_type() out of ObjectType.h and into HTTPConnect.cc and
+	changed its name to get_description_type() which is not only
+	more accurate but also less likely to conflict with other functions
+	(there are two other 'get_type()'s in libdap already). There are
+	other related changes.
+
+2008-08-01  James Gallagher <jgallagher at opendap.org>
+
+	Minor fix in dds.lex - test for an error from fgets(). Closes
+	ticket 1068.
+
+2008-08-01  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the expr-test tests - they were only running the
+	intern_data() code and not the serialize/deserialize code. Also,
+	removed use of move_dds() from expr-test as it is no longer
+	needed.
+
+2008-07-31  James Gallagher <jgallagher at opendap.org>
+
+	String attribute values are always quoted when the DAS is written
+	out (now). This is part of the fix for ticket 1163 (the other part
+	being changes to the handlers). See README for more information.
+
+	M    tests/das-testsuite/das-test.0/test.8.exp
+	M    tests/das-testsuite/das-test.0/test.9.exp
+	M    tests/das-testsuite/das-test.0/test.11.exp
+	M    tests/das-testsuite/das-test.0/test.1.exp
+	M    tests/das-testsuite/das-test.0/test.2.exp
+	M    tests/das-testsuite/das-test.0/test.3.exp
+	M    tests/das-testsuite/das-test.0/test.4.exp
+	M    README
+	M    util.h
+	M    AttrTable.cc
+	M    Vector.cc
+	M    das.y
+	M    util.cc
+	M    unit-tests/AttrTableTest.cc
+
+2008-07-28  hyoklee
+
+	Added dods_url_c type for Vector::value() function.
+
+2008-07-23  James Gallagher <jgallagher at opendap.org>
+
+	Merged changes from tags/libdap/3.8.2 (-r18931:19106
+	$svn/tags/libdap/3.8.2 .)
+
+	M    Ancillary.cc
+	M    VCPP/BeforeInstall.txt
+	M    VCPP/libdap.iss
+	M    VCPP/config.h
+	M    VCPP/Makefile
+
+2008-07-15  James Gallagher <jgallagher at opendap.org>
+
+	Patch from Patrice Dumas for gnulib/autoconf 2.62 compatibility.
+
+	M    gl/m4/extensions.m4
+
+2008-07-15  Patrick West <pwest at ucar.edu>
+
+	Problem where nested sequences not having any values selected
+	because of constraint evaluation, so nested sequences aren't being
+	pushed to the value stack. When coming out of parent_part_two to
+	the end of parent_part_one, the stack is popped to get that
+	sequences values. Since nothing was being pushed, the values for
+	that sequence were being popped leaving an empty stack. So when
+	top is called on an empty stack, caused bus error.
+
+	Also, in Sequence.cc, a dynamic cast was being made to a Sequence
+	variable called tmp. dynamic casts were called three more times in
+	the method. These can get expensive, so removed the other dynamic
+	casts and using first variable called tmp.
+
+	Added and modified DBG statements.
+	M    tests/TestInt32.cc
+	M    tests/TestFloat32.cc
+	M    tests/TestByte.cc
+	M    tests/TestSequence.cc
+	M    BaseType.cc
+	M    Sequence.cc
+	M    AISDatabaseParser.cc
+
+2008-06-25  James Gallagher <jgallagher at opendap.org>
+
+	Fixed one more problem with the xdr-datatype header. Assuming
+	that XDR uses the C99 types if the inttypes.h header is present
+	works on new FC machines but not OS/X, et cetera. I removed that
+	from the Makefile.am.
+
+	M    OSX_Resources/InstallationCheck
+	M    OSX_Resources/Info.plist
+	M    conf/acinclude.m4
+	M    Makefile.am
+
+2008-06-25  James Gallagher <jgallagher at opendap.org>
+
+	Fixes - I hope - to the *-datatypes headers. Other updates for
+	comments and documentation.
+
+	M    AISResources.cc
+	M    configure.ac
+	M    xdr-datatypes-static.h
+	M    xdr-datatypes-config.h.in
+	M    main_page.doxygen
+	M    Error.cc
+	M    conf/acinclude.m4
+	M    HTTPCacheTable.cc
+	M    doxy.conf
+
+2008-06-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed apue_db. Updates to the documentation for 3.8.2
+
+	M    ChangeLog
+	D    apue_db
+	M    INSTALL
+	M    README
+	M    NEWS
+
+2008-06-23  James Gallagher <jgallagher at opendap.org>
+
+	Minor changes - comments & docs.
+
+	M    HTTPCacheTable.cc
+	M    HTTPCacheTable.h
+
+2008-06-23  James Gallagher <jgallagher at opendap.org>
+
+	Minor changes from the 3.8.1 code except that the HTTP Caching
+	changes developed here on the trunk of libdap are now
+	included (libdap 3.8.1 excluded those fixes).
+
+	M    configure.ac
+	M    ChangeLog
+	M    NEWS
+	M    ce_functions.cc
+	M    unit-tests/AISMergeTest.cc
+	M    unit-tests/HTTPCacheTest.cc
+
+2008-06-16  James Gallagher <jgallagher at opendap.org>
+
+	Merged changes from the 3.8.1 tag.
+
+	M    VCPP/BeforeInstall.txt
+	M    VCPP/libdap.iss
+	A    VCPP/unistd.h
+	M    libdap.spec
+	M    README
+
+2008-06-16  James Gallagher <jgallagher at opendap.org>
+
+	AISMergeTest updated to work with the newer test.opendap.org
+	fnoc1 test data set (which has slightly different attributes).
+
+2008-06-16  James Gallagher <jgallagher at opendap.org>
+
+	Removed HTTPCacheTable::CacheEntry's lock since it was redundant
+	and was causing a dead lock. Also removed RCReader's debug output.
+
+2008-06-16  Patrick West <pwest at ucar.edu>
+
+	Added access to response file.
+	M    HTTPResponse.h
+	M    Response.h
+
+2008-06-10  James Gallagher <jgallagher at opendap.org>
+
+	The lock used to protect the CacheEntry object was redundant and I
+	removed it. Also, I backed out other changes but retained some of
+	the added encapsulation added to the CacheEntry struct. I checked
+	this code in because I fairly certain it works, but the test
+	server is down and so I cannot run the unit tests for HTTPCache.
+
+	M    HTTPCacheTable.cc
+	M    HTTPCacheTable.h
+	M    unit-tests/HTTPCacheTest.cc
+
+2008-06-09  Dan Holloway <dholloway at opendap.org>
+
+	Added ifdef HAVE_UNISTD_H, include <unistd.h>, required on RedHat 3.+
+
+2008-05-30  Patrick West <pwest at ucar.edu>
+
+	Moved ancillary functions from DODSFilter and cgi_util to
+	Ancillary class as static methods. Moved the ancillary tests from
+	cgiUtilTest to ancT. Had to update configure.ac and Makefile.am to
+	get libdap to compile, removing apue directory.
+	
+	M    DODSFilter.cc
+	M    configure.ac
+	M    cgi_util.cc
+	A    Ancillary.cc
+	M    Makefile.am
+	M    cgi_util.h
+	A    Ancillary.h
+	A    unit-tests/ancT.cc
+	M    unit-tests/cgiUtilTest.cc
+	M    unit-tests/Makefile.am
+
+2008-05-30  James Gallagher <jgallagher at opendap.org>
+
+	Test svn switch (I added a space to the to the top of the file).
+
+	M    util.cc
+
+2008-05-22  James Gallagher <jgallagher at opendap.org>
+
+	Fixed comments in the ce functions - they said to use "version"
+	when it's actually a blank arg list that returns the response.
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Made the directory name nicer
+
+	M    configure.ac
+	A    apue_db
+	D    apue_db/apue.h
+	D    apue_db/include
+	D    apue_db/db
+	A    apue_db/db.c
+	D    apue_db/lib
+	A    apue_db/lockreg.c
+	D    apue_db/Make.defines.linux
+	A    apue_db/t4.c
+	A    apue_db/error.c
+	M    Makefile.am
+	D    apue_db_lib
+	M    das.lex
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Removed include subdir
+
+	D    apue_db_lib/include
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Removed apue.h header.
+
+	D    apue_db_lib/apue.h
+	M    apue_db_lib/db.c
+	M    apue_db_lib/lockreg.c
+	M    apue_db_lib/t4.c
+	M    apue_db_lib/error.c
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Removed
+
+	D    apue_db_lib/Make.defines.linux
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Get rid of some temporary directories...
+
+	D    apue_db_lib/db
+	D    apue_db_lib/lib
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Added Advanced Programming in the Unix Environment DB.
+
+	A    apue_db_lib/apue.h
+	A    apue_db_lib/apue_db.h
+	M    apue_db_lib/lib/libapue.a
+	A    apue_db_lib/db.c
+	A    apue_db_lib/lockreg.c
+	A    apue_db_lib/t4.c
+	AM   apue_db_lib/Makefile.am
+	A    apue_db_lib/error.c
+
+2008-05-21  James Gallagher <jgallagher at opendap.org>
+
+	Copied
+
+2008-05-20  James Gallagher <jgallagher at opendap.org>
+
+	Removed cruft from the Steven's db checkin.
+
+2008-05-20  James Gallagher <jgallagher at opendap.org>
+
+	Added the Steven's db code in apue_db_lib (which I might rename later).
+
+2008-05-20  James Gallagher <jgallagher at opendap.org>
+
+	Removed #if 0 .. #endif lines.
+
+2008-05-20  James Gallagher <jgallagher at opendap.org>
+
+	Read/Write locking in place. Ready to start changing over from a
+	single index file to a distributed way of storing the entries.
+
+2008-05-15  James Gallagher <jgallagher at opendap.org>
+
+	Moved the locking of entries into the cache table class. This sets
+	the stage for changes to the table implementation so that it can be
+	stored on disk and not in memory.
+
+2008-05-14  James Gallagher <jgallagher at opendap.org>
+
+	removed #if 0 after refactoring HTTPCache, HTTPCacheTable
+	and CacheEntry. Tests now run.
+
+2008-05-14  James Gallagher <jgallagher at opendap.org>
+
+	CacheEntry has not been encapsulated, but only to the extent
+	that fields are manipulated with accessor/mutator methods.
+	The basic logic is still exposed to HTTPCache.
+
+2008-05-14  Patrick West <pwest at ucar.edu>
+
+	Requires using unistd.h if HAVE_UNISTD_H is defined, which requires
+	including config.h.
+	M    unit-tests/marshT.cc
+	M    unit-tests/RCReaderTest.cc
+
+2008-05-14  Patrick West <pwest at ucar.edu>
+
+	unlink requires unistd.h on linux machines.
+	M    unit-tests/marshT.cc
+
+2008-05-13  James Gallagher <jgallagher at opendap.org>
+
+	Added HTTPCacheTable to the VCPP Makefile
+
+2008-05-13  James Gallagher <jgallagher at opendap.org>
+
+	I Have refactored HTTPCache so that most of the operations
+	on the index file and in-memory 'database' of the cache
+	contents is now in the HTTPCacheTable class.
+
+2008-05-09  James Gallagher <jgallagher at opendap.org>
+
+	Added HTTPCacheTable class. HTTPCache will now be refactored
+	so that it makes all cache table accesses through this class'
+	interface. See ticket #1114 and #1118.
+
+2008-04-25  James Gallagher <jgallagher at opendap.org>
+
+	Wrapped CURL_PROXYAUTH in #ifdef #endif to accommodate older versions of
+	libcurl.
+
+	M HTTPConnect.cc
+
+2008-04-25  James Gallagher <jgallagher at opendap.org>
+
+	Spelling errors fixed.
+
+	M    VCPP/BeforeInstall.txt
+	M    README.dodsrc
+	M    RCReader.cc
+
+2008-04-25  James Gallagher <jgallagher at opendap.org>
+
+	Build tools no longer installed
+
+2008-04-24  James Gallagher <jgallagher at opendap.org>
+
+	Added installer setup file and License for the installer
+
+2008-04-23  James Gallagher <jgallagher at opendap.org>
+
+	Comments and strings modified as part of the win32 build of 3.8.1
+	from svn
+
+2008-04-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed Win32 definition of vsnprintf() for VC 2008 compat - edit
+	for use with VC 2005
+
+2008-04-23  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for libdap 3.8.0
+
+2008-04-21  James Gallagher <jgallagher at opendap.org>
+
+	Ticket 1095: The proxy support in HTTPConnect baroque and caused
+	many people problems. I expanded on the syntax allowed (the old
+	syntax is still supported) so that it mirrors the syntax most
+	users expect. I updated the docs including the comments in the
+	.dodsrc file.
+
+	M    Makefile.am
+	M    RCReader.cc
+	M    NEWS
+	M    HTTPConnect.cc
+	M    unit-tests/RCReaderTest.cc
+	A    unit-tests/rcreader-testsuite/test4.rc
+	A    unit-tests/rcreader-testsuite/test5.rc
+
+2008-04-15  James Gallagher <jgallagher at opendap.org>
+
+	Added code to follow redirects in HTTPConnect.cc
+
+2008-04-07  Patrick West <pwest at ucar.edu>
+
+	Delete being called on array without [], as is being called below the
+	exception condition.
+	M    HTTPCache.cc
+
+2008-03-19  James Gallagher <jgallagher at opendap.org>
+
+	Added info about win32 locations for .dodsrc
+
+	M    README.dodsrc
+
+2008-03-19  James Gallagher <jgallagher at opendap.org>
+
+	Added Patrice Dumas' patch for <cstring>
+
+	M    SignalHandler.cc
+	M    gse.lex
+	M    dds.lex
+	M    HTTPConnect.cc
+	M    das.lex
+	M    ce_expr.lex
+
+2008-03-04  Patrick West <pwest at ucar.edu>
+
+	Now checks for which architecture the build is being run on and
+	updates the InstallationCheck script M
+	update_mac_package_contents.pl
+
+2008-03-04  Patrick West <pwest at ucar.edu>
+
+	3.8.0 release of libdap.
+	
+	M    configure.ac
+	M    ChangeLog
+	M    OSX_Resources/Info.plist
+	M    OSX_Resources/ReadMe.txt
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+2008-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Added conditional include of unistd.h for RHEL3 build.
+
+	M    SignalHandler.cc
+	M    tests/TestArray.cc
+	M    HTTPConnect.cc
+	M    DAS.cc
+
+2008-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Header patch from Patrice Dumas.
+
+	Many files modified.
+
+2008-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Directory regex --> pathname_ok() call. A minor change.
+
+	M Util.cc
+
+2008-03-02  James Gallagher <jgallagher at opendap.org>
+
+	Added shell commands so build works with bison 1.28. That
+	version treats the -o option differently than the 2.x version.
+
+	M Makefile.am
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2008-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Added conditional include of unistd.h for RHEL3 build.
+	M    SignalHandler.cc
+	M    tests/TestArray.cc
+	M    HTTPConnect.cc
+	M    DAS.cc
+
+2008-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Header patch from Patrice Dumas.
+	Many files modified.
+
+2008-03-03  James Gallagher <jgallagher at opendap.org>
+
+	Directory regex --> pathname_ok() call. A minor change.
+	M Util.cc
+
+2008-03-02  James Gallagher <jgallagher at opendap.org>
+
+	Added shell commands so build works with bison 1.28. That
+	version treats the -o option differently than the 2.x version.
+	M Makefile.am
+
+2008-03-01  James Gallagher <jgallagher at opendap.org>
+
+	Tweaked the comments about the YY_INPUT macro.
+	M dds.lex
+
+2008-02-29  James Gallagher <jgallagher at opendap.org>
+
+	Switch back to the old YY_INPUT macro for now...
+	M    dds.lex
+
+2008-02-29  James Gallagher <jgallagher at opendap.org>
+
+	I found that a number of the places where a *.tab.h was included did
+	not get changed when I went to the .hh file names (which is how
+	bison does things when you tell it to make the output a *.tab.cc
+	file). Here are the fixes. the distcheck and rpm targets now work.
+	M    Error.lex
+	M    Int16.cc
+	M    error-test.cc
+	M    tests/expr-test.cc
+	M    tests/dds-test.cc
+	M    UInt16.cc
+	M    Int32.cc
+	M    gse-test.cc
+	M    Str.cc
+	M    Float64.cc
+	M    Operators.h
+	M    UInt32.cc
+
+2008-02-29  James Gallagher <jgallagher at opendap.org>
+
+	There are three changes in these files: 1. formatting;
+	2. Grammar builds; 3. Security fixes. For the formatting
+	changes some files just got messed up and I was sick of
+	looking at it. Grammar changes amount to simplifying the
+	builds of the lex and y files. Now the sed calls in the
+	Makefile have been removed - commented out to be completely
+	removed later. 3. Nothing major on the security front
+	but I made some changes all the same.
+
+2008-02-29  Patrick West <pwest at ucar.edu>
+
+	Updates for release of 3.7.11.
+	M    configure.ac
+	M    ChangeLog
+	M    INSTALL
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2008-02-28  Patrick West <pwest at ucar.edu>
+
+	If cleanup.sh does not exist, then a make clean will error out.
+	clean-local depends on cleanup.sh.
+	M    cache-testsuite/Makefile.am
+
+2008-02-28  Patrick West <pwest at ucar.edu>
+
+	Added comment regarding ais_testsuite directory and how those files
+	are being distributed.
+	M    unit-tests/Makefile.am
+
+2008-02-28  Patrick West <pwest at ucar.edu>
+
+	Removing generated files from Makefile.am. Removing temporary files
+	in marshT created for writing marshalled data. cleanup script
+	cleaned up.  cache-testsuite makefile running local cleanup.sh since
+	cleanup.sh is generated, also added distclean-local to remove the
+	dods_cache directory.  unit-tests makefile adds individual
+	ais_testsuite files because there is the generated file there so
+	just adding the directory wasn't working.
+	M    Makefile.am
+	M    unit-tests/marshT.cc
+	M    unit-tests/cache-testsuite/cleanup.sh.in
+	M    unit-tests/cache-testsuite/Makefile.am
+	M    unit-tests/Makefile.am
+
+2008-02-28  Patrick West <pwest at ucar.edu>
+
+	Modified tests and configuration to get unit-tests to run during
+	distcheck.
+	M    unit-tests/AISMergeTest.cc
+	M    unit-tests/DODSFilterTest.cc
+	D    unit-tests/ais_testsuite/ais_database.xml
+	A    unit-tests/ais_testsuite/ais_database.xml.in
+	D    unit-tests/cache-testsuite/cleanup.sh
+	A    unit-tests/cache-testsuite/cleanup.sh.in
+	M    unit-tests/cache-testsuite/Makefile.am
+	M    unit-tests/DASTest.cc
+	M    unit-tests/AISResourcesTest.cc
+	M    unit-tests/DDSTest.cc
+	A    unit-tests/test_config.h.in
+	M    unit-tests/HTTPConnectTest.cc
+	M    unit-tests/DDXParserTest.cc
+	M    unit-tests/cgiUtilTest.cc
+	M    unit-tests/AISDatabaseParserTest.cc
+	M    unit-tests/CEFunctionsTest.cc
+	M    unit-tests/GridGeoConstraintTest.cc
+	M    unit-tests/Makefile.am
+	M    unit-tests/RCReaderTest.cc
+
+2008-02-27  Patrick West <pwest at ucar.edu>
+
+	Added check for cppunit in configure. If present, then the tests
+	will be built and run. if not then a message will appear saying that
+	can't run the tests without the library, but it's not an error.
+	M    configure.ac
+	A    conf/cppunit.m4
+	M    Makefile.am
+	M    unit-tests/Makefile.am
+
+2008-02-27  James Gallagher <jgallagher at opendap.org>
+
+	Updated indentation using "indent -kr"
+	M    gl/alloca_.h
+	M    gl/mbchar.h
+	M    gl/localcharset.c
+	M    gl/strcasecmp.c
+	M    gl/regex_internal.c
+	M    gl/strnlen1.c
+	M    gl/malloc.c
+	M    gl/wchar_.h
+	M    gl/localcharset.h
+	M    gl/stdint_.h
+	M    gl/strcase.h
+	M    gl/regex.c
+	M    gl/stdbool_.h
+	M    gl/memchr.c
+	M    gl/regex_internal.h
+	M    gl/strnlen1.h
+	M    gl/mbuiter.h
+	M    gl/regex.h
+	M    gl/wctype_.h
+	M    gl/regexec.c
+	M    gl/strncasecmp.c
+	M    gl/gettext.h
+	M    gl/alloca.c
+	M    gl/mbchar.c
+	M    gl/regcomp.c
+
+2008-02-26  Patrick West <pwest at ucar.edu>
+
+	No longer need the MacOSX specific readme and install files.
+	M    OSX_Resources/Info.plist
+	D    INSTALL_MacOSX.rtf
+	D    README_MacOSX.rtf
+
+2008-02-23  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2008-02-22  James Gallagher <jgallagher at opendap.org>
+
+	Updated
+
+2008-02-22  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an error that crept into xdr-datatypes-static from the xp
+	port. I made the change in a new copy of the xdr-datatypes.h header
+	added to the VCPP directory.  Also, I removed some old code from the
+	XDRUtils.cc file.
+	M    xdr-datatypes-static.h
+	AM   VCPP/xdr-datatypes.h
+	M    XDRUtils.cc
+
+2008-02-21  Patrick West <pwest at ucar.edu>
+
+	Added remove of temporary directories when pkg build is done.
+	M    Makefile.am
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Modified Makefile to install xdr-datatypes.h from VCPP
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Removed a patch
+	M XDRStreamMarshaller.cc
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Removed a patch
+	M XDRFileMarshaller.cc
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Backed out some changes for my version of XP.
+	M XDRFileUnMarshaller.cc
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for the win32 build from Anna Nokolov - I turned her files
+	into a patch but there were some rejects.
+	M    xdr-datatypes-static.h
+	M    XDRFileUnMarshaller.cc
+	M    gl/stdint_.h
+	M    XDRStreamMarshaller.cc
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Added patch from Anna Nokolov.
+	M XDRFileMarshaller.cc
+
+2008-02-21  James Gallagher <jgallagher at opendap.org>
+
+	Applied Win32 patches from Anna Nokolov.
+	M    cgi_util.cc
+	M    VCPP/Makefile
+	M    GNU/GNURegex.cc
+	M    parser-util.cc
+	M    util.h
+	M    das.lex
+	M    gl/localcharset.c
+	M    gl/stdint_.h
+	M    gl/regex_internal.h
+	M    util.cc
+	M    XDRFileMarshaller.cc
+
+2008-02-18  Patrick West <pwest at ucar.edu>
+
+	functional expressions were not being evaluated when building the
+	ddx.  Updated this and removed newline from error message if problem
+	with functional expressions.
+	M    DODSFilter.cc
+
+2008-02-14  Patrick West <pwest at ucar.edu>
+
+	Fixed sed issue with discovering version inormation in libdap.m4.
+	This one should be used by anyone who wants to use libdap.
+	M    conf/libdap.m4
+
+2008-02-13  James Gallagher <jgallagher at opendap.org>
+
+	Added unistd.h include.
+	M    unit-tests/AISResourcesTest.cc
+	M    unit-tests/ByteTest.cc
+	M    unit-tests/testFile.cc
+
+2008-02-13  James Gallagher <jgallagher at opendap.org>
+
+	Added config.h header include to AttrTableTest.cc
+
+2008-02-13  James Gallagher <jgallagher at opendap.org>
+
+	Added include of unistd.h to AttrTableTest.cc for RHEL3
+
+2008-02-05  James Gallagher <jgallagher at opendap.org>
+
+	Removed two tests that fail on machines where the tests are run as
+	root.
+	M HTTPCacheTest.cc
+
+2008-02-05  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2008-02-04  Patrick West <pwest at ucar.edu>
+
+	Added method to not only return the FILE pointer but also the cached
+	file name when getting the cached response. Also, when parsing
+	headers, taking into account a blank line and a malformed header.
+	M    HTTPCache.cc
+	M    HTTPCache.h
+	M    HTTPConnect.cc
+
+2008-02-04  Patrick West <pwest at ucar.edu>
+
+	Includes added for unlink function call
+	M    unit-tests/ddsT.cc
+
+2008-02-02  Patrick West <pwest at ucar.edu>
+
+	Added namespace libdap
+	M    Error.lex
+	M    RValue.cc
+	M    DDXParser.h
+	M    DODSFilter.cc
+	M    HTTPResponse.h
+	M    Int16.cc
+	M    Int32.h
+	M    Structure.h
+	M    AISResources.cc
+	M    Sequence.h
+	M    Str.h
+	M    ResponseTooBigErr.cc
+	M    SignalHandler.cc
+	M    ResponseTooBigErr.h
+	M    SignalHandler.h
+	M    XDRUtils.h
+	M    escaping.h
+	M    Connect.h
+	M    DDXParser.cc
+	M    cgi_util.cc
+	M    dods-datatypes-static.h
+	M    ce_functions.h
+	M    gse.lex
+	M    DDXExceptions.h
+	M    Resource.h
+	M    Error.cc
+	M    HTTPCacheDisconnectedMode.h
+	M    UnMarshaller.h
+	M    Response.h
+	M    Int16.h
+	M    SignalHandlerRegisteredErr.h
+	M    ce_parser.h
+	M    ConstraintEvaluator.cc
+	M    DAS.h
+	M    DDS.cc
+	M    XDRFileMarshaller.h
+	M    tests/TestInt32.h
+	M    tests/TestStructure.h
+	M    tests/TestInt16.h
+	M    tests/TestUrl.h
+	M    tests/TestSequence.h
+	M    tests/TestStr.h
+	M    tests/TestFloat64.h
+	M    tests/das-test.cc
+	M    tests/TestGrid.h
+	M    tests/TestByte.h
+	M    tests/TestTypeFactory.h
+	M    tests/TestFloat32.h
+	M    tests/TestArray.h
+	M    tests/TestUInt32.h
+	M    tests/dds-test.cc
+	M    tests/TestUInt16.h
+	M    tests/TestCommon.cc
+	M    Array.cc
+	M    BaseType.h
+	M    HTTPCacheInterruptHandler.h
+	M    EventHandler.h
+	M    Float64.h
+	M    AISConnect.cc
+	M    UInt16.cc
+	M    InternalErr.h
+	M    EncodingType.h
+	M    gse_parser.h
+	M    Marshaller.h
+	M    AlarmHandler.h
+	M    Byte.cc
+	M    GNU/GNURegex.cc
+	M    GNU/GNURegex.h
+	M    Byte.h
+	M    DataDDS.h
+	M    BaseType.cc
+	M    DDS.h
+	M    XDRUtils.cc
+	M    ArrayGeoConstraint.h
+	M    GeoConstraint.h
+	M    HTTPCacheResponse.h
+	M    RCReader.cc
+	M    GridGeoConstraint.h
+	M    Constructor.h
+	M    util_mit.h
+	M    Error.h
+	M    Int32.cc
+	M    DODSFilter.h
+	M    DapObj.h
+	M    gse.y
+	M    HTTPCache.cc
+	M    DataDDS.cc
+	M    HTTPCache.h
+	M    parser-util.cc
+	M    DapIndent.h
+	M    ce_expr.y
+	M    AISResources.h
+	M    ObjectType.h
+	M    Float32.cc
+	M    Error.y
+	M    dds.lex
+	M    PipeResponse.h
+	M    util.h
+	M    AISExceptions.h
+	M    AISDatabaseParser.h
+	M    AttrTable.cc
+	M    InternalErr.cc
+	M    Grid.h
+	M    HTTPConnect.cc
+	M    AISMerge.h
+	M    RValue.h
+	M    Structure.cc
+	M    cgi_util.h
+	M    Url.cc
+	M    Vector.cc
+	M    getdap.cc
+	M    BaseTypeFactory.h
+	M    Str.cc
+	M    Sequence.cc
+	M    das.lex
+	M    XDRFileUnMarshaller.cc
+	M    Float32.h
+	M    XDRFileUnMarshaller.h
+	M    ce_functions.cc
+	M    expr.h
+	M    AttrTable.h
+	M    GridGeoConstraint.cc
+	M    Constructor.cc
+	M    UInt32.h
+	M    XDRStreamMarshaller.h
+	M    das.y
+	M    AISMerge.cc
+	M    parser.h
+	M    BaseTypeFactory.cc
+	M    Url.h
+	M    Vector.h
+	M    DAS.cc
+	M    ConstraintEvaluator.h
+	M    GSEClause.cc
+	M    GSEClause.h
+	M    util.cc
+	M    Clause.h
+	M    ArrayGeoConstraint.cc
+	M    Float64.cc
+	M    Operators.h
+	M    UInt32.cc
+	M    XDRStreamMarshaller.cc
+	M    Grid.cc
+	M    util_mit.cc
+	M    Connect.cc
+	M    escaping.cc
+	M    unit-tests/AISMergeTest.cc
+	M    unit-tests/sequenceT.cc
+	M    unit-tests/DODSFilterTest.cc
+	M    unit-tests/HTTPCacheTest.cc
+	M    unit-tests/DASTest.cc
+	M    unit-tests/AISResourcesTest.cc
+	M    unit-tests/DDSTest.cc
+	M    unit-tests/SignalHandlerTest.cc
+	M    unit-tests/ArrayGeoConstraintTest.cc
+	M    unit-tests/ArrayTest.cc
+	M    unit-tests/AttrTableTest.cc
+	M    unit-tests/HTTPConnectTest.cc
+	M    unit-tests/DDXParserTest.cc
+	M    unit-tests/ddsT.cc
+	M    unit-tests/cgiUtilTest.cc
+	M    unit-tests/ByteTest.cc
+	M    unit-tests/attrTableT.cc
+	M    unit-tests/SequenceTest.cc
+	M    unit-tests/RegexTest.cc
+	M    unit-tests/generalUtilTest.cc
+	M    unit-tests/AISDatabaseParserTest.cc
+	M    unit-tests/GridGeoConstraintTest.cc
+	M    unit-tests/RCReaderTest.cc
+	M    unit-tests/parserUtilTest.cc
+	M    HTTPConnect.h
+	M    dds.y
+	M    StdinResponse.h
+	M    DapIndent.cc
+	M    XDRFileMarshaller.cc
+	M    Clause.cc
+	M    AISDatabaseParser.cc
+	M    GeoConstraint.cc
+	M    Array.h
+	M    AISConnect.h
+	M    UInt16.h
+	M    ce_expr.lex
+	M    RCReader.h
+
+2008-02-01  James Gallagher <jgallagher at opendap.org>
+
+	Added some file to svn:ignore
+
+	M gl
+
+2008-02-01  James Gallagher <jgallagher at opendap.org>
+
+	Added conditional set of the gcc -Wall, et c., flags.
+	M Makefile.am
+
+2008-01-31  Nathan Potter <ndp at coas.oregonstate.edu>
+
+	libdap: Changed Error handling in ce_functions.cc so that the errors
+	thrown appropriatley referenced an error code other than unknown
+
+2008-01-31  James Gallagher <jgallagher at opendap.org>
+
+	Added conditional set of the gcc -Wall, et c., flags.
+
+2008-01-30  James Gallagher <jgallagher at opendap.org>
+
+	Include <algorithm> for all builds, not just win32. This is a fix
+	for AIX and its native compiler.
+
+2008-01-29  James Gallagher <jgallagher at opendap.org>
+
+	Update to the package target for OSX.
+	M    OSX_Resources/InstallationCheck
+	M    OSX_Resources/update_mac_package_contents.pl
+	M    OSX_Resources/InstallationCheck.strings
+	M    Makefile.am
+
+2008-01-28  James Gallagher <jgallagher at opendap.org>
+
+	It seems that universal binaries are not yet working - I commented
+	out that part of the Makefile.
+	M    Makefile.am
+
+2008-01-28  James Gallagher <jgallagher at opendap.org>
+
+	Hacked the Makefile.am so that the 'pkg' target makes a universal
+	binary - maybe. Fixed up the OSX resources' text.
+	M    OSX_Resources/Info.plist
+	M    OSX_Resources/Description.plist
+	M    Makefile.am
+
+2008-01-22  James Gallagher <jgallagher at opendap.org>
+
+	Added support to filter out ^M that's introduced by DOS editors.
+	M update_mac_package_contents.pl
+
+2008-01-16  James Gallagher <jgallagher at opendap.org>
+
+	Updated comments
+	M Makefile.am
+
+2008-01-16  James Gallagher <jgallagher at opendap.org>
+
+	Removed major and minor version.
+	M    OSX_Resources/Info.plist
+
+2008-01-14  James Gallagher <jgallagher at opendap.org>
+
+	Applied pkgconfig patch from Patrice.
+	M    libdap.spec
+	M    Makefile.am
+	M    libdapclient.pc.in
+	M    libdap.pc.in
+	M    unit-tests/testFile.cc
+	M    unit-tests/Makefile.am
+	M    libdapserver.pc.in
+	A    dap-config-pkgconfig
+
+2008-01-12  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2008-01-11  James Gallagher <jgallagher at opendap.org>
+
+	Added. These help automate the build process.
+	AM   OSX_Resources/macify_license_file.pl
+	AM   OSX_Resources/update_mac_package_contents.pl
+
+2008-01-11  James Gallagher <jgallagher at opendap.org>
+
+	Updates to the OS/X build so that it is more automatic. No more
+	pmproj file, either. I added <code> tags in the README so that the
+	perl script that updates the Mac version of that file will look
+	decent.
+	M    OSX_Resources/InstallationCheck
+	M    OSX_Resources/License.txt
+	M    OSX_Resources/Info.plist
+	M    OSX_Resources/InstallationCheck.strings
+	M    OSX_Resources/ReadMe.txt
+	M    OSX_Resources/Welcome.html
+	M    README
+	M    Makefile.am
+	D    mac_osx
+	D    libdap.pmproj
+
+2008-01-10  Patrick West <pwest at ucar.edu>
+
+	Certain size vector of bytes was failing when writing to the xdr
+	stream.  Changed the size of the buffer to add enough to cover the
+	word boundary.  Updated unit test to test for this.
+	M    Vector.cc
+	M    XDRStreamMarshaller.cc
+	M    unit-tests/marshT.cc
+	M    unit-tests/arrayT.cc
+
+2008-01-08  James Gallagher <jgallagher at opendap.org>
+
+	Removed leading spaces of the lines so that the file can be used
+	easily on the Mac where lines will wrap in the Installer.
+
+2008-01-08  James Gallagher <jgallagher at opendap.org>
+
+	Fixed up these two tests to match the changes in the ais database
+	they used.
+	M    unit-tests/AISMergeTest.cc
+	M    unit-tests/AISResourcesTest.cc
+
+2008-01-07  James Gallagher <jgallagher at opendap.org>
+
+	make check now runs the unit tests (ticket 1012)
+	M    Makefile.am
+
+2008-01-07  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the AIS database parser tests so they now use Hyrax and not
+	some kludge.
+	M    unit-tests/ais_testsuite/ais_database.xml
+	M    unit-tests/AISDatabaseParserTest.cc
+
+2007-12-01  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-11-30  Patrick West <pwest at ucar.edu>
+
+	MacOSX resources updated. Added a README and INSTALL file to be put
+	alongside the .pkg in the .dmg.
+	M    OSX_Resources/Info.plist
+	D    README_MaxOSX.rtf
+	M    Makefile.am
+	A    README_MacOSX.rtf
+
+2007-11-30  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-11-29  Patrick West <pwest at ucar.edu>
+
+	the .pc files needed to be dealt with during the pkg build so that
+	the prefix was set correctly.
+	M    Makefile.am
+
+2007-11-29  Patrick West <pwest at ucar.edu>
+
+	README and INSTALL files for a MacOSX installation. To be put into
+	the .dmg along with the .pkg.
+	A    README_MaxOSX.rtf
+	A    INSTALL_MacOSX.rtf
+
+2007-11-28  James Gallagher <jgallagher at opendap.org>
+
+	Updated for release 3.7.10
+
+	M    configure.ac
+	M    ChangeLog
+	M    INSTALL
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2007-11-28  James Gallagher <jgallagher at opendap.org>
+
+	Fixed warnings about potentially uninitialized uses of ENTRY in
+	HTTPCache.cc
+
+2007-11-28  Patrick West <pwest at ucar.edu>
+
+	Added private default constructor, copy constructor, and operator=
+	to the classes, all through InternalErr. Added copyright
+	information as well.
+	
+	M    XDRUtils.h
+	M    UnMarshaller.h
+	M    XDRFileMarshaller.h
+	M    Marshaller.h
+	M    XDRUtils.cc
+	M    XDRFileUnMarshaller.cc
+	M    XDRFileUnMarshaller.h
+	M    XDRStreamMarshaller.h
+	M    XDRStreamMarshaller.cc
+	M    XDRFileMarshaller.cc
+
+2007-11-26  Patrick West <pwest at ucar.edu>
+
+	In Vector.cc, checking if _var is null before attempting delete.
+	Didn't appear to be an issue, but seemed to be a needed test.
+
+	In XDRStreamMarshaller, not allocating such a large buffer.
+	Allocating only what is needed in put_str and both put_vector
+	calls. The other methods are using the static buffer so we don't
+	have to allocate each time. Prettied up the code, added more
+	comments, and corrected some exception messages.
+	
+	M    Vector.cc
+	M    XDRStreamMarshaller.cc
+
+2007-11-21  James Gallagher <jgallagher at opendap.org>
+
+	libdapclient and libdapserver library versions bumped up.
+
+	M    configure.ac
+	M    depend.sh
+	M    libdap.spec
+	M    NEWS
+
+2007-11-14  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the LIBDAP CHECK macro
+
+	M    conf/libdap.m4
+
+2007-11-13  James Gallagher <jgallagher at opendap.org>
+
+	Updated for version 3.7.9
+
+	M    configure.ac
+	M    ChangeLog
+	M    INSTALL
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+2007-11-13  James Gallagher <jgallagher at opendap.org>
+
+	Fixeed ticket #995. The problem was in intern_data_for_leaf.
+	This problem was fixed by changing the way intern_data_for_leaf()
+	worked, slightly. It was always popping the stack of `d_values`
+	object pointers regardless of the return value of read_row().
+	However, if no values are read then the call to
+	intern_data_for_parent_part_two() would never be called and the
+	d_values field of the child sequence wouldn't be pushed onto the stack.
+	Hence the pop should not happen - because there's no child there to
+	pop. I fixed this with a slight change in the code. The method now
+	skips the while loop and subsequent pop operation if the first call
+	to read_row() returns false. The while loop won't be run anyway,
+	so the actual change is minor and eliminates an unnecessary test
+	in the case where read_row does return false initially.
+
+	All of the tests that are expected to pass now do.
+
+2007-11-12  James Gallagher <jgallagher at opendap.org>
+
+	Grid.cc: Changed the way the declarataion is printed by print_val()
+	so that intern_data can use this too and work with the expr-test
+	test driver.
+	Sequence.cc: transfer_data_part_two() now uses intern_data() when
+	it should in place of read(). Also, print_one_row() is now more
+	flexible in the way it prints rows. Before it expected that the
+	first row would alway be printed (because it assume that the row
+	had been read by deserialize()). Now it checks to see if the row
+	should be printed because it knows that intern_data() might be
+	run and that method is working with local data - the first row
+	might not satisfy the CE.
+	Sequence.h: Formatting
+	Structure.cc: Switched from transfer_data to intern_data.
+
+2007-11-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed this test. The error message changed and the test failed
+	for that reason, not that error went undetected.
+
+	M dds-testsuite/dds-test.0/test.17.exp
+
+2007-11-12  James Gallagher <jgallagher at opendap.org>
+
+	Copied and munged these so that they call the expr-test_start
+	procedure and test intern_data() in libdap.
+
+	M    test.9.exp
+	M    test.ya.exp
+	M    test.yb.exp
+	M    test.yc.exp
+	M    test.yd.exp
+	M    test.ye.exp
+	M    test.yf.exp
+	M    test.yg.exp
+	M    test.a.exp
+	M    test.b.exp
+	M    test.c.exp
+	M    test.d.exp
+	M    test.zz0.exp
+	M    test.e.exp
+	M    test.zz1.exp
+	M    test.zz2.exp
+	M    test.f.exp
+	M    test.zz3.exp
+	M    test.g.exp
+	M    test.zz4.exp
+	M    test.61a.exp
+	M    test.h.exp
+	M    test.zz5.exp
+	M    test.61b.exp
+	M    test.i.exp
+	M    test.61c.exp
+	M    test.j.exp
+	M    test.61d.exp
+	M    test.k.exp
+	M    test.l.exp
+	M    test.m.exp
+	M    test.n.exp
+	M    test.o.exp
+	M    test.p.exp
+	M    test.q.exp
+	M    test.r.exp
+	M    test.s.exp
+	M    test.t.exp
+	M    test.u.exp
+	M    test.v.exp
+	M    test.w.exp
+	M    test.wa.exp
+	M    test.x.exp
+	M    test.wb.exp
+	M    test.y.exp
+	M    test.wc.exp
+	M    test.xa.exp
+	M    test.xb.exp
+	M    test.xc.exp
+	M    test.xd.exp
+	M    test.xe.exp
+	M    test.z0.exp
+	M    test.z1.exp
+	M    test.z2.exp
+	M    test.z3.exp
+	M    test.z4.exp
+	M    test.z5.exp
+	M    test.z6.exp
+	M    test.1.exp
+	M    test.z7.exp
+	M    test.2.exp
+	M    test.5.exp
+	M    test.6.exp
+
+2007-11-12  James Gallagher <jgallagher at opendap.org>
+
+	Updated test code so that the new intern_data() method is tested.
+
+	M    tests/TestInt32.cc
+	M    tests/TestInt32.h
+	M    tests/TestInt16.cc
+	M    tests/TestStructure.h
+	M    tests/TestInt16.h
+	M    tests/TestUrl.h
+	M    tests/TestStr.h
+	M    tests/TestSequence.h
+	M    tests/TestFloat32.cc
+	M    tests/TestArray.cc
+	M    tests/TestFloat64.cc
+	M    tests/expr-testsuite/config/unix.exp
+	M    tests/TestFloat64.h
+	M    tests/TestUInt32.cc
+	M    tests/TestGrid.cc
+	M    tests/TestUInt16.cc
+	M    tests/TestGrid.h
+	M    tests/TestCommon.h
+	M    tests/expr-test.cc
+	M    tests/TestStructure.cc
+	M    tests/TestUrl.cc
+	M    tests/TestByte.cc
+	M    tests/TestByte.h
+	M    tests/TestSequence.cc
+	M    tests/TestStr.cc
+	M    tests/README
+	M    tests/TestFloat32.h
+	M    tests/TestArray.h
+	M    tests/TestUInt32.h
+	M    tests/TestUInt16.h
+	M    tests/TestCommon.cc
+
+2007-11-08  James Gallagher <jgallagher at opendap.org>
+
+	Added the intern_data() method as a replacement and fix for/to
+	transfer_data(). This method should correctly handle the types
+	presented by HDF5 like Array of Structure
+
+	M    Structure.h
+	M    Sequence.h
+	M    BaseType.h
+	M    BaseType.cc
+	M    Grid.h
+	M    Structure.cc
+	M    Vector.cc
+	M    Sequence.cc
+	M    Vector.h
+	M    Grid.cc
+	M    unit-tests/HTTPCacheTest.cc
+	M    unit-tests/SequenceTest.cc
+
+2007-11-08  Patrick West <pwest at ucar.edu>
+
+	All characters in the pathname need to match the regular
+	expression. So need to compare the result of the match call in
+	pathname_ok to the length of the path being matched. If not all
+	characters match, then return false. 
+
+	M util.cc
+
+2007-10-31  James Gallagher <jgallagher at opendap.org>
+
+	Added pathname_ok() prototype to util.h and added malloc
+	check to XDRStreamMarshaller.cc
+
+2007-10-30  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a parse error in the pathname sanitizer function.
+
+	M util.cc
+
+2007-10-24  James Gallagher <jgallagher at opendap.org>
+
+	Formatting
+
+2007-09-27  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-09-26  Patrick West <pwest at ucar.edu>
+
+	marshaller test
+	
+	A    unit-tests/marshT.cc
+
+2007-09-24  James Gallagher <jgallagher at opendap.org>
+
+	Applied patch from Patrice to package/ship generated
+	files with source dists.
+
+	M Makefile.am
+
+2007-09-21  James Gallagher <jgallagher at opendap.org>
+
+	Fixed various issues.
+
+2007-08-28  James Gallagher <jgallagher at opendap.org>
+
+	Modified because issues show up in the nightly builds.
+
+	M    XDRUtils.cc
+	M    Vector.cc
+
+2007-08-28  James Gallagher <jgallagher at opendap.org>
+
+	unit-test/Makefile.am: Removed comments that shadowed various
+	unit tests since I think that was checked in by mistake.
+
+2007-08-28  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-08-27  Patrick West <pwest at ucar.edu>
+
+	Added methods to be able to send dap objects to iostream in
+	addition to the methods to send to FILE pointers. Created
+	Marshaller and UnMarshaller classes to pass to serialize and
+	deserialize methods (respectively) to separate out that code from
+	BaseType classes. Created XDRFileMarshaller to serialize into XDR
+	using FILE pointer. Created XDRStreamMarshaller to serialize into
+	XDR using ostream (XDR memory buffer). Created XDRFileUnMarshaller
+	to read from XDR using FILE pointer. Did NOT create
+	XDRStreamUnmarshaller as it didn't seem to be needed. Separated
+	out anything to do with XDR into separate header files and utility
+	class XDRUtils.
+	
+	M    DODSFilter.cc
+	M    Int16.cc
+	M    Int32.h
+	M    Structure.h
+	M    Sequence.h
+	M    Str.h
+	M    configure.ac
+	A    XDRUtils.h
+	A    xdr-datatypes-static.h
+	M    cgi_util.cc
+	A    xdr-datatypes-config.h.in
+	M    dods-datatypes-static.h
+	M    Error.cc
+	A    UnMarshaller.h
+	M    Int16.h
+	M    DAS.h
+	M    DDS.cc
+	A    XDRFileMarshaller.h
+	M    tests/expr-test.cc
+	M    Array.cc
+	M    BaseType.h
+	M    Float64.h
+	M    UInt16.cc
+	M    AlarmHandler.h
+	A    Marshaller.h
+	M    Byte.cc
+	M    Byte.h
+	M    DDS.h
+	M    BaseType.cc
+	A    XDRUtils.cc
+	M    Makefile.am
+	M    Constructor.h
+	M    Error.h
+	M    Int32.cc
+	M    DODSFilter.h
+	M    DataDDS.cc
+	M    Float32.cc
+	M    util.h
+	M    AttrTable.cc
+	M    Grid.h
+	M    Structure.cc
+	M    cgi_util.h
+	M    Vector.cc
+	M    Str.cc
+	M    Sequence.cc
+	A    XDRFileUnMarshaller.cc
+	M    Float32.h
+	A    XDRFileUnMarshaller.h
+	M    AttrTable.h
+	M    Constructor.cc
+	M    UInt32.h
+	A    XDRStreamMarshaller.h
+	M    dods-datatypes-config.h.in
+	M    Vector.h
+	M    DAS.cc
+	M    util.cc
+	M    Float64.cc
+	M    UInt32.cc
+	A    XDRStreamMarshaller.cc
+	M    Grid.cc
+	M    Connect.cc
+	M    unit-tests/Makefile.am
+	A    XDRFileMarshaller.cc
+	M    Array.h
+	M    UInt16.h
+
+2007-08-24  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Updated fortify targets
+
+2007-08-22  Patrick West <pwest at ucar.edu>
+
+	Functionality of Passive classes was passed to their parent
+	classes. Added set_value(vector<type>) methods to Vector. Added
+	default read method to Structure that iterates through vars and
+	calls read, just as PassiveStructure did. Removed Passive classes
+	from Makefile.
+	
+	D    PassiveUrl.cc
+	D    PassiveInt16.h
+	M    Structure.h
+	D    PassiveStr.cc
+	D    PassiveStr.h
+	D    PassiveUInt16.h
+	D    PassiveInt16.cc
+	D    PassiveByte.cc
+	D    PassiveFloat32.h
+	D    PassiveStructure.cc
+	D    PassiveStructure.h
+	D    PassiveUInt32.cc
+	D    PassiveFloat32.cc
+	D    PassiveArray.cc
+	M    Makefile.am
+	D    PassiveInt32.cc
+	M    Structure.cc
+	M    Vector.cc
+	D    PassiveFloat64.cc
+	D    PassiveArray.h
+	D    PassiveInt32.h
+	D    PassiveUrl.h
+	D    PassiveByte.h
+	M    Vector.h
+	D    PassiveFloat64.h
+	D    PassiveUInt32.h
+	D    PassiveUInt16.cc
+
+2007-08-22  James Gallagher <jgallagher at opendap.org>
+
+	Str.h: Changed the size of max_str_len from 32767 to 65535
+	(DODS_USHORT_INT-1) because 32k was not big enough for the
+	AURA HDF5 data files. See ticket 962 and 956.
+
+2007-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Response.h: Made the new 'status' parameter have a default
+	value of '0' so that specializations do not need modification
+	if they know nothing about the new param. This change was
+	made for PipeResponse.h - arguably something that should be
+	removed, but it's there as long as we support the CGI server.
+	StdinResponse.h: Removed the second param to teh ctor since
+	it is no longer needed.
+
+2007-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Removed -Werror since on OS/X and RHEL3
+	the grammar files generate warnings about unused
+	variables.
+
+2007-08-20  James Gallagher <jgallagher at opendap.org>
+
+	Removed warnings about strict aliasing rules by adding
+	Vector::void *value() and replacing calls to buf2_val()
+	with it. See ticket #941.
+
+2007-08-20  James Gallagher <jgallagher at opendap.org>
+
+	Updates to a number of the doxygen comments.
+
+2007-08-20  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a problem in util.cc where the sense of size_ok()
+	was backwards! Also rewrote parts of ce_functions.cc so
+	that value() was used in place of buf2val() which is far
+	better from a type-safety standpoint and removes a number
+	of warnings about strict aliasing of types. Also fixed
+	error in Error.cc where 'undefined_error' was used where
+	zero (0) should have been used. Modified RValue"build_btp_args()
+	so that the size of the arg list is added to the malformed
+	args message.
+
+2007-08-18  James Gallagher <jgallagher at opendap.org>
+
+	Patch from Patrice Dumas that fixes the distclean target and
+	repairs the spec file now that the generated grammar files are no
+	longer included checked into subversion.
+
+	M    libdap.spec
+	M    Makefile.am
+
+2007-08-17  James Gallagher <jgallagher at opendap.org>
+
+	Added a target so that the generated grammar files are copied to a
+	directory so that they don't _have_ to be built using bison/flex.
+
+	M    INSTALL
+	M    Makefile.am
+
+2007-08-17  James Gallagher <jgallagher at opendap.org>
+
+	I removed the generated grammar files from svn (but put copies in
+	the new 'grammarfile' subdirectory). Now, svn checkouts need bison
+	and flex to build.
+
+	D    lex.gse_.cc
+	D    lex.dds.cc
+	D    expr.tab.h
+	D    dds.tab.h
+	D    ce_expr.tab.cc
+	M    GNU/GNURegex.cc
+	D    lex.Error.cc
+	M    Makefile.am
+	D    ce_expr.tab.h
+	D    Error.tab.h
+	A    grammarfiles
+	A    grammarfiles/ce_expr.tab.h
+	A    grammarfiles/lex.das.cc
+	A    grammarfiles/Error.tab.cc
+	A    grammarfiles/Error.tab.h
+	A    grammarfiles/lex.dds.cc
+	A    grammarfiles/lex.gse_.cc
+	A    grammarfiles/lex.ce_expr.cc
+	A    grammarfiles/das.tab.cc
+	A    grammarfiles/das.tab.h
+	A    grammarfiles/dds.tab.cc
+	A    grammarfiles/lex.Error.cc
+	A    grammarfiles/dds.tab.h
+	A    grammarfiles/gse.tab.cc
+	A    grammarfiles/gse.tab.h
+	A    grammarfiles/expr.tab.h
+	A    grammarfiles/ce_expr.tab.cc
+	D    lex.das.cc
+	D    lex.ce_expr.cc
+	D    das.tab.h
+	D    das.tab.cc
+	D    dds.tab.cc
+	D    Error.tab.cc
+	D    gse.tab.cc
+	D    gse.tab.h
+
+2007-08-15  James Gallagher <jgallagher at opendap.org>
+
+	Fixes
+
+2007-08-15  James Gallagher <jgallagher at opendap.org>
+
+	Fixes
+
+	M    lex.gse_.cc
+	M    lex.dds.cc
+	M    dds.tab.h
+	M    lex.Error.cc
+	M    Makefile.am
+	M    util.h
+	M    lex.das.cc
+	M    lex.ce_expr.cc
+	M    util.cc
+	M    dds.tab.cc
+	M    GeoConstraint.cc
+
+2007-08-15  James Gallagher <jgallagher at opendap.org>
+
+	Patch to add HTTP response status to the Response object and to fix the
+	spelling of getdap (it was geturl in places). From Darren Hardy.
+
+	M    HTTPResponse.h
+	M    lex.gse_.cc
+	M    lex.dds.cc
+	M    Response.h
+	M    dds.tab.h
+	M    lex.Error.cc
+	M    HTTPCacheResponse.h
+	M    HTTPConnect.cc
+	M    lex.das.cc
+	M    getdap.cc
+	M    lex.ce_expr.cc
+	M    AISMerge.cc
+	M    dds.tab.cc
+	M    StdinResponse.h
+
+2007-08-13  James Gallagher <jgallagher at opendap.org>
+
+	Modified as part of refactoring.
+
+	M    RValue.cc
+	M    cgi_util.cc
+	M    Error.cc
+	M    ConstraintEvaluator.cc
+	M    DDS.cc
+	M    Array.cc
+	M    Makefile.am
+	M    Error.h
+	M    HTTPCache.cc
+	M    DataDDS.cc
+	M    dds.lex
+	M    DAS.cc
+	M    util.cc
+	M    Connect.cc
+	M    dods-limits.h
+	M    dds.y
+	M    Array.h
+	M    ce_expr.lex
+
+2007-08-09  James Gallagher <jgallagher at opendap.org>
+
+	Applied the hyrex_redirect patch from NASA. This code now detects and
+	records the value of a Location: HTTP header.
+
+	M    HTTPConnect.cc
+
+2007-08-07  Patrick West <pwest at ucar.edu>
+
+	OPeNDAPDir and OPeNDAPFile not needed in libdap, specific to cedar
+	project. M Makefile.am
+
+2007-08-07  Patrick West <pwest at ucar.edu>
+
+	Not needed in libdap, specific to cedar project.
+	
+	A    http://scm.opendap.org:8090/svn/trunk/cedar-handler/OPeNDAPFile.h
+	D    http://scm.opendap.org:8090/svn/trunk/libdap/OPeNDAPFile.h
+
+2007-08-07  Patrick West <pwest at ucar.edu>
+
+	Not needed in libdap, specific to cedar project.
+	
+	A    http://scm.opendap.org:8090/svn/trunk/cedar-handler/OPeNDAPFile.cc
+	D    http://scm.opendap.org:8090/svn/trunk/libdap/OPeNDAPFile.cc
+
+2007-08-07  Patrick West <pwest at ucar.edu>
+
+	Not needed in libdap, specific to cedar project.
+	
+	A    http://scm.opendap.org:8090/svn/trunk/cedar-handler/OPeNDAPDir.cc
+	D    http://scm.opendap.org:8090/svn/trunk/libdap/OPeNDAPDir.cc
+
+2007-08-07  Patrick West <pwest at ucar.edu>
+
+	Not needed in libdap, specific to cedar project.
+	A    http://scm.opendap.org:8090/svn/trunk/cedar-handler/OPeNDAPDir.h
+	D    http://scm.opendap.org:8090/svn/trunk/libdap/OPeNDAPDir.h
+
+2007-06-27  James Gallagher <jgallagher at opendap.org>
+
+	unit-tests/Makefile.am: Added -I$(topsrcdir) to the CPPFLAGS for
+	distcheck.
+
+2007-06-27  James Gallagher <jgallagher at opendap.org>
+
+	tests/Makefile.am: Added -I$(topsrcdir) to the CPPFLAGS for
+	distcheck.
+
+2007-06-27  James Gallagher <jgallagher at opendap.org>
+
+	Updated for version 3.7.8
+
+	M    INSTALL
+	M    README
+	M    NEWS
+
+2007-06-26  James Gallagher <jgallagher at opendap.org>
+
+	Updates for version 3.7.8 - still need to do README and INSTALL.
+
+	M    DODSFilter.cc
+	M    configure.ac
+	M    ChangeLog
+	M    libdap.spec
+	M    NEWS
+
+2007-06-26  James Gallagher <jgallagher at opendap.org>
+
+	Replaced unidata support email with the opendap-tech list address.
+
+2007-06-26  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-06-25  James Gallagher <jgallagher at opendap.org>
+
+	Added.
+
+	AM   gl/config.charset
+
+2007-06-25  James Gallagher <jgallagher at opendap.org>
+
+	Added files from the gnulib update.
+
+	A    gl/m4/wint_t.m4
+	A    gl/m4/wchar.m4
+	A    gl/m4/localcharset.m4
+	A    gl/m4/ulonglong.m4
+	A    gl/m4/stdint.m4
+	A    gl/m4/gnulib-common.m4
+	A    gl/m4/wctype.m4
+	A    gl/m4/longlong.m4
+	A    gl/m4/include_next.m4
+	A    gl/m4/glibc21.m4
+	AM   gl/localcharset.c
+	A    gl/ref-del.sed
+	AM   gl/localcharset.h
+	A    gl/ref-del.sin
+	A    gl/ref-add.sed
+	AM   gl/wchar_.h
+	A    gl/ref-add.sin
+	AM   gl/stdint_.h
+	AM   gl/wctype_.h
+
+2007-06-22  James Gallagher <jgallagher at opendap.org>
+
+	Updated gnulib and fixed a memory problem in the GNURegex class
+	(which should really be renamed to DAPRegex, but that would break
+	other code). The problem was that to use the gnulib regex code the
+	config.h header has to be included and the gl subdir must be
+	searched. I moved the declaration of the regex_t field of Regex
+	into the implementation file to avoid having config.h in a header
+	that is installed in <prefix>/include. This fixes ticket #953
+	which first showed up in libnc-dap.
+
+	M    tests/Makefile.am
+	M    GNU/GNURegex.cc
+	M    GNU/GNURegex.h
+	M    Makefile.am
+	M    regex_test.cc
+	M    gl/alloca_.h
+	M    gl/m4/regex.m4
+	M    gl/m4/gnulib-comp.m4
+	M    gl/m4/ssize_t.m4
+	M    gl/m4/gnulib-cache.m4
+	M    gl/m4/onceonly_2_57.m4
+	M    gl/m4/codeset.m4
+	M    gl/m4/alloca.m4
+	M    gl/m4/extensions.m4
+	M    gl/regex_internal.c
+	M    gl/malloc.c
+	M    gl/stdbool_.h
+	M    gl/regex.c
+	M    gl/regex_internal.h
+	M    gl/regex.h
+	M    gl/regexec.c
+	M    gl/Makefile.am
+	M    gl/gettext.h
+	M    gl/alloca.c
+	M    gl/regcomp.c
+	M    util.cc
+	M    Operators.h
+	M    unit-tests/RegexTest.cc
+	M    unit-tests/Makefile.am
+
+2007-06-21  James Gallagher <jgallagher at opendap.org>
+
+	Reverted to the old version of get_attr() for release.
+
+	M    AttrTable.cc
+
+2007-06-21  James Gallagher <jgallagher at opendap.org>
+
+	escaping.cc: one last call to size replaced.
+
+2007-06-21  James Gallagher <jgallagher at opendap.org>
+
+	escaping.cc: Replaced calls to string::size() with ones to
+	string::length(). They return the same information, but it's
+	cleaner to use the same method everywhere
+
+2007-06-19  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a problem in save_raw_http_header() where a header from an
+	old server (terminated by a newline but no return) caused a read
+	violation when the header was empty.
+
+	M    HTTPConnect.cc
+
+2007-06-08  James Gallagher <jgallagher at opendap.org>
+
+	Spelling in comments and strings
+
+	M    AlarmHandler.h
+	M    GeoConstraint.h
+	M    expr.h
+	M    RCReader.h
+
+2007-06-04  James Gallagher <jgallagher at opendap.org>
+
+	Updated comments.
+
+	M    lex.gse_.cc
+	M    AISResources.cc
+	M    configure.ac
+	M    cgi_util.cc
+	M    lex.dds.cc
+	M    ChangeLog
+	M    ConstraintEvaluator.cc
+	M    Array.cc
+	M    ce_expr.tab.cc
+	M    Byte.cc
+	M    lex.Error.cc
+	M    ce_expr.tab.h
+	M    Error.tab.h
+	M    AttrTable.cc
+	M    lex.das.cc
+	M    lex.ce_expr.cc
+	M    das.tab.h
+	M    ce_functions.cc
+	M    Constructor.cc
+	M    das.tab.cc
+	M    ArrayGeoConstraint.cc
+	M    Connect.cc
+	M    Error.tab.cc
+	M    Clause.cc
+	M    doxy.conf
+	M    gse.tab.cc
+	M    gse.tab.h
+
+2007-05-25  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-05-24  Patrick West <pwest at ucar.edu>
+
+	Standard location of PackageMaker command line app.
+	
+	M    Makefile.am
+
+2007-05-24  Patrick West <pwest at ucar.edu>
+
+	Ability to build .pkg file from the Makefile instead of running
+	PackageMaker GUI.
+	
+	A    OSX_Resources/Info.plist
+	A    OSX_Resources/Description.plist
+	M    Makefile.am
+
+2007-05-18  James Gallagher <jgallagher at opendap.org>
+
+	Updated pkg.m4 macros
+
+	M    pkg.m4
+
+2007-05-17  James Gallagher <jgallagher at opendap.org>
+
+	Fixed typos in grammar files.
+
+	M    Error.lex
+	M    gse.lex
+	M    gse.y
+	M    ce_expr.y
+	M    Error.y
+	M    dds.lex
+	M    das.lex
+	M    das.y
+	M    ce_expr.lex
+
+2007-05-17  James Gallagher <jgallagher at opendap.org>
+
+	Fixed typos in libdap headers.
+
+	M    DDXParser.h
+	M    Sequence.h
+	M    SignalHandler.h
+	M    debug.h
+	M    escaping.h
+	M    Connect.h
+	M    ce_functions.h
+	M    SignalHandlerRegisteredErr.h
+	M    gse_parser.h
+	M    DDS.h
+	M    ArrayGeoConstraint.h
+	M    GeoConstraint.h
+	M    HTTPCacheResponse.h
+	M    Error.h
+	M    AISResources.h
+	M    PipeResponse.h
+	M    util.h
+	M    Grid.h
+	M    AttrTable.h
+	M    PassiveUrl.h
+	M    Url.h
+	M    Clause.h
+	M    Operators.h
+	M    HTTPConnect.h
+	M    StdinResponse.h
+	M    Array.h
+	M    UInt16.h
+
+2007-05-17  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-05-16  James Gallagher <jgallagher at opendap.org>
+
+	Added pkg.m4 to conf so build from svn will work on machines w/o
+	pkg-config. Updated comments.
+
+	A    conf/pkg.m4
+	M    Makefile.am
+	M    Constructor.h
+	M    unit-tests/Makefile.am
+
+2007-05-14  James Gallagher <jgallagher at opendap.org>
+
+	Removed the html docs from svn; RPM now builds a 'doc' package.
+
+	D    docs/html.tar.gz
+	M    libdap.spec
+
+2007-05-14  James Gallagher <jgallagher at opendap.org>
+
+	Resolved conflicted state of AISDatabaseParser.h
+
+2007-05-14  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-05-13  James Gallagher <jgallagher at opendap.org>
+
+	Patrice Dumas' changes to dods-datatypes.h - Now the header uses
+	the C99 types unless the stdint.h header is not present.
+
+	D    dods-datatypes.h.in
+	M    configure.ac
+	A    dods-datatypes-static.h
+	M    conf/acinclude.m4
+	M    Makefile.am
+	A    dods-datatypes-config.h.in
+
+2007-05-13  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-05-12  James Gallagher <jgallagher at opendap.org>
+
+	Added Patrice Dumas' pkgconf patches
+
+	M    dods-datatypes.h.in
+	M    configure.ac
+	AM   conf/compile
+	M    conf/libdap.m4
+	A    conf/check_zlib.m4
+	M    libdap.spec
+	M    BaseType.cc
+	M    Makefile.am
+	M    Structure.cc
+	A    libdapclient.pc.in
+	A    libdap.pc.in
+	A    libdapserver.pc.in
+	M    dap-config.in
+
+2007-05-10  James Gallagher <jgallagher at opendap.org>
+
+	Comments & Strings
+
+	M    BaseType.h
+	M    BaseType.cc
+	M    Float32.cc
+	M    AISDatabaseParser.h
+	M    Float32.h
+	M    AISDatabaseParser.cc
+	M    AISConnect.h
+
+2007-05-02  James Gallagher <jgallagher at opendap.org>
+
+	Updates for 3.7.7
+
+	M    configure.ac
+	M    ChangeLog
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+2007-03-29  James Gallagher <jgallagher at opendap.org>
+
+	Added definition of trunc() for Solaris < 10.
+
+2007-03-29  James Gallagher <jgallagher at opendap.org>
+
+	Added definition of trunc() for Solaris < 10.
+
+2007-03-28  James Gallagher <jgallagher at opendap.org>
+
+	All files (.cc and .h) formatted using astyle. I found one
+	introduced error and one issue with the strings passed to the
+	Error exceptions.
+
+2007-03-27  James Gallagher <jgallagher at opendap.org>
+
+	Minor formatting changes.
+
+	M    Byte.cc
+	M    unit-tests/HTTPConnectTest.cc
+
+2007-03-27  James Gallagher <jgallagher at opendap.org>
+
+	Wrapped the calls to ConstraitEvaluator::eval() in a compile-time
+	constant (EVAL) which defaults to zero (so the calls are not made
+	for non-sequence types). Also wrapped the server-side compression
+	code in a compile-time constant COMPRESSION_FOR_SERVER3 which
+	is also zero by default. Lastly, added DapObj constructor init
+	for BAS, DDS and BaseTyep constructors.
+
+2007-03-26  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc, unit-tests/DDSTest.cc: Fixed ticket # 708. The dataBLOB
+	element now gets an empty href attribute.
+
+2007-03-26  James Gallagher <jgallagher at opendap.org>
+
+	README: Added a note about thread-saftey.
+
+2007-03-26  James Gallagher <jgallagher at opendap.org>
+
+	Patch from Patrice Dumas: Fix the order of library builds! This
+	closes #880.
+
+2007-03-23  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the help/version/args messages for the server-side functions
+	so that they are somewhat rational. There is a ticket to develop a
+	'capabilities' response for Hyrax and that should replace these
+	messages.
+
+	M    ce_functions.cc
+	M    GeoConstraint.cc
+
+2007-03-23  James Gallagher <jgallagher at opendap.org>
+
+	Updated test for changes to the 'wrong number of args" messages
+	from the first set of server-side functions.
+
+	M    tests/expr-testsuite/data.zz0
+	M    tests/expr-testsuite/data.z0
+
+2007-03-12  James Gallagher <jgallagher at opendap.org>
+
+	Resolved signed/unsigned compares
+
+	M    Vector.cc
+
+2007-03-12  James Gallagher <jgallagher at opendap.org>
+
+	Removed some int/unsigned compares
+
+	M    tests/TestArray.cc
+
+2007-03-12  James Gallagher <jgallagher at opendap.org>
+
+	Updated notes and version information for 3.7.6.
+
+	M    configure.ac
+	M    README.AIS
+	M    ChangeLog
+	M    INSTALL
+	M    README.dodsrc
+	M    libdap.spec
+	M    README
+	M    NEWS
+
+2007-03-12  James Gallagher <jgallagher at opendap.org>
+
+	Fixed some errors in the unit tests, one bug in the RCReader when
+	reading the VALIDATE_SSL keyword. Updated the parser stuff.
+
+	M    lex.dds.cc
+	M    RCReader.cc
+	M    lex.das.cc
+	M    das.tab.h
+	M    das.y
+	M    das.tab.cc
+	M    unit-tests/RegexTest.cc
+	M    unit-tests/RCReaderTest.cc
+
+2007-03-11  James Gallagher <jgallagher at opendap.org>
+
+	Removed DODS_DEBUG
+
+	M    ce_functions.cc
+
+2007-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Fixed ticket #857: The linear_scale function was crashing because
+	of a failure to test that a parent variable existed before getting
+	its type. I also fixed an unrelated problem where double quotes
+	around an attribute value broke the string --> double code and
+	added a new feature where files which omit the y intercept because
+	it's zero do not return an error but instead use 0.0 as a default.
+	Finally, the error message text was improved.
+
+	M ce_functions.cc
+
+2007-02-16  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: removed some errant tabs.
+
+2007-02-16  James Gallagher <jgallagher at opendap.org>
+
+	dap-config.in: fixed #816; --help was wrong.
+
+2007-02-16  James Gallagher <jgallagher at opendap.org>
+
+	I removed throw(Error) from the method declarations in the header
+	and impl. files. I removed the include of Error.h from the header.
+	I added the include using "" in the impl. This should fix the
+	ml-structs build error that started on 1/7/07 when Rob made some
+	changes for the win32 build.
+
+	M    GNU/GNURegex.cc
+	M    GNU/GNURegex.h
+
+2007-02-09  James Gallagher <jgallagher at opendap.org>
+
+	Updated for version 3.7.5
+
+	M    docs/html.tar.gz
+	M    libdap.spec
+
+2007-02-07  James Gallagher <jgallagher at opendap.org>
+
+	main_page.doxygen: Updated the version number to 3.7.5.
+
+2007-02-07  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc, GeoConstraint.cc, HTTPConnect.cc: Formatting
+	lex.dds,cc, les.gse_.cc: Regenerated.
+
+2007-02-05  James Gallagher <jgallagher at opendap.org>
+
+	data.z2-7: updated the data values for two and three
+	dimensional arrays given the new code in GeoConstraint.
+
+2007-02-05  James Gallagher <jgallagher at opendap.org>
+
+	expr-test.cc, TestArray.cc: formatting changes
+
+2007-02-05  James Gallagher <jgallagher at opendap.org>
+
+	AISMergeTest.cc, HTTPConnectTest.cc: Fixed errors that have
+	cropped upover time, esp. as Server4 has become the default.
+
+2007-02-02  Patrick West <pwest at ucar.edu>
+
+	Added information about PATH and LD_LIBRARY_PATH.
+	M    INSTALL
+
+2007-01-30  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Added support for missing values to linear_scale.
+	Now, if missing_value is present (in the attributes or given as a
+	parameter) values which match will not be scaled.
+
+2007-01-29  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Added a new version of get
+	get_attribute_double_value() that takes a vector of strings
+	and returns the value of the first attribute found in that
+	vector. Also cleaned up the memory use in the linear_scale
+	function so that function no longer leaks the new template
+	variable. This was part of the fix for #660 (See also the
+	checkin for Clause.cc from today).
+
+2007-01-29  James Gallagher <jgallagher at opendap.org>
+
+	Clause.cc: Added a call to set_read_p(true) in Clause::value
+	so that handlers' read() methods will not try to 'read over'
+	the values inserted to the variables by a CE function.
+
+2007-01-29  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint.cc: Minor formatting fix.
+
+2007-01-26  James Gallagher <jgallagher at opendap.org>
+
+	Updates to comments.
+
+2007-01-26  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Fixed ticket 659 where array data was not
+	read when a relational constraint was not used. The bug
+	crept in while making another fix (for the HDF4 handler).
+	The problem was that Grid::read() was used to read the maps
+	(bit not the Array) and as a side effect read_p was set for
+	the entire Grid, not just the maps. I reset the Array read_p
+	value; see ce_functions.cc
+
+2007-01-21  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Synch win32 Makefile wrt recent libdap code changes
+
+2007-01-12  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-01-11  Patrick West <pwest at ucar.edu>
+
+	comment headers updated with correct information and Copyright.
+	M    DapObj.h
+	M    DapIndent.h
+	M    DapIndent.cc
+
+2007-01-11  Patrick West <pwest at ucar.edu>
+
+	Added dump method to the BaseType classes, DAS, DDS, DataDDS. To
+	do this, created a DapObj base class for all of these to inherit
+	from (directly or indirectly) and in the DapObj class is the
+	operator<< method. This will aid in debugging. Created an
+	indentation classes to help with dumping objects.
+
+	M    Int16.cc
+	M    Int32.h
+	M    Structure.h
+	M    Sequence.h
+	M    Str.h
+	M    Int16.h
+	M    DAS.h
+	M    DDS.cc
+	M    BaseType.h
+	M    Array.cc
+	M    Float64.h
+	M    UInt16.cc
+	M    Byte.cc
+	M    Byte.h
+	M    DataDDS.h
+	M    BaseType.cc
+	M    DDS.h
+	M    Makefile.am
+	M    Constructor.h
+	M    Int32.cc
+	A    DapObj.h
+	M    DataDDS.cc
+	A    DapIndent.h
+	M    Float32.cc
+	M    AttrTable.cc
+	M    Grid.h
+	M    Structure.cc
+	M    Vector.cc
+	M    Str.cc
+	M    Sequence.cc
+	M    Float32.h
+	M    AttrTable.h
+	M    Constructor.cc
+	M    UInt32.h
+	M    Vector.h
+	M    DAS.cc
+	M    Float64.cc
+	M    UInt32.cc
+	M    Grid.cc
+	A    DapIndent.cc
+	M    Array.h
+	M    UInt16.h
+
+2007-01-08  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-01-07  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Last Makefile tweeks to automate pkging for win32
+
+2007-01-07  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Add doc's that accompany win32 libdap releases to the repository
+
+2007-01-07  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2007-01-06  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Prevent "error.h" from getting picked up during ml-structs build
+	under win32 (that's error.h with a little "e").
+
+2007-01-06  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Removed VC++-6.x-specific ifdefs.  6.x not supported any longer anyway
+	as some old template-related hacks are no longer in the code.
+
+2007-01-06  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Add sample code for compiling/linking with libdap under win32
+
+2007-01-03  James Gallagher <jgallagher at opendap.org>
+
+	Vector.h: Removed 'Vector::' prefix in a bunch on accessors; these
+	caused g++ 4.1.1 to gag. Fix from Rob Cermak.
+
+2007-01-02  Patrick West <pwest at ucar.edu>
+
+	3.7.4 release
+	M    configure.ac
+	M    ChangeLog
+	M    libdap.spec
+	M    NEWS
+
+2006-12-31  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Synchronize select win32 Makefiles to build/pkg the same way
+
+2006-12-20  James Gallagher <jgallagher at opendap.org>
+
+	Added Structure::transfer_data() so that a handler can simulate the
+	actions of serialize() without actually sending the data.
+	M    Structure.h
+	M    Structure.cc
+	M    Sequence.cc
+
+2006-12-20  James Gallagher <jgallagher at opendap.org>
+
+	DDXParser.cc: Fixed an error introduced by the Eclipse
+	code formatter.
+
+2006-12-19  James Gallagher <jgallagher at opendap.org>
+
+	DDXParser.cc, DODSFilter.cc: Formatting changes
+
+2006-12-13  James Gallagher <jgallagher at opendap.org>
+
+	Updated libdap.pmproj to/for version 3.7.3
+
+2006-12-10  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Change of pkging location simplifies user builds
+
+2006-12-06  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Set LIBDAP_ROOT appropriately in the MS Windows case
+
+2006-12-06  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Remove external .manifest as an issue by internalizing into binaries
+
+2006-12-05  James Gallagher <jgallagher at opendap.org>
+
+	getdap.cc: Fixed a bug where the constraint expression passed
+	in using -c was not used when getting either a DDS or a DDX
+	(but it was used when getting data).
+
+2006-12-05  James Gallagher <jgallagher at opendap.org>
+
+	Added comments to DDS and DataDDS about when it's OK
+	to delete their type factories (only when you're done
+	using the DDS or if you're about to switch to a new
+	factory).
+
+2006-12-05  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Require *.exe.manifest to accompany .exe's if they are to run.  I
+	guess I don't yet know why these are generated
+
+2006-12-05  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Improve win32 exe linking
+
+2006-12-03  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Just libdap for win32 makefile tweeks
+
+2006-12-02  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	New Makefile code to gen exports for dll's automatically
+
+2006-12-02  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Module export def's no longer required.  Constructed at build time.
+
+2006-11-25  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Automate module export definition regeneration for dll's (hard)
+
+2006-11-24  James Gallagher <jgallagher at opendap.org>
+
+	Updated OSX ReadME.txt for 3.7.3
+
+2006-11-24  James Gallagher <jgallagher at opendap.org>
+
+	Documentation and build file update for the 3.7.3 release.
+
+2006-11-24  James Gallagher <jgallagher at opendap.org>
+
+	AISMergeTest.cc: UPdated baseline to account for new fnoc1.das
+	file in data/nc.
+
+2006-11-22  James Gallagher <jgallagher at opendap.org>
+
+	Updated ChangeLog
+
+2006-11-21  James Gallagher <jgallagher at opendap.org>
+
+	Fixed unescattr() in escaping.cc. Now the code works when there
+	are several escaped characters or when the escapes are escaped.
+	That is, this version can be used by the libnc-dap library and the
+	result is code that passes all the nc_test tests for char and text
+	attributes.
+
+2006-11-12  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Make win32 pkging dir locaton slightly more flexible
+
+2006-11-12  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Update module export definitions for dll versions of the Core
+
+2006-11-11  James Gallagher <jgallagher at opendap.org>
+
+	Removed errant 3.7.3 sub directory.
+
+2006-11-07  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnectTest.cc: Turned off debugging
+
+2006-11-07  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnectTest.cc: Fixed up the tests for headers once again...
+
+2006-11-07  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-11-06  James Gallagher <jgallagher at opendap.org>
+
+	configure.ac: I moved the DAP Protocol setting up where
+	it's likely to be updated and not glossed over.
+
+2006-11-06  James Gallagher <jgallagher at opendap.org>
+
+	getdap.cc: getdap now reports the protocol version in addition
+	to the server version.
+
+2006-11-06  James Gallagher <jgallagher at opendap.org>
+
+	Added tests for the new parameter VALIDATE_SSL
+
+2006-11-06  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnect.cc, RCReader: The .dodsrc file now supports a
+	VALIDATE_SSL option which controls libcurl's validation of SSL
+	hosts and certificates. If this is set (the default), certificates
+	must be signed by a recognized Certificate Authority and hosts
+	must be properly named. Clear (set to zero) to get the old
+	behavior from libcurl which does not perform this validation.
+
+2006-11-03  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnect.cc: Modified so that gzip and compress are also
+	accepted encodings.
+
+2006-11-02  Patrick West <pwest at ucar.edu>
+
+	Removed DODSResponseObject from the Makefile after removing the
+	file from libdap. DAS and DDS no longer inherit from
+	DODSResponseObject. New classes representing DAS, DDS and DataDDS
+	were created in BES. M Makefile.am
+
+2006-11-02  Patrick West <pwest at ucar.edu>
+
+	Moved DODSResponseObject.h to the BES, naming it
+	BESResponseObject. Created in BES three classes to represent DAS,
+	DDS, and DataDDS. D DODSResponseObject.h M DAS.h M DDS.h M DDS.cc
+
+2006-10-30  James Gallagher <jgallagher at opendap.org>
+
+	expr-tests for geogrid() and geoarray(): Fixed the tests so they
+	work using the new notation which passed geo points using lat,lon
+	as opposed to lon,lat.
+
+2006-10-30  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Removed the debug flags from AM_CXXFLAGS. -Werror
+	really breaks the builds because of issues in the bison/flex
+	code.
+
+2006-10-28  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	Constructor.cc, ArrayGeoConstructor.cc: Removed DODS_DEBUG
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	DDSTest.cc: Removed compiler warnings.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnect.cc: Fixed a bug in save_raw_http_headers() where the
+	test for the \r\n line terminator was broken (tested nmemb-1 instead
+	of nmemb-2.
+	Makefile.am: added a target for test coverage and added the debugging
+	options to CXXFLAGS by default. Make sure to back this out before
+	release
+	Unit Tests: Fixed up warnings in the unit tests
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	DDS.h: Added declarations for the new transfer_attributes()
+	methods
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	Constructor.h: Added declarations for the new transfer_attributes()
+	methods.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	BaseType.h: Added a little text to the ptr_duplicate() documentation.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	HTTPCache.cc: Changed the way the mutex which is used to protect
+	the various methods is initialized.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint.cc: Fixed two warnings, one about using a prefix
+	operator with modulus and assignment back to the same variable and
+	the other about field initialization order.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	DODSFilter.cc: Fixed the broken definition of send_blob(),
+	not that it matters...
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc: I removed the second attempt at transfer_attributes and
+	started on a third. This one seems to work much better; see the
+	tests in DDSTest.cc. This version takes the _dim attributes from
+	the hdf4 server and bundles them with a Grid Map or puts them in
+	a sub-container for an Array. This should not break libnc-dap while
+	still preserving all the attribute data.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	Constructor: Added code to merge attributes into a constructor.
+	This method is called from DDS.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Removed unused parameters.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	ArrayGeoConstraint: Fixed a warning where one version of the
+	constructor was not using all of its parameters.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	ArrayGeoConstraintTest: added
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	DDSTest.cc, Makefile.am: Updated with tests for
+	DDS::transfer_attributes.
+
+2006-10-27  James Gallagher <jgallagher at opendap.org>
+
+	Added test data for DDS::transfer_attributes new new version.
+
+2006-10-24  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnect.cc: Removed debugging.
+
+2006-10-24  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc: Removed the 'sub table' code from transfer_attributes().
+	getdap.cc: Added -X option to build the DDX on the client to simplify
+	debugging (e.g., ticket 480)
+
+2006-10-24  James Gallagher <jgallagher at opendap.org>
+
+	Massive removal of exception qualifiers/declarations. I've left
+	only the exception declarations in RCReader (which declare that
+	no exceptions are thrown) and those for constructors. In
+	HTTPConnect.cc:save_raw_http_headers() fixed a bug where headers
+	were assumed to have \r\n terminators. That is true only for new
+	servers. See ticket #631 for more information.
+
+2006-10-24  James Gallagher <jgallagher at opendap.org>
+
+	cgi_util, DODSFilter: Made many params & methods const
+
+2006-10-23  James Gallagher <jgallagher at opendap.org>
+
+	Fixed AISDatabaseParser.cc
+
+2006-10-23  James Gallagher <jgallagher at opendap.org>
+
+	AISDatabaseParser.cc: Replaced calls to getLineNumber and
+	xmlSAX2GetLineNumber with calls to one or the other depending on
+	the library version. In some places the SAX2 API was used
+	exclusively, in others the old API was used. The changes mean the
+	new API will always be used OR the old API will always be used,
+	depending on library version.
+
+2006-10-23  James Gallagher <jgallagher at opendap.org>
+
+	DDXParser.cc: I put the call to xml2's getLinNumber() Back in the
+	code since older distros don't have the newer library.
+
+2006-10-20  James Gallagher <jgallagher at opendap.org>
+
+	Closed some tickets for the server-side functions and added
+	the version function.
+
+2006-10-20  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for ticket 616: I added code to GeoConstraint that checks
+	the bounding box to make sure it includes data and returns an
+	Error if it does not. Also, the order of the bounding box lat and
+	lon were switched to fit more with practice. The GeoConstraint
+	method arguments were no changes, only the order of lat and lon
+	passed to the geogrid() and geoarray() functions.
+
+2006-10-20  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	Data for geoarray tests added.
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	Baseline data for geoarray tests added.
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	Tests for geoarray: Added
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	Added geoarray() which required changes to GeoConstraint and
+	GridGeoConstraint (I created GridGeoConstraint and made
+	GeoConstraint abstract). ce_functions.cc was also modified.
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	ArrayGeoConstraint.cc: Added
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	ArrayGeoConstraint.h: Added
+
+2006-10-19  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-18  James Gallagher <jgallagher at opendap.org>
+
+	Updated baseline for text.z3.exp (data.z3) after fixing
+	GeoConstraint::find_latitude_indeces().
+
+2006-10-18  James Gallagher <jgallagher at opendap.org>
+
+	Added data.61a-d
+
+2006-10-18  James Gallagher <jgallagher at opendap.org>
+
+	GridGeoConstraintTest: Updated with a new test for
+	find_latitude_indeces.
+
+2006-10-18  James Gallagher <jgallagher at opendap.org>
+
+	Updated the data.z? files given that the range selection behavior in
+	GeoConstraint has been changed.
+
+2006-10-16  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Update win32 module export definitions for latest libdap*.
+
+2006-10-16  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Provide header for find_if under win32
+
+2006-10-16  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Change funcs that return nothing to be declared so
+
+2006-10-14  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-13  James Gallagher <jgallagher at opendap.org>
+
+	GridGeoConstraint: Fixed the calls so that they no longer use the
+	dds argument
+
+2006-10-13  James Gallagher <jgallagher at opendap.org>
+
+	GridGeoConstraint: Added
+
+2006-10-13  James Gallagher <jgallagher at opendap.org>
+
+	Removed DDS from GeoConstraint.
+
+2006-10-13  James Gallagher <jgallagher at opendap.org>
+
+	HTTPCache.cc: Minor change to a comment.
+
+2006-10-13  James Gallagher <jgallagher at opendap.org>
+
+	Refactored GeoConstraint so that all the Grid-specific code is now
+	in GridGeoConstraint (created/added GridGeoConstraint). Modified
+	ce_functions so that geogrid uses the new object. Updated the unit
+	tests. Added the new class to the Makefile.am
+
+2006-10-13  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-12  James Gallagher <jgallagher at opendap.org>
+
+	Added tests.
+
+2006-10-12  James Gallagher <jgallagher at opendap.org>
+
+	Test baseline data for the geogrid() function
+
+2006-10-12  James Gallagher <jgallagher at opendap.org>
+
+	Changes test.10 to test.a
+
+2006-10-12  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-11  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2006-10-11  James Gallagher <jgallagher at opendap.org>
+
+	Added tests to expr-testsuite for geogrid. Somewhat dubious
+	at the moment.
+
+2006-10-10  James Gallagher <jgallagher at opendap.org>
+
+	expr-test.cc: reformatted
+
+2006-10-09  James Gallagher <jgallagher at opendap.org>
+
+	BaseType, RValue, et c.: Closed ticket regarding optimization
+	of build_btp_args. Args are always BaseTypes and before they
+	were always read. This could cause huge Grid/Array variables to
+	be read when those were arguments to functions, even if the
+	running the function would result in only a small part of the
+	Grid/Array being returned. Now arguments are not read. If functions
+	need values for the arguments, they must read them themselves.
+
+2006-10-09  James Gallagher <jgallagher at opendap.org>
+
+	cgi_util.cc: Fixed a bug in set_mime_text where the wrong 'type'
+	was returned. The type was always set to dap4_ddx.
+
+2006-10-09  James Gallagher <jgallagher at opendap.org>
+
+	CEFunctionsTest: Paths easy to set for debugger.
+
+2006-10-09  James Gallagher <jgallagher at opendap.org>
+
+	DDXParserTest: Turned off debug
+
+2006-10-09  James Gallagher <jgallagher at opendap.org>
+
+	AISDatabaseParser: Replaced old xml getLineNumber with the newer
+	SAX2 api call.
+
+2006-10-06  James Gallagher <jgallagher at opendap.org>
+
+	Vector: Added set_value() and value() methods.
+	Updated docs
+
+2006-10-06  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Now the linear_scale function will work for
+	Grid Maps in the hdf4 handler.
+
+2006-10-06  James Gallagher <jgallagher at opendap.org>
+
+	Check point: I've modified Connect, getdap and ObjectType so they
+	support a Connect::request_ddx() method. I've added a stream
+	reader to DDXParser and am in the process of figuring out where
+	the attributes are going!
+
+2006-10-05  James Gallagher <jgallagher at opendap.org>
+
+	DDXParser.h: Added an intern_stream() method to read from a stream and
+	updated the code (one function) to use the new SAX2 API from libxml2.
+
+2006-10-05  James Gallagher <jgallagher at opendap.org>
+
+	DDXParser.cc: Added an intern_stream() method to read from a stream and
+	updated the code (one function) to use the new SAX2 API from libxml2.
+
+2006-10-05  James Gallagher <jgallagher at opendap.org>
+
+	Vector.cc: Ran indent
+
+2006-10-04  James Gallagher <jgallagher at opendap.org>
+
+	ConstraintEvaluator: Now uses a list to store the list of functions
+	and the add_function() methods now overwrite functions with the
+	same names so it's possible to provide specializations of the
+	standard functions in ce_functions.
+
+2006-10-04  James Gallagher <jgallagher at opendap.org>
+
+	Added value()/set_value() methods to Float32/64, Int16/32,
+	UInt16/32 and Str.
+
+2006-10-04  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Both grid and geogrid now use a little hack to
+	read the map vectors of a Grid. The HDF handler cannot read the
+	Grid Maps directly (maps on HDF are not really variables but are
+	attributes instead). This hack involves setting send_p for the
+	just the maps and then calling the Grid's read() method.
+
+2006-10-04  James Gallagher <jgallagher at opendap.org>
+
+	ConstraintEvaluator: Now uses a list to store the list of functions
+	and the add_function() methods now overwrite functions with the
+	same names so it's possible to provide specializations of the
+	standard functions in ce_functions.
+
+2006-10-04  James Gallagher <jgallagher at opendap.org>
+
+	Vector.cc: Simplified the code in val2buf()
+
+2006-10-03  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-10-02  James Gallagher <jgallagher at opendap.org>
+
+	Float64, Int32: Added value/set_value() methods
+	Grid: Added an reverse iterator typedef and rbegin/rend
+	methods. This provides an easy way to access the 'rightmost'
+	map vectors (used by geogrid()).
+
+2006-10-02  James Gallagher <jgallagher at opendap.org>
+
+	Vector.cc: Ran through astyle indent utility.
+
+2006-10-02  James Gallagher <jgallagher at opendap.org>
+
+	parser-util.cc: Ran through astyle indent utility.
+
+2006-10-02  James Gallagher <jgallagher at opendap.org>
+
+	CEFunctionsTest: Added tests for linear_scale().
+
+2006-10-02  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions: Added linear_scale function.
+	CEFunctionsTest: Added tests for linear_scale().
+
+2006-09-30  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-09-29  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Added GEOConstraintTest
+
+2006-09-29  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraintTest: Extracted from CEFunctionsTest and added to
+	svn.
+
+2006-09-28  James Gallagher <jgallagher at opendap.org>
+
+	Clause.cc: Fixed up some comments.
+
+2006-09-28  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint.cc: Turned off instrumentation; removed throw()
+	from declarations, fixed a problem with bad latitude constraint
+	information that caused a fatal error (now it sends a message
+	indicating how to fix the problem).
+
+2006-09-28  James Gallagher <jgallagher at opendap.org>
+
+	DODSFilter.cc: Modified send_data() so that errors thrown by
+	BaseType functions will be returned to clients correctly.
+
+2006-09-28  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc, GeoConstraint.h: Removed 'throw(Error)' from
+	declarations since C++ calls abort() when/if another type of
+	excpetion is thrown, even if there's a catch() clause for it.
+
+2006-09-28  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.h: Removed 'throw(Error)' from declarations since C++
+	calls abort() when/if another type of excpetion is thrown, even if
+	there's a catch() clause for it.
+
+2006-09-27  James Gallagher <jgallagher at opendap.org>
+
+	Vector.cc: I made the instrumentation in the ctor and dtor
+	'level two' statements so that the output would be less cluttered.
+
+2006-09-27  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint.cc: reorder_data_longitude_axis() now works.
+	CEFunctionsTest.cc: Turned off debugging.
+
+2006-09-26  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint: Checkpoint; passes unit tests but still fails with
+	a real dataset (COADS_CLIMATOLOGY). Problem with circular
+	longitude axis.
+
+2006-09-25  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: The grid() function is now implemented so that
+	geogrid() can use it to evaluate GSEs (ticket 569)
+
+2006-09-25  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc/h: The grid() function is now a BaseType* function.
+	CEFunctionsTests: Work with the new grid() implementation changes.
+
+2006-09-24  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Removed old code that was getting in the way.
+
+	GeoConstraint.cc: Fixed a buf in reorder_data_longitude_axis():
+	off-by-one error when applying the first constraint (used
+	d_lon_length instead of d_lon_length-1 for the end point).
+
+	CEFunctionsTest: Added code to use TestTypes from the 'test'
+	directory and generally fixed up the tests so they work with the
+	new BaseType function version of geogrid().
+
+2006-09-23  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Modified TestArray so that it's possible to see that arrays really
+	are subsampled. That is, if a constraint is set on an array,
+	TestArray::read() will first allocate the whole array and then
+	sample it, simulating a read() method that's interacting with an
+	API that knows how to sample an array. Works only for two dims.
+
+2006-09-22  James Gallagher <jgallagher at opendap.org>
+
+	test.c{0,1}: Added
+
+2006-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Grid: Added get_array() which returns an Array* so the cast that
+	was needed when using array_var() can be removed. I changed all
+	the calls to array_var() to get_array() (DDS, ce_expr, ce_functions).
+
+	RValue.cc: I removed the read() call when build_btp_args() builds
+	an argument list. This change may break client software, but it means
+	that variables are not complete read when they are passed to CE
+	functions, which should be a big boost in efficiency when working
+	with EOS Grids in geogrid().
+
+	Added code in TestArray to make arrays with constrained values.
+	GeoConstraint: Updates; almost complete.
+
+2006-09-22  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint: Added a new method and an enum to record the 'sense' of
+	the latitude map (normal or inverted).
+	Added tests for the find_latitude_indeces() method to the unit tests
+
+2006-09-21  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint/geogrid checkpoint.
+	Byte,Str: Added value() and set_value() methods
+	TestArray: Improved the read() method so it uses the series_values
+	property and so it returns reasonable values for lat/lon vectors
+	expr-test.cc: Now can be used to test BaseType functions
+
+2006-09-20  James Gallagher <jgallagher at opendap.org>
+
+	Another GeoConstraint checkpoint
+
+2006-09-20  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint checkpoint
+
+2006-09-19  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Patch from Patrice Dumas regarding the libdapserver
+	and libdapclient libraries.
+
+2006-09-19  James Gallagher <jgallagher at opendap.org>
+
+	libdap.spec: Patch from Patrice Dumas regarding the libdapserver
+	and libdapclient libraries.
+
+2006-09-19  James Gallagher <jgallagher at opendap.org>
+
+	dap-config.in: Changed the semantics of --libs so that it matches
+	the old behavior.
+
+2006-09-15  James Gallagher <jgallagher at opendap.org>
+
+	Updated the version to 3.7.2 and the associated ChangeLog,
+	configure.ac, et c., files. The docs have also been updated
+	(docs/html.tar.gz).
+
+2006-09-15  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnect.cc: Changed the way headers are parsed. Now the code
+	assumes that each header is terminated by a \r\n pair (previously
+	the code assumed the line terminator was a \n character only).
+
+2006-09-15  James Gallagher <jgallagher at opendap.org>
+
+	HTTPConnectTest: Fixed most, but not all, of the failures. See
+	ticket 552 for more info.
+
+2006-09-15  James Gallagher <jgallagher at opendap.org>
+
+	test.f.exp: The change to TestStr so that the number included in the
+	string increments broke this test. Fixed.
+
+2006-09-15  James Gallagher <jgallagher at opendap.org>
+
+	Sequence: Doxygen was complaining about the types used in the
+	new transfer_data_*() methods because they were not exactly the
+	same string (vector<Sequence*> versus sequence_values_stack_t).
+	I made them the same.
+
+2006-09-15  James Gallagher <jgallagher at opendap.org>
+
+	doxy.conf: Now the method listings are in alphabetical order.
+
+2006-09-14  James Gallagher <jgallagher at opendap.org>
+
+	SequenceTest.cc: Now tests the new transfer_data() method.
+
+2006-09-14  James Gallagher <jgallagher at opendap.org>
+
+	Added the transfer_data() method to Sequence. This method reads
+	data using the read() method and loads values into the local object's
+	d_values field. Values can then be used by methods like print_val()
+	which expect to see information stored in the Sequence objects
+	as if the object was part of a client and had read the data off of
+	the wire. I also modified the print_vals_by_row so that nested
+	Sequences values are indented by four spaces.
+
+2006-09-14  James Gallagher <jgallagher at opendap.org>
+
+	TestStr.cc: Modified the string so that the value of count
+	increments by one for each instance.
+
+2006-09-14  James Gallagher <jgallagher at opendap.org>
+
+	TestInt32.cc: Modified so that on 64-bit machines the overflow of the
+	'* 32' operation does not reset the value of _buf to zero, but instead
+	_buf cycles back to 32.
+
+2006-09-13  James Gallagher <jgallagher at opendap.org>
+
+	Sequence: Added transfer_data and related methods. These are used
+	to move data on the server-side from a data source into the
+	d_values field, loading the variables in the sequence with data in
+	a way that is very similar to the operation of all the other
+	variables. This provides a way to pass a DDS to other code which
+	is loaded with data. SequenceTest.cc and Makefile.am in
+	unit-tests: Test the transfer_data method. Int32: I added a
+	value() method similar to those added to Float32/64 a while back.
+	This simplifies testing so much... configure.ac: Bumped up the
+	revision number of the library.
+
+2006-09-08  James Gallagher <jgallagher at opendap.org>
+
+	GNURegex: I change the regex_t field from a regular variable to a
+	pointer. Seems to fix the problem, although I don't know why. Not
+	the most reassuring feeling...
+
+2006-09-05  James Gallagher <jgallagher at opendap.org>
+
+	BaseType.cc: Modified add_var() so that it now throws an InternalErr
+	and fixed up the documentation so it reads correctly.
+
+2006-09-02  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-09-01  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: geogrid() no longer uses the projection/selection
+	function model. Now it's a pure projection function.
+
+2006-09-01  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint: removed old code and modified find_lon_lat_maps()
+	so that I can test with the COADS dataset. Tests not working...
+
+2006-09-01  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint: removed old code and modified find_lon_lat_maps()
+	so that I can test with the COADS dataset. Tests not working...
+
+2006-09-01  James Gallagher <jgallagher at opendap.org>
+
+	checkpoint: GeoConstraint/geogrid() nearly working Changes in
+	DDS, ConstraintEvaluator, ce_functions (now uses the new libdap
+	namespace), RValue, various tests.
+
+2006-09-01  James Gallagher <jgallagher at opendap.org>
+
+	Updates/Changes to the grid() testsuite that uses remote servers.
+	I changed the tests so they now run using servers on test.opendap.org
+	and use getdap (the tests were originally written to use geturl).
+
+2006-08-29  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint: Changed code to do the data translation for split
+	constraints so that it uses memcpy(). Untested.
+
+2006-08-28  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint: Added some of the code needed to swap parts of a 'split'
+	longitude constraint.
+
+2006-08-28  James Gallagher <jgallagher at opendap.org>
+
+	CEFunctionsTest.cc: Added unit tests for vector swapping coode.
+
+2006-08-28  James Gallagher <jgallagher at opendap.org>
+
+	Added separate lon/lat bounding box marking code to GeoConstraint.
+
+2006-08-25  James Gallagher <jgallagher at opendap.org>
+
+	More work on geogrid().
+	M    ce_functions.h
+	M    GeoConstraint.h
+	M    Grid.h
+	M    Vector.cc
+	M    ce_functions.cc
+	M    Grid.cc
+	M    unit-tests/CEFunctionsTest.cc
+	M    GeoConstraint.cc
+
+2006-08-25  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-08-24  James Gallagher <jgallagher at opendap.org>
+
+	Progress on the geogrid() server-side function. Changed/Added files:
+	M    RValue.cc
+	M    ce_functions.h
+	M    GeoConstraint.h
+	M    Makefile.am
+	M    gse-test.cc
+	M    ce_functions.cc
+	A    unit-tests/ce-functions-testsuite
+	A    unit-tests/ce-functions-testsuite/two_grid.dds
+	A    unit-tests/ce-functions-testsuite/geo_grid.dds
+	M    unit-tests/CEFunctionsTest.cc
+	M    Clause.cc
+	M    GeoConstraint.cc
+
+2006-08-22  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Updated release files for the 3.7.1 source release.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc, DDS.cc, CEFunctionsTest.cc, docs/html.tar.gz:
+	Updates for documentation. For CEFunctionsTest.cc: Added tests
+	for the new grid() and nascent geogrid() code.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint.cc: Added
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc: Fixed tcket 480. The transfer_attributes() method
+	was not handling the HDF4 *_dim_? attribute containers
+	correctly, at least as far as the libnc-dap was concerned.
+	Now those attribute containers are made subtables of the
+	associated variable. That is, if there's a variable <var>
+	and a container <var>_dim_0, then the attribute table
+	<var> will have a subtable 'dim_0'.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Added stuff for gwogrid() (which still doesn't
+	work).
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	BaseType.cc: Updates to comments.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Grid.h: Comment fixes, moved some doxygen comments into
+	Grid.cc.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	GeoConstraint.h: Added. Currently does nothing.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.h: changed the name of func_grid_select() to
+	projection_function_grid(). Added projection _function_geogrid().
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	AttrTableTest.cc: Added a test for the new append_attr() method.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	DDSTest.cc: Added a test for ticket 480 (transfer_attributes()).
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	S2000415.HDF.test1.das: Added for more DDS::transfer_attributes()
+	tests.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Mkaefile.am: GetConstraint.cc Added.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	RValue.cc: Fixes for some comments.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	Grid.cc: Fixes for some comments.
+
+2006-08-21  James Gallagher <jgallagher at opendap.org>
+
+	DAS.cc: Removed the 'char*' versions of the methods. These have not
+	been needed since we stopped using the GNU String class.
+
+2006-08-17  James Gallagher <jgallagher at opendap.org>
+
+	BaseType.h: Reformatted a doc comment for var().
+
+2006-08-17  James Gallagher <jgallagher at opendap.org>
+
+	AttrTable: Added append_attr() method that takes a vector of values
+	so that client code does not have to call the single value version
+	in a loop.
+
+2006-08-17  James Gallagher <jgallagher at opendap.org>
+
+	AttrTable: Added append_attr() method that takes a vector of values
+	so that client code does not have to call the single value version
+	in a loop.
+
+2006-08-15  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-08-14  James Gallagher <jgallagher at opendap.org>
+
+	das.tab.cc: Updated (edits to das.y).
+
+2006-08-14  James Gallagher <jgallagher at opendap.org>
+
+	das.y: config_dap.h --> config.h
+
+2006-08-14  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am, CEFunctionsTest.cc: Added unit tests for the the
+	grid() ce function.
+
+2006-08-14  James Gallagher <jgallagher at opendap.org>
+
+	Str.cc: No longer includes an extern declaration for escattr() since
+	that function is not called by this code.
+
+2006-08-14  James Gallagher <jgallagher at opendap.org>
+
+	GSEClause.cc: Added the word 'map' to the error messages about
+	missing map variables.
+
+2006-08-11  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Modified so that the errors returned match those
+	in the design.
+
+2006-08-01  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc, DDXParser.cc/h, tests/ddx-testsuite/*.ddx: Changed the name
+	of the dodsBLOB element to dataBLOB and the attribute from URL to href.
+	See ticket #454.
+
+2006-08-01  James Gallagher <jgallagher at opendap.org>
+
+	DDSTest.cc: Changed expected name to dataBLOB from dodsBLOB and
+	attribute of that element to href from URL.
+
+2006-08-01  James Gallagher <jgallagher at opendap.org>
+
+	html.tar.gz: Updated build of reference docs.
+
+2006-08-01  James Gallagher <jgallagher at opendap.org>
+
+	generalUtilTest.cc: Fixed test for the new id2www/www2id behavior
+	which escapes the percent sign.
+
+2006-08-01  James Gallagher <jgallagher at opendap.org>
+
+	BaseType.h, ConstraintEvaluator.cc, DODSFilter.cc, escaping.cc/.h,
+	Sequence.cc: Updated comments.
+
+2006-08-01  James Gallagher <jgallagher at opendap.org>
+
+	libdap.m4: Applied Patrice Dumas' patch which checks for the newer
+	dap-config and uses it's options for the three library setup.
+
+2006-07-31  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-07-30  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	w32 Makefile rewrite & export def's for 3-lib split-up of libdap
+
+2006-07-09  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Tweeks for win32 porting effort
+
+2006-07-09  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	New makefile for win32 libdap version to accomodate 3-library split
+
+2006-07-07  James Gallagher <jgallagher at opendap.org>
+
+	docs/html.tar.gz, escaping.cc: Updated/corrected documentation.
+
+2006-07-07  James Gallagher <jgallagher at opendap.org>
+
+	cgi_util.cc, configure.ac: Fixed bug 437. When a handler is not passed
+	a version number, it will now use the library's version number set at
+	compile time.
+
+2006-07-03  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Patch core to use libcurl as a dll without crashing
+
+2006-06-14  James Gallagher <jgallagher at opendap.org>
+
+	Removed GNU error and builtin from Makefile.am (they were already
+	removed from the directry GNU.
+
+2006-06-14  James Gallagher <jgallagher at opendap.org>
+
+	Updates to ChangeLog, README, INSTALL, NEWS, libdap.spec,
+	Makefile.am and html.tar.gz for the beta releae 3.7.0.
+
+2006-06-13  James Gallagher <jgallagher at opendap.org>
+
+	lex.gse_.cc: Comments
+
+2006-06-13  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc, gse.lex: fixed comments
+
+2006-06-09  James Gallagher <jgallagher at opendap.org>
+
+	INSTALL.AIX: Added newer comments from Dan S.
+
+2006-06-09  James Gallagher <jgallagher at opendap.org>
+
+	INSTALL: Updated by adding a reference to the INSTALL.AIX file.
+
+2006-06-06  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-06-05  James Gallagher <jgallagher at opendap.org>
+
+	GNURegex: Added Error thows back into the code
+
+2006-06-05  James Gallagher <jgallagher at opendap.org>
+
+	In GNU: Removed some now-unused files and fixed a bug in
+	GNURegex.cc where config.h was not included when it must be. This
+	caused a failure on OS/X because the rpl_regexec(), ..., symbols
+	were not defined.
+
+2006-06-02  James Gallagher <jgallagher at opendap.org>
+
+	regex_test.cc: Added
+
+2006-06-01  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-05-31  Nathan Potter <ndp at coas.oregonstate.edu>
+
+	GNURegex.cc: kludge! Added a workaround patch to
+	GNURegex.cc:match() to avoid a illegal memory access segmentation
+	fault under OS-X 10.4.6. Inline comments provide greater detail.
+	(ndp)
+
+2006-05-31  James Gallagher <jgallagher at opendap.org>
+
+	ssize_t.m4: Added during most recent update.
+
+2006-05-30  James Gallagher <jgallagher at opendap.org>
+
+	In gl/: Update to the gnulib code. This may fix a problem on OS/X
+	where the gnulib regexec function appears to corrupt the stack.
+
+2006-05-19  James Gallagher <jgallagher at opendap.org>
+
+	Various types (Int16, et c.): Removed include of ce_expr.tab.h since
+	that header is included by Operators.h
+
+2006-05-19  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Removed include of libgnu from libdapclient and
+	libdapserver. This should fix the multiple define error at link time.
+
+2006-05-19  James Gallagher <jgallagher at opendap.org>
+
+	ce_expr.y: fixed multiple use of the variable name 'table' in
+	declarations.
+
+2006-05-18  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: reordered libraries and added ce_parser.h to DAP_HDR
+
+2006-05-10  James Gallagher <jgallagher at opendap.org>
+
+	AISDatabaseParser.h, AISResources.cc, AISResources.h, Resource.cc:
+	Updates to doxygen comments.
+
+2006-05-08  James Gallagher <jgallagher at opendap.org>
+
+	Operators.h: Made dods_max() inline. This should improve performance
+	and also fix a problem introduced by the recently applied AIX patch
+	where dods_max() was multiply defined.
+
+2006-05-04  James Gallagher <jgallagher at opendap.org>
+
+	INSTALL.AIX: Updated the information from Dan Stromberg and Martin
+	Peschke.
+
+2006-05-04  James Gallagher <jgallagher at opendap.org>
+
+	Operators.h, RValue.cc, deflate.c: Applied patches from Dan Stromberg
+	which fix problems found during a port to the native AIX compiler.
+
+2006-05-01  James Gallagher <jgallagher at opendap.org>
+
+	libdap.m4: Added DAP_CLIENT_LIBS and DAP_SERVER_LIBS to symbols
+	that are written out.
+
+2006-04-20  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-04-19  James Gallagher <jgallagher at opendap.org>
+
+	ce_expr.y: The expression parser now passes the ConstraintEvaluator
+	object to projection functions.
+
+2006-04-19  James Gallagher <jgallagher at opendap.org>
+
+	ConstraintEvaluator: Removed some code that was commented out.
+
+2006-04-19  James Gallagher <jgallagher at opendap.org>
+
+	expr.h: The projection function typedef now includes a fourth
+	argument so that the ConstraintEvaluator can be passed to the
+	projection function. This provides a way for the proj_function to
+	register the matching selection function.
+
+2006-04-19  James Gallagher <jgallagher at opendap.org>
+
+	ce_parser.h: Added. Used to pass both the DDS and ConstraintEvaluator
+	to the CE Parser.
+
+2006-04-19  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	configure.ac, dap-config.in, conf/libdap.m4: bumped up the revision
+	number to 3.7.0 (which will be the next revision), added options to
+	dap-config --server-libs and --client-libs and updated the libdap.m4
+	macro to match the new three-library organization of libdap.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	expr.lex, expr.y, lex.expr.cc, expr.tab.cc: Removed/Replaced with
+	ce_expr...
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	Removed_functions.txt: Updated for the latest changes.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	lex.ce_expr.cc: Added
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	expr-test.cc, tests/Makefile.am: Tests updated for changes in DDS,
+	DODSFilter, et cetera.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	DODSFilter: Modified so that this class now takes a ConstraintEvaluator
+	object in the places where needed.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	DDS: Removed the constraint evaluator and the send() method.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	BaseType.h and it's child classes: Now the serialize() method
+	takes not only a DDS but also a ConstraintEvaluator object.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	ce_expr.lex, ce_expr.y, ce_expr.tab.{cc,h}: Added files that
+	contains a modified ce parser. This parser takes two objects as
+	input: ConstraintEvaluator and DDS. The old parser took only the
+	DDS.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	ConstraintEvaluator: Added this class. Now the ce evaluator is separate
+	from the DDS object.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	Clause.h: Added private methods for the const ctor and operator=
+	so that default versions would not get called by accident.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	cgi_util.cc: Removed the do_data_transfer() function. Use DODSFilter.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	ce_functions.cc: Minor change to the func_length code. It no
+	longer uses the 'constants' vector in DDS to store the BaseType
+	used for the return value. The caller can easily free the storage.
+	Also, this function is never used!
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	INSTALL.AIX: Fixed spelling and added a note about not bugging
+	Martin or assuming he's going to guarantee the steps will work.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	Makefile.am: Now builds the ce_expr parser in place of the expr
+	parser. There's no real difference in the grammar accepted by the
+	new parser, but ce_expr takes both the ConstraintEvaluator and
+	DDS objects, where the old one took only the DDS.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	Operators.h: Now uses the ce_expr parser header.
+
+2006-04-18  James Gallagher <jgallagher at opendap.org>
+
+	parser.h: Removed the GSEClause include that I'd commented out earlier.
+
+2006-04-16  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Rename, add dirs and prune as appropriate for VC++ port
+
+2006-04-04  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-04-03  James Gallagher <jgallagher at opendap.org>
+
+	gse_parser.h: Added. This holds parser info used by the grid() ce
+	function. The contents of this file were originally in parser.h, which
+	holds definitions for the DAP parsers. Moving the info about grid()
+	here maens that the grid() code can be part of the dapserver library.
+
+2006-04-03  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Edit 'scalar deleting destructors' out of win32 module def's
+
+2006-03-31  James Gallagher <jgallagher at opendap.org>
+
+	For ticket 307 I modified the build so that three libraries are
+	made instead of just one. The libdap library now contains only
+	classes used for the DAP2 implementation. The client and server
+	support code is now in libdapclient and libdapserver. Many files
+	were modified since I trimmed the includes so that classes in
+	libdapclient don't include headers in libdapserver and vice versa.
+
+2006-03-31  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-03-30  James Gallagher <jgallagher at opendap.org>
+
+	Added INSTALL.AIX
+
+2006-03-27  James Gallagher <jgallagher at opendap.org>
+
+	Massive propset on libdap to get svn to ignore many things so
+	eclipse will work more smoothly
+
+2006-03-24  James Gallagher <jgallagher at opendap.org>
+
+	Updated svn:ignore for some files.
+
+2006-03-21  James Gallagher <jgallagher at opendap.org>
+
+	Build of docs/html.tar.gz for 3.6.2 on 3/21/06
+
+2006-03-21  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-03-20  James Gallagher <jgallagher at opendap.org>
+
+	Moved tests/expr-testsuite/test.a to tests/expr-testsuite/test.10.
+
+2006-03-20  James Gallagher <jgallagher at opendap.org>
+
+	test.c.exp: Removed log
+
+2006-03-19  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Win32 libnc-dods requires core's regex.h installed.  None stock on
+	windows. 
+
+2006-03-19  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Update export module definitions per recent core changes
+
+2006-03-16  James Gallagher <jgallagher at opendap.org>
+
+	NEWS: Spelling... one more time
+
+2006-03-16  James Gallagher <jgallagher at opendap.org>
+
+	NEWS: Spelling...
+
+2006-03-14  James Gallagher <jgallagher at opendap.org>
+
+	Updated ChangeLog, configure.ac, libdap.spec and NEWS for version
+	3.6.2
+
+2006-03-14  James Gallagher <jgallagher at opendap.org>
+
+	I changed the way DODSFilter handles the compression sub-process.
+	The class was caling waitpid on the child process which was blocking
+	even after the child had exited. I found that calling fflush on
+	the FILE* where teh server is writing the response is sufficient
+	to guarantee that all the data from the compressor is written w/o
+	using waitpod. This is a fix for ticket #335
+
+2006-03-10  James Gallagher <jgallagher at opendap.org>
+
+	Added a new public method to Connect read_data_no_mime() which can
+	be used to read from a file. This method read a DAP2 data object
+	from a file but does not try to parse MIME headers before reading
+	the data. I modified getdap.cc so that it uses this when reading
+	from a file that's not stdin.
+
+2006-03-10  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Updated for 3.6.1
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Bumped up the version to 3.6.1. Files affected: configure.ac libdap.spec,
+	INSTALL, README, NEWS.
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Updated tests/expr-testsuite/expr-test.0/test.c by changing its name to
+	test.d so that Eclipse's indexer won't gag on it.
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	removed unused test directories expr-testsuite and grid-func-testsuite
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Added -t option to DODSFilter.cc. This was left out by mistake.
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Changed tests from dodsdev to test.opendap.org
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Bumped up the version to 3.6.1. Files affected: configure.ac libdap.spec,
+	INSTALL, README, NEWS.
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Updated tests/expr-testsuite/expr-test.0/test.c by changing its name to
+	test.d so that Eclipse's indexer won't gag on it.
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	removed unused test directories expr-testsuite and grid-func-testsuite
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Added -t option to DODSFilter.cc. This was left out by mistake.
+
+2006-03-09  James Gallagher <jgallagher at opendap.org>
+
+	Changed tests from dodsdev to test.opendap.org
+
+2006-03-08  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the C++-style comment in deflate.c from a bug reprot
+	from Jim Davis at Nasa.
+
+2006-03-06  James Gallagher <jgallagher at opendap.org>
+
+	Updated for 3.6.0-2
+
+2006-03-06  James Gallagher <jgallagher at opendap.org>
+
+	Increased the release number to two.
+
+;; Local Variables:
+;; coding: utf-8
+;; End:
+2006-03-06  James Gallagher <jgallagher at opendap.org>
+
+	Increased the release number to two.
+
+2006-03-05  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Trivial change in comment in win32 libdap makefile
+
+2006-03-05  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Redo recently clobbered changes from gl/ refresh
+
+2006-03-01  James Gallagher <jgallagher at opendap.org>
+
+	Updated the OSX_Resources/Readme.txt file for 3.6.0.
+
+2006-02-28  James Gallagher <jgallagher at opendap.org>
+
+	Updated grammar files and added rpm and OS/X package targets to Makefile.am
+
+2006-02-28  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-02-27  James Gallagher <jgallagher at opendap.org>
+
+	Updated NEWS.
+
+2006-02-27  James Gallagher <jgallagher at opendap.org>
+
+	Updated the Mac/OSX project file for 3.6.0
+
+2006-02-27  James Gallagher <jgallagher at opendap.org>
+
+	Added unit-tests/testFile.cc: This provides a way to link the FILE*
+	output code with C++ strings so that unit tests can work their magic.
+
+2006-02-27  James Gallagher <jgallagher at opendap.org>
+
+	Updated documentation files (README, NEWS, ChangeLog), version information
+	(configure.ac, libdap.spec) and removed two unused unit test files.
+
+2006-02-27  James Gallagher <jgallagher at opendap.org>
+
+	Imported the latest gnulib code (see the Makefile.am in gl for the
+	gnulib-tool arguments).
+
+2006-02-25  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Removed lines in Makefile.am that were commented out.
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Removed html.tar.z and added html.tar.gz
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Removed docs.tar.gz
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Added docs and docs/html.tar.gz
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Fixed up the regression tests so that they don't use deprecated
+	Error methods.
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Removed LongIterAdapter.cc from tests
+
+2006-02-24  James Gallagher <jgallagher at opendap.org>
+
+	Removed files no longer needed. Removed depreacted methods. Updated
+	documentation.
+
+2006-02-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed most $Log$ entries since they are not supported by
+	Subversion. Will do the rest tomorrow...
+
+2006-02-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed all the method overloads that used const char *
+	parameters. Those methods were added so that the Pix objects,
+	which were passed as void*, would not get called with character
+	strings by mistake. Since the Pix methods are gone, these are no
+	longer needed.
+
+2006-02-21  James Gallagher <jgallagher at opendap.org>
+
+	I fixed the constructors for both PipeResource and StdinResource
+	so that the parent class and fields were initialized in the
+	correct order. I also fixed up the documentation for
+	DODSResponseObject.
+
+2006-02-20  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Tweek linker settings for libdap dll
+
+2006-02-20  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Sync win32 makefile with unix version, rewrite
+
+2006-02-20  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Update module definitions for dll version of libdap
+
+2006-02-20  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Tweek for win32 port
+
+2006-02-15  Patrick West <pwest at ucar.edu>
+
+	fixed indentation
+
+2006-02-15  Patrick West <pwest at ucar.edu>
+
+	commented out DataDDS constructor that doesn't take BaseTypeFactory
+
+2006-02-15  James Gallagher <jgallagher at opendap.org>
+
+	DataDDS.cc: Added a call to protocol_string_to_numbers in the
+	constructor. This sets the internal protocol version numbers so
+	that calls to Sequence:: deserialize() work (they now use the
+	protcol version number to select the correct algorithm for reading
+	from the stream instead of the server version).
+
+2006-02-15  James Gallagher <jgallagher at opendap.org>
+
+	AttrTable.cc: Corrected a problem in add_value_alias where looking
+	for attributes could cause a segmentation fault. The problem was
+	that AttrTable::find() was setting the return iterator to
+	attr_end() for the AttrTable object it returned as a value-result
+	parameter (so the test to see if the iterator was pointing to the
+	end needed to be done using that table and not the calling object.
+
+2006-02-14  James Gallagher <jgallagher at opendap.org>
+
+	NEWS and ChangeLog both updated.
+
+2006-02-14  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-02-13  James Gallagher <jgallagher at opendap.org>
+
+	Modified the print_xml method in Constructor and grid. It no
+	longer prints anything for variables that are not part of the
+	current projection when printing the constrained ddx. This works
+	because the DDS::mark method marks the parents of projected
+	variables.
+
+2006-02-13  James Gallagher <jgallagher at opendap.org>
+
+	Added PipeResponse.h and StdinResponse.h; changed getdap and
+	Connect to use them.
+
+2006-02-13  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Flush weekend win32 porting work back to trunk
+
+2006-02-10  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Removed xdr routines from win32 subdir under libdap. Code now in
+	base tools used to build under win32.
+
+2006-02-09  James Gallagher <jgallagher at opendap.org>
+
+	empty comment
+
+2006-02-09  James Gallagher <jgallagher at opendap.org>
+
+	Removed all deprecated methods as per ticket 248. This includes
+	Pix methods, ostream I/O methods used by servers and various junk
+	in Connect.
+
+2006-01-25  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2006-01-24  James Gallagher <jgallagher at opendap.org>
+
+	Added Removed_functions.txt: This file contains the type
+	signitures of methods/functions recently (version 3.6 and later)
+	removed.
+
+2006-01-24  James Gallagher <jgallagher at opendap.org>
+
+	The ostream I/O was removed and many files were modified. The code
+	is still present inside #if 0 ... #endif preprocessor lines.
+
+2006-01-23  James Gallagher <jgallagher at opendap.org>
+
+	All unit tests updated to work after removing the iostream
+	functions/methods.
+
+2006-01-19  James Gallagher <jgallagher at opendap.org>
+
+	Added protocol version to the library. The version number is set
+	in the configure.ac file. I've modified the unit tests so that
+	they work. I've also removed (#if 0 ... #endif) all of the MIME
+	header functions which used the C++ iostream stuff (which is part
+	of the task to remove deprecated code).
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	Updated ChangLog
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc: transfer_attributes used odd logic and an unneeded
+	variable. Fixed.
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	expr-test.cc: changed new exception code to use fprintf() (it was
+	using cerr).
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	GSEClause: Removed the old, unimplemented, methods that were
+	supposed to take the grid() function subexpressions. Fixed up some
+	comments in the class as well.
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	cgi_util.cc: In remove_mime_header() \n was used as the MIME
+	header separator when CRLF should have been used. Since the rest
+	of the code was fixed for 3.5.3, remove_mime_header() didn't find
+	the separator. This broke the HTML form response.
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	DDS.cc: transfer_attributes used odd logic and an unneeded
+	variable. Fixed.
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	expr-test.cc: changed new exception code to use fprintf() (it was
+	using cerr).
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	GSEClause: Removed the old, unimplemented, methods that were
+	supposed to take the grid() function subexpressions. Fixed up some
+	comments in the class as well.
+
+2006-01-12  James Gallagher <jgallagher at opendap.org>
+
+	cgi_util.cc: In remove_mime_header() \n was used as the MIME
+	header separator when CRLF should have been used. Since the rest
+	of the code was fixed for 3.5.3, remove_mime_header() didn't find
+	the separator. This broke the HTML form response.
+
+2005-12-30  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Work toward accomodating gcc under mingw
+
+2005-12-27  James Gallagher <jgallagher at opendap.org>
+
+	Installed GNU indent code formatter to eclipse and used it on
+	expr-test.cc
+
+2005-12-27  James Gallagher <jgallagher at opendap.org>
+
+	In expr-test, the function parse_mime() did not test for the new
+	CRLF line terminator. This caused an infinite loop. Fixed. I also
+	added a comment to cgi-util.cc noting that if the CRLF constant is
+	changed, then the one in expr-test.cc should be changed too. Since
+	the test code is, well, test code, it doesn't seem like the
+	constant should be moved out into one of the header files. The
+	CRLF constant is really used only by the cgi-util code.
+
+2005-12-27  James Gallagher <jgallagher at opendap.org>
+
+	Removed regex.loT
+
+2005-12-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed extra qualtification on the private method Regex::init in
+	GNURegex.h.
+
+2005-12-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed the send version method body and replaced it with a call
+	to do_version() in cgi_util.cc. This consolodates the code that
+	writes HTTP headers to one file.
+
+2005-12-23  James Gallagher <jgallagher at opendap.org>
+
+	Changed all calls to fprintf that write parts of the HTTP resonse
+	header so that they terminate lines using CRLF pairs and not just
+	LF (\n or 0x0a). I also fixed the spelling of Content-Type (the
+	'T' in 'Type' was not capitalized).
+
+2005-12-12  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Missing colon in switch from recent porting tweeks.
+
+2005-12-11  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	ifdef profoundly-non-portable signal handling code. Windows has
+	few signals.
+
+2005-12-11  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Hardcode blocksize on win32
+
+2005-12-11  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Reverse ancient VC++ 6.0 template hacks. Microsoft has come toward
+	the standard.
+
+2005-12-05  James Gallagher <jgallagher at opendap.org>
+
+	Updated
+
+2005-11-22  James Gallagher <jgallagher at opendap.org>
+
+	Made docs a PHONY target
+
+2005-11-22  James Gallagher <jgallagher at opendap.org>
+
+	Fixed source0 using Patrice's patch
+
+2005-11-16  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-11-15  James Gallagher <jgallagher at opendap.org>
+
+	Added commentary
+
+2005-11-15  James Gallagher <jgallagher at opendap.org>
+
+	Added/Hacked
+
+2005-11-11  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-11-10  James Gallagher <jgallagher at opendap.org>
+
+	Added note about dejagnu not working on some systems unless
+	config.guess is linked here or at the top.
+
+2005-11-09  James Gallagher <jgallagher at opendap.org>
+
+	The XML schema site has chamged to xml.opendap.org. I stopped
+	testing these values because that's not really what the DDS class
+	unit tests should be looking at.
+
+2005-11-09  James Gallagher <jgallagher at opendap.org>
+
+	The set of chars allowed in an identifier was enlarged to include
+	%. The secind test was altered to fit that.
+
+2005-10-31  James Gallagher <jgallagher at opendap.org>
+
+	Hacked up the pkg target so that the dap-config script has the
+	correct values for the places where the osx package will be
+	installed, not where the build dumps it prior to packaging.
+
+2005-10-25  Patrick West <pwest at ucar.edu>
+
+	added function to access the libdap name from PACKAGE_NAME
+
+2005-10-25  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-10-24  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-10-18  James Gallagher <jgallagher at opendap.org>
+
+	Update from build after failed attempt to remove Pix.h
+
+2005-10-18  James Gallagher <jgallagher at opendap.org>
+
+	Fixed som grammatical problems with the DDX response.
+
+2005-10-12  James Gallagher <jgallagher at opendap.org>
+
+	Updates to the documentation files.
+
+2005-10-07  James Gallagher <jgallagher at opendap.org>
+
+	escattr() no longer uses Regex.
+
+2005-10-07  James Gallagher <jgallagher at opendap.org>
+
+	Updated to match the new libdap behavior for escaping.
+
+2005-10-05  James Gallagher <jgallagher at opendap.org>
+
+	I made the standard print representation of a Grid use Array and
+	Maps instead of ARRAY and MAPS. So I fixed the tests too.
+
+2005-10-05  James Gallagher <jgallagher at opendap.org>
+
+	Don't have these in svn.
+
+2005-10-05  James Gallagher <jgallagher at opendap.org>
+
+	Don't have these in svn.
+
+2005-10-05  James Gallagher <jgallagher at opendap.org>
+
+	Fix for ticket #44 (which was filed under the hdf4 handler). I
+	made the set of characters not escaped by id2www and id2www_ce the
+	same as those that dds.les and expr.lex expect in an id. Actually
+	the asterisk is escaped even though dds.lex will parse it,
+
+2005-10-05  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-10-04  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the background one last time
+
+2005-10-04  James Gallagher <jgallagher at opendap.org>
+
+	Added a background image to the osx installer
+
+2005-10-04  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-10-04  James Gallagher <jgallagher at opendap.org>
+
+	Updates for the OS/X packages stuff.
+
+2005-10-03  James Gallagher <jgallagher at opendap.org>
+
+	Nodified cleanup to not copy the svn parts of dods_cahce_init when
+	it makes dods_cache. This will help keep Eclipse's svn module from
+	being confused.
+
+2005-10-03  James Gallagher <jgallagher at opendap.org>
+
+	Build improvements from Patrice Dumas.
+
+2005-10-03  Patrick West <pwest at ucar.edu>
+
+	calling fflush rather that fclose in send_data
+
+2005-10-01  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-09-30  James Gallagher <jgallagher at opendap.org>
+
+	Updated NEWS with info about regex.
+
+2005-09-30  James Gallagher <jgallagher at opendap.org>
+
+	Updated for the changes to Regex.
+
+2005-09-30  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-09-29  James Gallagher <jgallagher at opendap.org>
+
+	Removed regex from esc2undescore.
+
+2005-09-29  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an error in char2ASCII.
+
+2005-09-29  James Gallagher <jgallagher at opendap.org>
+
+	Grammar update
+
+2005-09-29  James Gallagher <jgallagher at opendap.org>
+
+	Fixes for gnulib regex code.
+
+2005-09-28  Yuan Ho <yuanho at ucar.edu>
+
+	adding install include dir
+
+2005-09-28  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-09-27  Yuan Ho <yuanho at ucar.edu>
+
+	adding install script
+
+2005-09-27  James Gallagher <jgallagher at opendap.org>
+
+	New libtool
+
+2005-09-27  James Gallagher <jgallagher at opendap.org>
+
+	Comment about the hack...
+
+2005-09-27  James Gallagher <jgallagher at opendap.org>
+
+	New grammar generated files and some temporary fixes in gl/m4/regex.m4
+
+2005-09-27  James Gallagher <jgallagher at opendap.org>
+
+	Fixed an error where a signed and unsigned were compared.
+
+2005-09-27  James Gallagher <jgallagher at opendap.org>
+
+	Added new copy.
+
+2005-09-27  James Gallagher <jgallagher at opendap.org>
+
+	New gnulib changes; first half, removing the old gl code. I don't
+	think this was necessary, but it's hard to tell.
+
+2005-09-23  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Fixed install-sh; it was left out of the earlier mv
+
+2005-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Moved the configuration files into 'conf.'
+
+2005-09-22  James Gallagher <jgallagher at opendap.org>
+
+	Changed the das lexer error message to include a character code.
+
+2005-09-19  Patrick West <pwest at ucar.edu>
+
+	missing declaration of BaseType
+
+2005-09-16  James Gallagher <jgallagher at opendap.org>
+
+	Added code to DODSFilter so support its use in something other
+	than a Unix command line filter program. In the process I found a
+	bug in escaping.cc:escattr() (ticket 210) which I fixed.
+
+2005-09-08  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a bug where _REENTRANT is defined and HAVE_STRFTIME is not.
+	This shows up on FC3/4 but not RHEL3 or OS/X.
+
+2005-09-08  James Gallagher <jgallagher at opendap.org>
+
+	Removed
+
+2005-09-08  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-09-07  James Gallagher <jgallagher at opendap.org>
+
+	Build update
+
+2005-09-07  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-09-06  James Gallagher <jgallagher at opendap.org>
+
+	Added alloc to gl_MODULES; for the os/x build.
+
+2005-09-06  James Gallagher <jgallagher at opendap.org>
+
+	Added the new gl directory.
+
+2005-09-06  James Gallagher <jgallagher at opendap.org>
+
+	Clean up.
+
+2005-09-06  James Gallagher <jgallagher at opendap.org>
+
+	Midway through resetting gl to only use the regex code.
+
+2005-09-03  James Gallagher <jgallagher at opendap.org>
+
+	Auto reset of Subversion properties
+
+2005-08-19  James Gallagher <jgallagher at opendap.org>
+
+	Updated libdap.spec so that it now requires libcurl 7.10.6 (a
+	downgrade from 7.12.0 so that we can build RPMs on RHEL3). This
+	seems to work just fine. Also fixed up the HTPPCacheTest unit test
+	so that it works the first time with a new check out.
+
+2005-08-19  James Gallagher <jgallagher at opendap.org>
+
+	downgrade to libcurl-7.10.6. This seems to work but needs more testing
+
+2005-08-17  James Gallagher <jgallagher at opendap.org>
+
+	Another shot at getting the build to work...
+
+2005-08-17  James Gallagher <jgallagher at opendap.org>
+
+	Build fixes; rpms now split into plain and -devel; fix for
+	libdap.m4 macro
+
+2005-08-16  James Gallagher <jgallagher at opendap.org>
+
+	Patched libdap.m4 (from Patrice) and added text the README
+	describing the macro.
+
+2005-08-16  James Gallagher <jgallagher at opendap.org>
+
+	Commented out the set of CFLAGS/CXXFLAGS (which was a left-over
+	from the non-automake build).
+
+2005-08-15  James Gallagher <jgallagher at opendap.org>
+
+	Updated for the release of 3.5.2.
+
+2005-08-12  James Gallagher <jgallagher at opendap.org>
+
+	Added back.
+
+2005-08-12  James Gallagher <jgallagher at opendap.org>
+
+	Test delete
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	config_dap.h --> config.h; also removed TRACE_NEW, #pragma
+	interface/impl. in test and unit-tests.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Removed trace_new.h; use valgrind instead.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Removed #pragma interface/implementation
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	So, I added IteratorAdapter.cc back in again.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Hmmm... Eclipse still doesn't seem to get the deletes quite right.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Tests updated for new float32 and 64 value computation.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Changed how sequential values are generated. The values should be
+	the same on 32 and 64-bit machines.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Updated...
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	I removed the DODS_GTAR and DODS_PERL calls; Added AC_DEFINE for
+	two version sof libxml2 and stripped away some code that was
+	commented out months ago.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Resolved conflicts & added some comments about the state of the
+	test driver.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Clarified commentary.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Added conditional compilation of the XML SAX callback struct. The
+	code now uses the library version number to determine which fields
+	should be included since later version have additional fields.
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Removed unused params in methods as reported by gcc 3.4. This may
+	break gcc 3.2, we will see...
+
+2005-08-11  James Gallagher <jgallagher at opendap.org>
+
+	Removed unused params in methods as reported by gcc 3.4. This may
+	break gcc 3.2, we will see...
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Changed comparison in set_max_size() so that it uses ULONG_MAX
+	(since the method uses a long) and does not test for negative
+	sizes (since size is unsigned).
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Moved debug options from AM_CXXFLAGS. Set the CXXFLAGS environment
+	variable (sample values are assigned to CXXFLAGS_DEBUG).
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	commented out #define DODS_DEBUG 1
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Reverted to previous version (which uses long instead of int). The
+	change breaks the unit tests (which otherwise work on both 32- and
+	64-bit machines.
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Latest and greatest eclipse/cdt settings...
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Addressed various warnings from gcc (compiled using -Wall -W
+	-Wcast-align) as part of making the code 64-bit clean.
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Added default init of TestCommon in the copy ctors for the
+	TestByte, ... classes.
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Added proper error return to all unit tests.
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Now GNURegex uses exceptions (std::invalid_argument and domain_error)
+	to signal problems. Controlled using USE_EXCEPTIONS. If this passes
+	on the nightly builds, then remove GNUerror.cc and builtin.h.
+
+2005-08-10  James Gallagher <jgallagher at opendap.org>
+
+	Fixed read() method: It did not include the 16-bit int types int
+	he switch statement.
+
+2005-08-08  James Gallagher <jgallagher at opendap.org>
+
+	Fixed a leak where a specialization of BaseTypeFactory was used
+	but not deleted.
+
+2005-08-08  root
+
+	Auto reset of Subversion properties
+
+2005-07-28  James Gallagher <jgallagher at opendap.org>
+
+	Changes for the OS/X build. Particularly for the regex code in gl.
+
+2005-07-25  James Gallagher <jgallagher at opendap.org>
+
+	Fixed; the macro was using ifelse and m4_syscmd/m4_sysval but
+	these didn't seem to be working. Also replaced obsolete AC_TRY_TUN
+	with AC_RUN_IFELSE().
+
+2005-07-23  James Gallagher <jgallagher at opendap.org>
+
+	Added libdap.m4: A macro that other packages can use to check for
+	the library. From Patrice Dumas.
+
+2005-07-22  James Gallagher <jgallagher at opendap.org>
+
+	Updated requirements for automake, et cetera.
+
+2005-07-22  James Gallagher <jgallagher at opendap.org>
+
+	Updated for automake 1.9.6.
+
+2005-07-21  James Gallagher <jgallagher at opendap.org>
+
+	Removed calls to OK() in the set_error_code() and
+	set_error_message() methods since these are called by the parser
+	on partially built objects.
+
+2005-07-20  James Gallagher <jgallagher at opendap.org>
+
+	Improved the documentation of BaseTypeFactory; removed
+	DEFAULT_BASETYPE_FACTORY from Makefile.am; added a note to
+	util.cc:prune_spaces questioning if that function is still needed;
+	added a test of prune_spaces to generalUtilTest.
+
+2005-07-20  James Gallagher <jgallagher at opendap.org>
+
+	Removed DEFAULT_BASETYPE_FACTORY switch. Updated build files using
+	autoreconf --install --force (using automake 1.9.2 from FC3).
+
+2005-07-19  James Gallagher <jgallagher at opendap.org>
+
+	Updated cdtproject file. Should this be in SVN?
+
+2005-07-19  James Gallagher <jgallagher at opendap.org>
+
+	Added gl/m4 to EXTRA_DIST; needed to get the distcheck target workig
+	with automake 1.6.3. Newer versions of automake set this correctly
+	given that ACLOCAL_AMFLAGS is used.
+
+2005-07-18  James Gallagher <jgallagher at opendap.org>
+
+	Removed $(top_srcdir) from ACLOCAL_AMFLAGS since this breaks
+	autoreconf.
+
+2005-07-18  James Gallagher <jgallagher at opendap.org>
+
+	Changed ACLOCAL_AMFLAGS from '-I gl/m4' to '-I $(top_srcdir)/gl/m4' to
+	fix one last problem with distcheck.
+
+2005-07-18  James Gallagher <jgallagher at opendap.org>
+
+	Applied Patrice's patch for unit-tests; make distcheck should now work.
+
+2005-07-18  James Gallagher <jgallagher at opendap.org>
+
+	Changed the cache dirs with initial values to <cache>_init and use
+	the cleanup.sh script to cp -r <*>_init <*> to restore them. This
+	way the tests work w/o svn.
+
+2005-07-18  James Gallagher <jgallagher at opendap.org>
+
+	Added blurb about using autoreconf to (re)build the autotools stuff.
+
+2005-07-15  James Gallagher <jgallagher at opendap.org>
+
+	Updated Makefile.am and the README/INSTALL/NEWS files. The 'dist'
+	target now works for make (although 'distcheck' fails for an odd
+	reason).
+
+2005-07-15  James Gallagher <jgallagher at opendap.org>
+
+	Copied/added
+
+2005-07-15  James Gallagher <jgallagher at opendap.org>
+
+	Removed
+
+2005-07-15  James Gallagher <jgallagher at opendap.org>
+
+	Moved/Added
+
+2005-07-15  James Gallagher <jgallagher at opendap.org>
+
+	Moved the unit tests from 'tests' to 'unit-tests.' The unit tests
+	are now only run when you cd into unit-tests and use make check.
+	This change was made because those tests use network services
+	which might not be present on some hosts used to build the
+	package.
+
+2005-07-15  James Gallagher <jgallagher at opendap.org>
+
+	More fixes for the tests
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	Fixed again...
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	Removed extra line. This hosed the test since it causes the
+	HTTPCache class to think there's a second zero-size entry.
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	Updated
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	Updated
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	Updated
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	Changed URL; chages cache directory number
+
+2005-07-14  James Gallagher <jgallagher at opendap.org>
+
+	AISMergeTest now works (required files are now installed on
+	test.opendap.org). Also, applied Patrice Dumas' patch for the
+	Makefile.am.
+
+2005-07-13  James Gallagher <jgallagher at opendap.org>
+
+	Fixed HTTPConnectTest
+
+2005-07-13  James Gallagher <jgallagher at opendap.org>
+
+	Spec file now includes support for a separate devel package
+	(commented out). From Patrice Dumas.
+
+2005-07-13  James Gallagher <jgallagher at opendap.org>
+
+	expr-test tests x, xa, xc, y, ya, and yc now expect to fail (and
+	do on 64bit hosts).
+
+2005-07-13  James Gallagher <jgallagher at opendap.org>
+
+	The last fix for this file? I hope so...
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	Added data files for tests in DDSTest. Bug 112.
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	mistakenly removed alloca_.h from svn. Fixed tests/cache_testsuite.
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	Test updates: expr-test now works except that 6 tests fail on
+	64bit machines. Also, I updated the gnulib replacement functions
+	so that gnulib-tool can be used in the future to update. I moved
+	the gnulib functions into the 'gl' subdir and put the m4 macros in
+	there inside the subdir 'gl/m4.' There's a note about the
+	procedure to use to update the functions in INSTALL.
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	Added again...
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	removed
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	Removed
+
+2005-07-12  James Gallagher <jgallagher at opendap.org>
+
+	Removed.
+
+2005-07-11  James Gallagher <jgallagher at opendap.org>
+
+	My previous fix for the gnulib mktime bug was bogus since it left
+	a replacement copy of mktime in the library using that name (which
+	is reserved). I've stopped using the gnulib mktime for now since
+	it doesn't seems absolutely necessary.
+
+2005-07-11  James Gallagher <jgallagher at opendap.org>
+
+	Modification from Patrice, et al. These were part of an attempt to work
+	around a bug with using mktime but they did not work.
+
+2005-07-08  James Gallagher <jgallagher at opendap.org>
+
+	Moved all tests to the 'tests' subdirectory. There are some tests
+	that are broken; only expr-test seems broken now but was not
+	before. Most of the broken tests require a localhost web daemon
+	and specific test files for it to serve; configure
+	test.opendap.org for these instead.
+
+2005-07-08  James Gallagher <jgallagher at opendap.org>
+
+	Removed use of the GPL regex-0.12 code and switched to gnulib
+	(which provides regex and other functions which are covered by
+	LGPL). These turned out to be fairly massive changes. The work was
+	done by Patrice Dumas (Thanks!). I removed a AC_DEFINE macro in
+	m4/mktime.m4 to work around a compilation problem when using
+	gnulib's mktime.c replacement function.
+
+2005-07-06  Patrick West <pwest at ucar.edu>
+
+	Added methods to Connect class to connect with the given URL
+	instead of building the URL to connect with, such as adding .das,
+	.dds, etc...
+
+2005-07-05  Rob Morris <Robert.O.Morris at jpl.nasa.gov>
+
+	Set eol-style to native on all text file in the trunk
+
+2005-07-05  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the library version numbers. The order was backwards for the
+	last two digits.
+
+2005-07-04  James Gallagher <jgallagher at opendap.org>
+
+	Added Patrice Dumas' patches for libtool, et cetera.
+
+2005-07-01  James Gallagher <jgallagher at opendap.org>
+
+	Moved the unit tests into the tests subdirectory.
+
+2005-07-01  James Gallagher <jgallagher at opendap.org>
+
+	After adding libtool support, I ran autoreconf --force --install
+	which in turn ran libtoolize. this updated a number of the support
+	code for the build. Added ltmain.sh.
+
+2005-07-01  James Gallagher <jgallagher at opendap.org>
+
+	Added. These generated files should be in svn.
+
+2005-07-01  James Gallagher <jgallagher at opendap.org>
+
+	Added support for libtool using a patch from Patrice Dumas.
+
+2005-07-01  James Gallagher <jgallagher at opendap.org>
+
+	Set exec
+
+2005-07-01  James Gallagher <jgallagher at opendap.org>
+
+	ModifiedMakefile.am so that the dejagnu_driver.sh script now works.
+
+2005-06-30  James Gallagher <jgallagher at opendap.org>
+
+	Automake changes; these work and build the tests. the DejaGNU test
+	support has not been tested yet but the unit tests all run and the
+	dejagnu drivers all build.
+
+2005-06-30  James Gallagher <jgallagher at opendap.org>
+
+	Switched to automake. Not complete but functional.
+
+2005-06-30  James Gallagher <jgallagher at opendap.org>
+
+	Applied patch from Patrice Dumas for the automake build.
+
+2005-06-22  James Gallagher <jgallagher at opendap.org>
+
+	Added for automake build
+
+2005-06-22  James Gallagher <jgallagher at opendap.org>
+
+	Started work on an automake file for this code; only partly done.
+	The library builds but nothing else is in place. The grammars are
+	in progress. They build but the way gse is handled is the the way
+	they all should be unless I can get automake's lex/yacc rules to
+	work. See Makefile.am.in_progress and configure.ac.for_am. Also
+	included in this check in is a patch to libdap.spec from Patrice
+	Dumas.
+
+2005-06-22  James Gallagher <jgallagher at opendap.org>
+
+	Remove the attempts to utilize automake's support for bison/flex
+	introduced in the past 9 revisions.
+
+2005-06-21  James Gallagher <jgallagher at opendap.org>
+
+	moved...
+
+2005-06-21  James Gallagher <jgallagher at opendap.org>
+
+	checkpoint
+
+2005-06-21  James Gallagher <jgallagher at opendap.org>
+
+	moved from *.lex files for automake
+
+2005-06-21  James Gallagher <jgallagher at opendap.org>
+
+	Moved from gse.lex for automake
+
+2005-06-20  James Gallagher <jgallagher at opendap.org>
+
+	Fixed the source path.
+
+2005-06-20  James Gallagher <jgallagher at opendap.org>
+
+	Commented out the Patch: and %patch lines since the patched code is
+	now in svn.
+
+2005-06-20  James Gallagher <jgallagher at opendap.org>
+
+	Accepted patches from Patrice Dumas <pertusus at free.fr> which
+	improve the build by using the system's regex library if found.
+	Also included in the patches were improvements to the rpm spec
+	file; the file now uses the fedora template and includes a fix for
+	Mandrake ('Tue' --> 'Tues' in the change log.
+
+2005-06-15  James Gallagher <jgallagher at opendap.org>
+
+	Fixed configure so that it does not include -gstabs on OS/X.
+
+2005-06-15  James Gallagher <jgallagher at opendap.org>
+
+	Changed eol-style, mime-type, other properties. Removed generated
+	files from svn. Modified configure.ac so that it tests for bison
+	and does not use bison -y.
+
+2005-06-15  James Gallagher <jgallagher at opendap.org>
+
+	Generated... Should these even be in SCM?
+
+2005-05-23  James Gallagher <jgallagher at opendap.org>
+
+	Removed cast to int at tokenlength = ... to avoid a warning about
+	differring pointer and int sizes on x86 64-bit CPUs.
+
+2005-05-23  James Gallagher <jgallagher at opendap.org>
+
+	Now uses local common-tests.exp and test.opendap.org.
+
+2005-05-23  James Gallagher <jgallagher at opendap.org>
+
+	Tests now use the local copy of common-tests.exp.
+
+2005-05-23  James Gallagher <jgallagher at opendap.org>
+
+	Reformat using indent and indent-eclipse plugin.
+
+2005-05-17  Patrick West <pwest at ucar.edu>
+
+	updated dap_version using libdap_version
+
+2005-05-13  James Gallagher <jgallagher at opendap.org>
+
+	3.5.1
+
+2005-05-13  James Gallagher <jgallagher at opendap.org>
+
+	3.5.1
+
+2005-05-13  James Gallagher <jgallagher at opendap.org>
+
+	checkpoint
+
+2005-05-12  James Gallagher <jgallagher at opendap.org>
+
+	moved
+
+2005-05-12  James Gallagher <jgallagher at opendap.org>
+
+	Renamed libdap-config to dap-config to fall in line more with what
+	other projects are doing.
+
+2005-05-12  James Gallagher <jgallagher at opendap.org>
+
+	05/12/05 jhrg
+
+2005-05-12  James Gallagher <jgallagher at opendap.org>
+
+	Modified install so that it no longer appends a version number to the
+	static library or includes. When we build a dynamic lib, look into the
+	version number thing then.
+
+2005-05-11  James Gallagher <jgallagher at opendap.org>
+
+	5/11/05
+
+2005-05-10  James Gallagher <jgallagher at opendap.org>
+
+	Changed to work with rpm. Don't alter the values of variables like
+	$includedir because values for these are passed into make by
+	rpmbuild, overriding the values set by the here. This was
+	happening with $includedir which had the string '/libdap' appended
+	early on in the Makefile and then @PACKAGE_VERSION@ appended in
+	the install-header target. When 'make' was run from the command
+	line, this worked OK, but not when rpmbuild passed in a new value
+	for $includedir.
+
+2005-05-10  James Gallagher <jgallagher at opendap.org>
+
+	Added
+
+2005-05-10  James Gallagher <jgallagher at opendap.org>
+
+	5/10/2005
+
+2005-05-10  James Gallagher  <jimg at zoey.opendap.org>
+
+	* libdap.spec (Prefix): Built spec file; tested. Some problems
+	remain, mostly that the curl and xml2 packages are not part of
+	the RHEL3 dist! I'll have to sort that out before this dist
+	mechanism becomes a reality.
+
+2005-04-15  James Gallagher  <jimg at comet.opendap.org>
+
+	* Removed include of config_dap.h from HTTPCache.h. This is the
+	only header file in the library that includes the config header.
+	Removing the include means that users of the library never see the
+	library's internal configuration. There's a potential problem with
+	this, however, in that users of the library must now use
+	opendap-config --cflags when building _or_ define HAVE_PTHREADS_H
+	themselves. I can make this last requirement go away if pthreads
+	becomes required for libdap++ (then the code won't need the
+	compile time symbol).
+
+2005-02-08  James Gallagher  <jimg at comet.dods.org>
+
+	* Merged with release-3-4-10
+
+2005-02-08  James Gallagher  <jimg at comet.dods.org>
+
+	* bumped the version up to 3.4.10; tagged.
+
+	* System upgrade to FC3/gcc-3.4; minor fixes for the build.
+
+2005-01-28  James Gallagher  <jimg at comet.dods.org>
+
+	* Merged with release-3-4-9.
+
+2005-01-27  James Gallagher  <jimg at comet.dods.org>
+
+	* Added code to Test* classes so that Sequences are easier to
+	test. These classes now return values similar to Nathan's DTS code
+	on the Java module (although not exactly the same).
+
+	* Fixed the way Sequence CEs are handled when Sequences are
+	nested. Tested to three levels deep. The serialization code in
+	Sequence is nw quite complex.
+
+	* Incremented version to 3.4.9; I've made some changes since the
+	last version and I need these in the trunk to test.
+
+2004-07-07  James Gallagher  <jimg at comet.dods.org>
+
+	* Merged with release-3-4-8FCS.
+
+2004-07-06  James Gallagher  <jimg at comet.dods.org>
+
+	* Bumped the version to 3.4.8.
+
+2004-07-02  James Gallagher  <jimg at comet.dods.org>
+
+	* I removed (commented) the pragma interface/implementation lines.
+	This increases the size of the library by ~1MB, which seems pretty
+	insignificant at this point. The change means that the code will
+	compile on HP/UX with gcc 3.2. It _may_ be that gcc 3.4 fixes this
+	problem, but it seems that the pragmas cause more headaches than
+	they are worth. It should be easy to 'add them back in' if we
+	decide to do that, since they are just commented out. 
+
+2004-03-11  James Gallagher  <jimg at comet.dods.org>
+
+	* Bumped the version to 3.4.7.
+
+	* I fixed a problem in SignalHandler and RCReader. Both od=f these
+	class had code that re-initialized a pthread_once_t mutex in their
+	delete_instance() method. This was used by some unit tests to make
+	a delete instances of these two singleton classes. The problem is
+	that while this runs (sort of, we had some reports of
+	crash-on-exit behavior) on Linux, it fails outright on Solaris. As
+	Rob M points out, it's a non-standard use of pthreads. I removed
+	the re-init and changed the unit tests. 
+
+2004-02-18  James Gallagher  <jimg at comet.dods.org>
+
+	* Merge release-3-4-2FCS.
+
+2004-02-16  James Gallagher  <jimg at comet.dods.org>
+
+	* Other fixes:
+	The DBG() macros now include namespace std declarations.
+	Used valgrind to isolate some memory leaks; others remain and this
+	will be an on-going process.
+	Made sure all calls to delete also set the pointer to null; this
+	fixes some dual-delete bugs.
+	Some of the doxygen comments have been improved.
+	Fixed places were the switch from strstream to stringstream was
+	botched. 
+
+	* Fixed the following bugs since version 3.4.5:
+	696: Infinite loop in the HDF4 server (w/character variables).
+	698: libdap++ now returns better error messages when the httpd
+	reports an error.
+	692: The info response now works.
+	695: The client-side cache is more robust. It does not leave cruft
+	around when a user interrupts a program.
+	691: Error responses were not parsed/processed correctly when
+	received by clients in some circumstances. Now they are.
+
+2004-01-30  James Gallagher  <jimg at comet.dods.org>
+
+	* usage.cc: Fixed bug 692. Only one global attribute and one
+	variable were output. The cause: ends operators left over from the
+	strstream code...
+
+2004-01-22  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added namespace std declarations to some files. The DBG() macro
+	uses cerr and thus the std namespace or std::cerr must be declared
+	for newer compilers.
+
+2003-12-08  Yuan Ho  <yuanho at ucar.edu>
+
+        * Merge release-3-4 into trunk.
+
+2003-11-10  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added the methods Float32::value() and Float64::value(). I think
+	the DAP should have a suite of methods which return values w/o
+	using the awkward void pointer scheme. These methods (will) require
+	a downcast unlike the void pointer methods. But they wind up being
+	much easier to use in situations where you know the type of the
+	BaseType object (which seems to be most of the time, in practice).
+
+2003-10-03  James Gallagher  <jimg at dcz.dods.org>
+
+	* I changed Connect's request_das, ..., methods so that they now
+	treat a response that lacks a Content-Description header
+	identifying the response as one of ours as a fatal error.
+
+	* I Fixed what seems like, in hindsight, a bug. The scanners were
+	treating illegal characters as non-fatal errors and writing
+	messages on stderr. In reality the scanners should have been
+	flagging those responses as bogus. Also, the scanners were using
+	exit(1) when they found a fatal error; I changed that so they now
+	throw an Error object.
+
+2003-09-19  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed bug #655. Here's how the DAP library looks for the RC
+	file: First it checks the env variable DODS_CONF, then HOME. If
+	neither is set it uses default values and disables the cache.
+	Here's how DODS_CONF is used: If it is the name of a file that
+	exists, use that as the RC file. If DODS_CONF names a directory,
+	look in that directory for a file called '.dodsrc'. If that file
+	exists, it uses it, otherwise try to create it using default
+	values *except* that the value of CACHE_ROOT is the directory part
+	of DODS_CONF with '.dods_cache/' appended. If DODS_CONF is not set
+	to any value, the code looks at HOME and applies the same rules as
+	for DODS_CONF (except that HOME should never be the name of a file
+	so some of the rules don't really apply). We may need to tune this
+	code for WIN32.
+
+	Note that caching is off by default and a .dodsrc created by the
+	library will have USE_CACHE set to zero. Users must actively turn
+	caching on by editing the RC file.
+
+2003-09-08  James Gallagher  <jimg at dcz.dods.org>
+
+	* HTTPConnect.cc (fetch_url): Fixed bug #661.
+
+2003-08-29  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added a new property to BaseType which can be used to
+	differentiate between variables that must be read by a server
+	because they are in the projection and those which must be read
+	because they are used in a selection clause or as a function
+	argument. Previously we were using the send_p property for both
+	these and it was causing problems when CEs contained both
+	projected variables and functions (see bug #657). The new property
+	is called 'in_selection' and is true if the variable is part of
+	the current CE's selection or is used in any type of CE function.
+	Servers should ensure that if their read() method implementation
+	test send_p before reading data they also test in_selection. Data
+	values should be read it *either* property is true. This fixes bug
+	#657.
+
+2003-07-28  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added support for Digest authentication. There's also potential
+	support for NTLM and GSS-Negotiate authentication, but I don't
+	have any way to test those. 
+
+2003-07-24  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added a new test driver called server_handler. It's much more
+	like a server's handler executable; combine it with geturl reading
+	from stdin to make tests. See also sh-testsuite. Nascent but still
+	useful. 
+
+	* DDS:send() has been incorporated into DODSFilter::send_data() as
+	part of a refactoring of DDS.
+
+	* Timeouts are now smart.
+
+2003-07-23  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added a timeout mechanism to the server and modified the Test*
+	classes so this is easier to test. Right now it's a pretty
+	rudimentary thing. However, the timeout can be set in the newly
+	expanded dods.rc configuration file. In the future when we have
+	reliable Error delivery this code will send an Error object that
+	explains that there was a time out, et cetera. Check out the
+	ChangeLog in DODS/etc for information about the expanded dods.rc file.
+
+2003-05-15  James Gallagher  <jimg at dcz.dods.org>
+
+	* Removed the List class/datatype. We've talked about this for
+	months (years). Done.
+
+2003-05-13  James Gallagher  <jimg at dcz.dods.org>
+
+	* Modified DODSFilter so that it takes a new switch, -o, which can
+	be used to tell a handler which object is to be returned. Handlers
+	can now be built which return all of the responses; the
+	DODS_Dispatch CGI module tells the hander which response to
+	generate. 
+
+2003-04-21  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged release-3-3-1.
+
+	* The RCReader class now supports using the environment variable
+	DODS_CONF to point toward a dodsrc file. The value of the envar
+	supersedes the default ~/.odsrc.
+
+	* In HTTPCache: changed catch(...) clauses so that they explicitly
+	name exceptions. The code was catching and re-throwing exceptions
+	and in methods where the types of exceptions were caught this
+	caused abort to be called, even when the re-thrown exception was
+	one of the declared types.
+
+	* Several bugs in the grid() function were fixed. First, the
+	function was not checking to make sure that map vectors using in
+	the selection sub-expressions passed to grid() actually existed.
+	Also, the mechanism used to read values of variables used as
+	arguments to CE functions was broken; constructor types were not
+	completely read but *were* marked as though they were. Look in
+	RValue for the latter fix.
+
+	* Some of the unit tests included code that wouldn't compile with
+	gcc 3.2.x; fixed. I'm now using gcc 3.2.2 for development (but
+	nightly builds also continue with 2.95.3 and VC++ as well).
+
+	* Added methods to DAS, AttrTable and DDS so that an integer index
+	can be used to access variables and attributes. This was done so
+	that the idl command-line client could iterate over instances
+	without actually having to work with C++ iterator objects.
+
+	* IteratorAdapter is no longer templated. This change was made to
+	accommodate the MS VC++ compiler. Also, doxygen comments have been
+	added to the code.
+
+2003-01-23    <jimg at dcz.dods.org>
+
+	* Made release 3.3.0. Not merged since there were very, very few
+	changes. 
+
+2003-01-22    <jimg at dcz.dods.org>
+
+	* I changed the source files so that they are clearly covered by
+	the GNU Lesser GPL.
+
+2003-01-10    <jimg at dcz.dods.org>
+
+	* NEWS: Added.
+
+	* Merged with changes tagged release-3-2-10 (from the release-3-2
+	branch). 
+
+2002-08-08    <jimg at dcz.dods.org>
+
+	* I Replaced the single VirtualCtors.cc file, which had a virtual
+	constructor for each of the data type classes in it (see Meyers
+	for a discussion of virtual ctors), with a set of files with one
+	virtual ctor per file. The old VirtualCtors.o file was *not*
+	included in the libdap++ library because of link-time problems it
+	would introduce. The new files *are* included. For any of the
+	data type classes you specialize, you must provide a virtual ctor
+	that returns an instance of your specialization. For any of the
+	data types you do *not* specialize, the library will use the
+	default virtual ctor.
+
+	* The library libdap++.a is now `apartment thread safe.' The
+	phrase comes from Microsoft's documentation; it means that the
+	library can be used in a limited sense with MT software. The limit
+	is that objects created using the library cannot be shared by
+	threads. A MT program can create several instances of Connect, for
+	example, but each instance can only be used by a single thread.
+
+2002-06-21    <jimg at dcz.dods.org>
+
+	* Connect.cc: Fairly extensive additions to Connect's interface.
+	The old interface is still supported, but its use is deprecated.
+
+	* VirtualCtors.cc: Added this file. It can be linked with clients
+	so that they don't have to provide definitions for the NewByte(),
+	..., NewGrid() 'virutal constructor' functions. This will work
+	only for those clients that don't need to subclass the various
+	types. There maybe a better way to do this; either use a real
+	factory class passed to DDS or by putting each of the New*()
+	virtual ctors in its own file and adding those to the library.
+	That way the linker will only extract them if they are needed. 
+
+2002-06-11    <jimg at dcz.dods.org>
+
+	* expr.y (process_array_indices): Arrays and Grids can no longer
+	be partially constrained (those constraints didn't work).
+
+2002-06-10    <jimg at dcz.dods.org>
+
+	* das.lex: Added '*' to the set of chars allowed in a WORD. Same
+	for dds.lex.
+
+2002-06-05    <jimg at dcz.dods.org>
+
+	* usage.cc: Modified so that option inforamtion passed in by
+	DODS_Dispatch.pm gets passed onto the filter programs (see bug 453).
+
+
+
+2002-06-03    <jimg at dcz.dods.org>
+
+	* Sequence.cc (print_all_vals): Removed Sequence::level and
+	set_level() methods and the private _level field.
+
+	* dods-limits.h (DODS_ULONG_MAX): Added U suffix to unsigned
+	numerical constants.
+
+2002-05-31    <jimg at dcz.dods.org>
+
+	* das.y: Bug 450; The reserved word attributes can now be used as
+	an attribute name.
+
+2002-05-28    <jimg at dcz.dods.org>
+
+	* Makefile.in: Geturl is no linked without the Test* classes. This
+	demonstrates that libdap++ can be used without subclassing. Look
+	at geturl.cc for an example. Of course, there are limitations on
+	what you can do without subclassing the data types...
+
+	* geturl.cc: Geturl no longer links with the Test* classes. It was
+	modified so that it can use the versions of the classes that are
+	part of libdap++.a (which is a recent change to the library). The
+	geturl.cc file now contains the `virtual ctors' used by the
+	library to instantiate the instances of the various variables.
+
+2002-05-26    <jimg at dcz.dods.org>
+
+	* Connect.h: Removed code specific to the GUI-based progress
+	indicator. 
+
+	* Error.h: Removed code specific to the GUI-based progress indicator.
+
+2002-05-22    <jimg at dcz.dods.org>
+
+	* Byte.h, Byte.cc, ..., Grid.h, Grid.cc: It is no longer necessary
+	to subclass the data type classes when building a client.
+
+2002-05-10    <jimg at dcz.dods.org>
+
+	* Connect.cc (www_lib_init): Joe Sirott found and fixed a bug when
+	making (many) multiple requests.
+
+2002-05-09    <jimg at dcz.dods.org>
+
+	* BaseType.cc (read): This method is not longer abstract.
+
+	* usage.cc (main): Fixed a bug triggered when PATH lacks `.'
+	
+2002-04-30    <jimg at dcz.dods.org>
+
+	* Merged with release-3-2-9
+
+2002-04-03    <jimg at dcz.dods.org>
+
+	* Makefile.in (binary-tar): Fixed binary-tar target.
+
+	* BaseType.cc: Added using std::endl and ::ends
+
+2002-04-02    <jimg at dcz.dods.org>
+
+	* DDS.cc: Fixed broken use of using std::strstream.
+
+	* Connect.cc (server_handler): Fixed bug 416.
+
+2002-03-27    <jimg at dcz.dods.org>
+
+	* usage.cc (write_global_attributes): Fixed usage's output of
+	nested attributes.
+
+2002-03-12    <jimg at dcz.dods.org>
+
+	* Bug 400 fixed.
+
+	* Servers now should recognize that a file called `das' in a
+	directory with data files is an ancillary DAS for any of those
+	files. If an ancillary DAS exists that has a more speciific name,
+	that file will be used instead of the directory-wide DAS.
+
+2001-10-13  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with release-3-2-8.
+
+	* Various bug fixes.
+
+	* Connect now uses exceptions to signal errors for all network I/O.
+
+2001-10-01  James Gallagher  <jimg at dcz.dods.org>
+
+	* Changed serialize and deserialize so that they use exceptions to
+	signal errors. The return values can be ignored. For backward
+	compatibility serialize always returns true and deserialize always
+	returns false (even though that's counter intuitive, that's the
+	old behavior for `no more data to read').
+
+2001-09-28  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with release 3.2.7. The next merge should use
+	release-3-2-7 -j release-3-2.
+
+2001-09-26  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a bug in the progress indicator's cancel button that
+	caused a crash.
+
+	* Fixed the grid() server-side function. This function can be used
+	in constraint expressions to *select* parts of Grid variables
+	based on the values of their map vectors. Here's an example using
+	the COADS dataset: The dataset can be found at:
+	http://dcz.dods.org/dods-3.2/nph-dods/data/nc/coads_climatology.nc.
+	Look at the DDS and at the Grid SST:
+	    Dataset {
+		Float64 COADSX[COADSX = 180];
+		Float64 COADSY[COADSY = 90];
+		Float64 TIME[TIME = 12];
+		Grid {
+		 ARRAY:
+		    Float32 SST[TIME = 12][COADSY = 90][COADSX = 180];
+		 MAPS:
+		    Float64 TIME[TIME = 12];
+		    Float64 COADSY[COADSY = 90];
+		    Float64 COADSX[COADSX = 180];
+		} SST;
+		...
+	    } coads_climatology;
+	From the attribute object you can find out about the map vector's
+	ranges: 
+            Attributes {
+		COADSX {
+		    String units "degrees_east";
+		    String modulo " ";
+		    String point_spacing "even";
+		}
+		COADSY {
+		    String units "degrees_north";
+		    String point_spacing "even";
+		}
+	    ...
+	Using the grid function you can ask for the part of SST that falls
+	between 30 and 50 degrees east and greater than 20 degrees north
+	using: grid(SST,"30<COADSX<50","20<=COADSY") as the constraint
+	expression. Note that two different styles of mini-expressions are
+	supported by the function. Requests outside the range of the map
+	vectors returns a message indicating their extent.
+
+2001-09-06  James Gallagher  <jimg at dcz.dods.org>
+
+	* Sequence::deserialize(...) now reads all the sequence values at
+	once. Its call semantics are the same as the other classes'
+	versions. Values are stored in the Sequence object using a
+	vector<BaseType *> for each row (those are themselves held in a
+	vector). Three new accessor methods have been added to Sequence
+	(row_value() and two versions of var_value()).
+	BaseType::deserialize(...) now always returns true. This matches
+	with the expectations of most client code (the seqeunce version
+	returned false when it was done reading, but all the calls for
+	sequences must be changed anyway). If an XDR error is found,
+	deserialize throws InternalErr. This fixes bug 258.
+
+
+2001-08-21  James Gallagher  <jimg at dcz.dods.org>
+
+	* After running tests for asciival, I decided to allow some more
+	characters in the CE part of a URL. I created id2www_ce which
+	allows all the characters in id2www plus [], {}, :, &, <>, = and
+	, (comma).
+
+2001-07-27  James Gallagher  <jimg at dcz.dods.org>
+
+	* New escaping semantics. The DAP library now supports escaping
+	names. Servers (and clients) no longer need to escaping characters
+	themselves. The functions used to escape characters have been
+	changed, too. The old functions escaped chars that could not be
+	included in a DAP URL. The new function only escape chars that
+	cannot be present in a URI as defined by RFC 2396 (``Uniform
+	Resource Identifiers (URI): Generic Syntax''). The DAP's scanners
+	and parsers have been expanded so that many more characters are
+	now allowed. The regular expressions used to define IDs and NAMEs
+	are: 
+	    ID	 [a-zA-Z_/%.][-a-zA-Z0-9_/%.#:+\\]*
+	    NAME [a-zA-Z_/%.0-9][-a-zA-Z0-9_/%.#:+\\]*
+	These changes mean that datasets which contain IDs with spaces
+	will work. Note that a space is not allowed in a URI so it will be
+	escaped. If you're typing in a URL to a browser, you must supply
+	the %20 escape. However, Connect is smart enough to escape the
+	space if it's present in a CE. On the server-side, DODSFilter and
+	the type classes remove the escape.
+
+2001-07-10  James Gallagher  <jimg at dcz.dods.org>
+
+	* If the `read from a file or stdin' feature of geturl is used and
+	the input source cannot be opened, an error message is printed.
+	This fixes a bug where a null input data source pointer caused a
+	segmentation violation. I also added a throw to
+	Connect::read_data() so that other clients that don't test the
+	data source pointer (which is a FILE *) will get an exception (as
+	opposed to a core file).
+
+2001-06-22  James Gallagher  <jimg at dcz.dods.org>
+
+	* I added `#' to the set of characters allowed in IDs. See bug 179.
+
+	* I normalized the definitions of ID, FLOAT and NEVER in the four
+	main scanners in the DAP library. They now all share the same set
+	of characters except for a few odd outliers.
+
+2001-06-18  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a bug that crept into the processing of the server's
+	version number information in the (client) class DataDDS. This
+	made it impossible for clients to process Sequences sent from
+	new servers because they we using the old (default)
+	deserialization scheme.
+
+2001-06-15  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with release-3-2-4. The next merge should use -j
+	release-3-2-4 -j release-3-2.
+
+2001-06-05  James Gallagher  <jimg at dcz.dods.org>
+
+	* das.y: Changed the way errors are handled. Many errors still
+	cause exceptions to be thrown. However, if an attribtue's value is
+	wrong (e.g., a floating point value that is out of range), rather
+	than throw an exception a note in the form of a container and
+	explanation are added to the attribute table where the error
+	occurred. This is particularly important for attributes like
+	numerical values since they are often machine-dependent. Here's an
+	example of a DAS which contains an error:
+	
+	Attributes {
+	    a {
+	        Byte size 7, 700;
+		Float64 type 6.02e400, 3.4;
+		Float64 type 6.02e400, 2.7, 10e-400;
+	    }
+        }
+
+	And here is how the DAS looks once it is processed by the
+	client-side software:
+
+	Attributes {
+	    a {
+		Byte size 7;
+		a_errors {
+		    Byte size 700;
+		    String size_explanation `700' is not a Byte value.;
+		    Float64 type 6.02e400, 6.02e400, 10e-400;
+		    String type_explanation `6.02e400' is not a Float64 value., `6.02e400' is not a Float64 value., `10e-400' is not a Float64 value.;
+		}
+		Float64 type 3.4, 2.7;
+	    }
+	}
+
+	* Makefile.in: Added a short script to the Makefile.in so that
+	when CppUnit stuff is not defined a message is printed. This is
+	only triggered for the unit_tests targets, so it's really a
+	reminder for the folks that are doing development.
+
+	* configure.in: Changed so that if CFLGAS/CXXFLAGS are defined
+	those values are used instead of the defaults. This simplifies
+	development and debugging because it is easier to get builds
+	without optimization and with optimal debugging without hand
+	editing the Makefile every time configure is run.
+
+2001-05-03  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added Cache-Control: no-cache header for error responses. This
+	will prevent internal server error responses (which look like
+	valid responses to the cache) from getting cached.
+
+	* Added support for conditional requests to the DODSFilter class,
+	the cgi_util functions and the DODS_Dispatch.pm Perl module.
+	Servers can now see conditional requests as such and respond
+	sensibly. If a server cannot use the modification time of a file,
+	then it should subclass DODSFilter and supply different versions
+	of the last modified time methods.
+
+2001-04-23  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed the unit test targets and variables. These are now
+	included in the Makefile.in but are commented out. You must
+	remove the comments to use the target. Also needed is the CppUnit
+	software which is in CVS in the CppUnit module.
+
+	* Added support for the Last-Modified MIME header. All DODS
+	servers which use the functions in cgi_util.cc and/or the class
+	DODSFilter can now easily include the Last-Modified header in
+	their responses. The only change that servers should make is to
+	pass the ancillary files location directory to
+	DODSFilter::send_data(). Use of the send_das() and send_dds()
+	methods should require no change. In addition, calling the
+	send_data() method without giving the ancillary files location
+	will work OK with the exception that ancillary files won't
+	contribute to the LM computation (as they will for the DAS and DDS
+	responses).
+
+	Currently the LM computation works only for file-based datasets.
+	Servers that provide access to other types of data should subclass
+	DODSFilter and provide alternate implementations of the relevant
+	methods. 
+	
+	* Fixed some warnings in Error.cc from g++.
+
+2001-02-13  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged authentication changes from the trunk (where that feature
+	was added) here so that it can be included in 3.2 without too much
+	confusion. 
+
+2001-02-09  James Gallagher  <jimg at dcz.dods.org>
+
+	* Substantial changes to Connect to support HTTP authentication.
+	libdap++ now support three ways of supplying credentials: via
+	Connect's ctor, in a URL (using Netscape's convention and via a
+	popup. 
+
+2001-01-26  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with release-3-2-3. The next merge should use -j
+	release-3-2-3 -j release-3-2.
+
+	* Tagged release-3-2-3
+
+2000-12-06  James Gallagher  <jimg at dcz.dods.org>
+
+	* There was an old problem with libwww which I patched in June or
+	July which fixed its caching of compressed responses. This patch
+	has not made it into the regular distribution, so when I upgraded
+	the patch was lost. I've re-applied the patch to the code in
+	src/packages/libwww. This, together with the .dodsrc bug fixed
+	below, fixes reported problems with the caching system (on unix at
+	least, I don't have any information about the problems on win32).
+
+	* Fixed .dodsrc file reading. Comments at the top of the file
+	caused the reader to stop processing the file and thus none of the
+	parameter values were being read.
+
+2000-12-04  James Gallagher  <jimg at dcz.dods.org>
+
+	* Note that the attribute table tests added are both unit tests
+	(look at the unit_tests target in the Makefile) and dejaGNU-type
+	tests. Take a look at AttrTableTest.cc to see how unit tests are
+	written for a class.
+
+2000-11-29  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed problems with attribute aliases. Added unit tests for
+	AttrTable. DAS is now a child of AttrTable, so the AttrTable
+	methods can be used at any level of the DAS object. The DAS
+	methods still work, but they are now implemented using AttrTable
+	methods. 
+
+2000-09-21  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged Jose Garcia's exception handling code. 
+
+	* Merging the exception software means that all definitions of the
+	read() method must change. See BaseType.h for details.
+
+	* Improved error messages returned by the parsers. The DAS and DDS
+	parsers now include a line number and, in many cases, context, for
+	each message. 
+
+	* Normalized all the #ifndef #endif guards in the header files so
+	they use the same naming scheme. Added guards around #include
+	lines for headers to speed compile times (see Lakos).
+
+	* Reorganized the source files so that the CVS logs appear at the
+	end rather than the start of each file. 
+
+2000-09-11  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added methods to Sequence to provide access to row number
+	constraint information. These methods (get_starting_row_number,
+	...) provide access to the indices given in a CE. Also added is a
+	method to set these values (until explicitly set the stating
+	and ending row numbers and the stride are -1). In addition there
+	is a method to get the current row number (useful when reading
+	row-by-row with read()) and a method to read the ith row into the
+	sequence. 
+
+	* Added Sequence row number selection. It is now possible to
+	request the first 10 rows of a sequence, or row 7 through 11 and
+	to do so using a stride. The notation is the same as for Arrays
+	and Grids; it uses the square brackets and colon separated
+	integers for start, stride and stop. 
+
+2000-08-31  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with 3.1.10. The next merge should use update -d -j
+	release-3-1-10 -j release-3-1.
+
+	* Fixed a bug in all the scanners (except the GSE scanner) where
+	\r characters in text sent from win32-hosted servers caused the
+	problems. The \r characters are either ignored or treated like
+	newlines when paired with \n (depending on the circumstances).
+
+2000-08-29  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with 3.1.9. The next merge should use update -d -j
+	release-3-1-9 -j release-3-1.
+
+2000-08-25  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a bug in esc2underscore(). The function used a static
+	instance of Regex; whatever regular expression was passed in on
+	the first call would be used for all subsequent calls. The same
+	problem existed for other functions in the file.
+
+2000-08-02  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with 3.1.8. The next merge should use cvs update -j
+	release-3-1-8 -j release-3-1.
+
+2000-08-02  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a config_dap.h goof. That header was included by some of
+	the DAP headers which might, in turn, be included by other
+	software. The HAVE_CONFIG_H symbol in config_dap.h was confusing
+	other code (e.g., the Cgicc library). I changed config_dap.h and
+	its use; the header is now only included by DAP .cc or .c files.
+	DAP header files which needed config_dap.h for the dods_int32,
+	etc., typedefs now get those from dods-datatypes.h. Headers which
+	used config_dap.h for the DVR symbol (which holds the dap version
+	information) have been rewritten.
+
+	This change means that code which now included config_dap.h should
+	be rewritten to use the dods-datatypes.h header or otherwise
+	changed so that config_dap.h is not used.
+
+2000-06-16  James Gallagher  <jimg at dcz.dods.org>
+
+	* Note: This release was made to patch a bug which shows up in the
+	version of loaddods that supports loading the DAS into a
+	structure (version 3.1.5 of loaddods). You need this code to build
+	that version of loaddods.
+
+	* Fixed the tests so they work on my machine (where I don't have
+	`.' in my PATH). I also added some `/'s in places where is *seems*
+	DejaGnu was supplying them before. If extras creep in that should
+	not e a problem.
+
+	* Fixed (by Ethan) the tar and binary-tar targets.
+
+	* Added a fair amount of instrumentation to the dtors of various
+	methods. 
+
+	* Fixed a bug in DDS. The del_var method must delete the BaseType
+	before deleting the list element. I also changes from a SLList to
+	a DLList to get a cleaner delete method.
+
+2000-06-07  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with version 3.1.6. Used cvs update -d -j release-3-1-5
+	-j release-3-1. The next merge should use -j release-3-1-6 -j
+	release-3-1. 
+
+	* Added code to Vector so that each element of vector<BaseType *>
+	_vec is explicitly copied and deleted.
+
+	* Fixed bugs in Grid, Structure and Sequence. The methods used to
+	get the Pix pointing to the first variable would segfault if there
+	were no variables. Now they return 0.
+
+	* DODSFilter now has a set_ce() method. This means that a server
+	can easily rewrite the CE it gets without loosing the other
+	features of DODSFilter.
+
+	* Connect.cc: Fixed bugs with local connections and the libwww and
+	Gui initializations. 
+
+	* Fixed a bug in AttrTable. Container attributes below the top
+	level were broken in the last release. Changed the get_attr_num()
+	method so that it returns a sensible value for both containers and
+	`plain' attributes. Added to struct entry so that it is more a
+	complete class. Added methods so that operator= and the copy-ctor
+	really work. The IFREMER server needs these fixes.
+
+	* Added to InternalErr a new ctor which makes it simpler to report
+	the file name and line number when an error is thrown.
+
+2000-06-06  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged changes from Rob's PC port. Used cvs update -j
+	pc-port-branch. I have done minimal testing on Linux (dejagnu is
+	not yet installed) and the code seems fine. 
+
+2000-04-17  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed two bugs in Connect.cc that caused client sessions which
+	mixed remote and local connections to fail.
+
+2000-04-06  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with Brent's gui2 code. This version of the progress
+	popup adds a cancel button. The software was checked in on the
+	gui2 branch and the point at which it was merged was tagged, on
+	that branch, as gui2-0. Future merges should use update -j gui2-0
+	-j gui2. 
+
+2000-03-31  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with release-3-1-5. The next merge should use -j
+	release-3-1-5 -j release.
+
+2000-03-28  James Gallagher  <jimg at dcz.dods.org>
+
+	* Look in the Makefile for this software to see the new support
+	library configure macros in action. These simplify getting the
+	right libraries on the link line without duplicates (which
+	lengthen link times). 
+
+	* Added libdap++-gui.a to the build/install/tar/binary-tar stuff.
+	This library is built with `GUI-enabled' versions of Connect and
+	Error. This is to support our progress indicator and cancel button.
+
+	* Added a new feature to the .dodsrc file and caching. Users can
+	set the default expiration time for a response using a parameter
+	in the RC file. By default the expiration time is 24 hours
+	(written in seconds).
+
+	* Fixed bugs in the caching software. Compressed responses now are
+	cached correctly and responses with several variables are also
+	correctly handled. 
+
+2000-03-31  James Gallagher  <jimg at dcz.dods.org>
+
+	* escaping.cc: Fixed a bug where an int was used to index into a
+	string object.
+
+	* parser-util.cc (check_float32): Float32, Float64 attributes no
+	longer check ranges.
+
+2000-03-20  James Gallagher  <jimg at dcz.dods.org>
+
+	* parser-util.cc (check_byte): Byte attributes can now be either
+	signed or not (i.e., their range is -128 to 255). This is to
+	support clients that assume bytes to be signed as well as those
+	that assume bytes to be unsigned.
+
+2000-01-26  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged with release3-1-4. The next merge should use: update -j
+	release-3-1-4 -j release-3-1.
+
+2000-01-26  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixes for Red hat 6.x (from Ethan).
+
+	* Fixed the use of the stdc++ library's string::find() method. Its
+	return type was assigned to an unsigned int in many places. On 64
+	bit machines this caused problems. The type now used is
+	string::size_type (although size_t also works).
+
+2000-01-24  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a bug in the DAS and DDS parsers (das.y, dds.y). These
+	parsers used static global C++ objects which require that their
+	constructors run before main(). However, when the dap library is
+	linked by a linker that is not aware of this (e.g., Sun's ld, when
+	using GNU C++) those constructors are never called and accessing
+	those objects causes a segmentation fault. Fixing this problem
+	might fix undiscovered bugs in netCDF clients and definitely fixes
+	problems with the nascent loaddods rewrite (where loaddods gets
+	rewritten in C++).
+
+1999-12-31  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added Gui (progress indicator) code back into the core. The
+	interpreter is now embedded in DODS. 
+
+1999-12-14  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a bug in Connect where once the Cache was closed it would
+	never be opened again. 
+
+	* Fixes/improvements for the caching code. The code now correctly
+	handles the case where many URLs are opened using Connect objects
+	created both sequentially and in an interleaved fashion. The Cache
+	index is now updated after each URL request. The Cache is now
+	closed only after all connect objects are destroyed.
+
+	* Connect.h: Added static members to track use of Connect objects
+	in conjunction with the new caching code.
+
+1999-11-04  James Gallagher  <jimg at dcz.dods.org>
+
+	* Merged: cvs update -j release-3-1-2 -j release-3-1, the next
+	merge command should use -j release-3-1-3 -j release-3-1.
+
+1999-11-03  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed the usage filter (nothing to do with the comment about a
+	function of the same name in cgi_utils.cc). The filter was slurping
+	entire datasets because it failed to append the .html suffix when
+	looking for user-defined documentation about a dataset.
+
+	* DDS::send now catches exceptions thrown by the expression
+	evaluator. This means more reliable handling of errors from within
+	server-side function. However, this is only a stop-gap solution to
+	the general problem of poor error processing within the library.
+	Look for a *real* solution to this problem in about 2 months.
+
+	* Fixed a range-check bug for unsigned 16-bit integers. The values
+	were being tested as if they were signed.
+
+	* Removed usage() from cgi_utils.cc since it was not used and was
+	causing conflicts with servers which defined a function with the
+	same name.
+
+	* Documentation updates.
+
+	* Substantial changes to the Makefile.in. See the top level ChangeLog.
+
+1999-08-27  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed the value of DODS_SHRT_MIN in dods-limits.h
+
+	* Now compiles with gcc 2.95
+
+1999-05-27  James Gallagher  <jimg at dcz.dods.org>
+
+	* Misc bug fixes.
+
+	* Error and InternalErr objects now are better behaved and DDS
+	throws them more predictably (although there's still a lot of work
+	to do there).
+
+	* Fixes merged from the alpha-3-0-0 branch.
+
+1999-05-24  James Gallagher  <jimg at dcz.dods.org>
+
+	* The DODS support address is now correct in all the places in the
+	dap. 
+
+	* Fixed some bugs that arose because C and C++ I/O streams may no
+	longer be synchronized.
+
+	* Dan removed the old GUI code. See the comments in Connect.cc.
+
+1999-05-19  James Gallagher  <jimg at dcz.dods.org>
+
+	* The dap++ library now builds using -fPIC (position independent
+	code) so sharable libraries should be easier to make.
+
+	* In DODS_Dispatch.pm, variables are checked for odd characters
+	that might be used to embed shell commands.
+
+	* Fixed security holes in the DODS_Dispatch.pm code. It now
+	returns the command as elements of an array which can be passed to
+	the exec() thus by passing the shell.
+
+	* Fixed all occurrences of the support email address to be the new
+	address. 
+
+1999-05-04  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added to DODSFilter and DODS_Dispatch.pm so that server version
+	number information can be passed from the CGI script to the core
+	software. Now when you ask for the version of a server, you will
+	get the server's version information in addition to the core's. In
+	addition, the XDODS-Server header that is returned with every
+	response will now contain the server's version number. This
+	assumes that the server's dispatch script initializes
+	DODS_Dispatch correctly.
+
+	* Added InternalErr class. This class should be thrown by any code
+	that finds an internal error (i.e., the sort of thing that might
+	otherwise be trapped by an assert).
+
+	* Committed changes that form the base of version 3. This combines
+	the new simple types with a reduced dependence on the old libg++
+	code and misc. fixes. 
+
+1999-04-21  James Gallagher  <jimg at dcz.dods.org>
+
+	* Small fix in prune_spaces(). This fixed a problem in the mexcdf
+	client (and presumably other netcdf or matlab programs to).
+
+1999-04-14  James Gallagher  <jimg at dcz.dods.org>
+
+	* Fixed a bug in Connection::del_connect() where an assert tested
+	false for a valid condition. It is OK for the conns[i] element to
+	be NULL when this method is run.
+
+	* Fixed a bug in Connect where the member _tv would be deleted
+	without being first allocated when local files are accessed. This
+	member is no longer needed (it was used by libwww 5.0).
+
+1999-04-09  James Gallagher  <jimg at dcz.dods.org>
+
+	* This release is a special ferret-only release. It is a stable
+	alpha version of what will be DODS 3.0 once some more features are
+	added. 
+
+1999-03-24  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added support for the new Int16, UInt16 and Float32 types.
+
+1999-03-22  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added the Int16, UInt16 and Float32 datatypes to attributes. See
+	the tests numbered test.18--20.
+
+1999-03-19  James Gallagher  <jimg at dcz.dods.org>
+
+	* Added a call to setprecision(15) in geturl. This makes it so
+	that floating point numbers will print with the full range or
+	precision. It might be that I have to move this when 32 bit floats
+	are added because they have lower precision (8). However, setting
+	the precision at this level (once, before the calls to print_val()
+	start) is probably more efficient.
+
+1999-03-17  James Gallagher  <jimg at dcz.dods.org>
+
+	* Changed cgi_util.cc:find_ancillary_file() so that it looks for
+	<pathname>.ext in addition to <basename>.ext and the other
+	variations. This means that the current convention of naming
+	ancillary DAS files <filename>.das will work for both the
+	DODS_Date(), etc., functions (whose Factory classes were using
+	this convention) and the regular DAS filter program. 
+
+1999-02-24  James Gallagher  <jimg at dcz.dods.org>
+
+	* An interim revision changed the way incoming data documents were
+	processed so that the DDS contained in the data document did not
+	have to copied to a separate file before being processed. However,
+	this broken programs that read data docs with a pipe. This problem
+	has been fixed. The document's DDS still is not copied, but
+	programs like asciival that read from stdin via a pipe now work.
+
+1999-01-21  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added the Grid Selection function. Grid variable may now be
+	`selected' based on the values of the Map vectors (since this a
+	constraint that returns data based on those data's values, I'm
+	calling it a selection operation). The syntax looks like:
+	grid(<grid var name>, <expression 0>, <expr 1>, ..., <expr n>). An
+	example: grid(dsp_band_1, "29.7 < lat <= 34.8", "lon > -70.9", "
+	-60 < lon"). This deliberately shows different forms the
+	`expressions' can take. Note that these expressions can only name
+	the grid's map vectors; they are not general expressions. Also
+	note that the function appears in the projection part of a CE.
+
+1999-01-15  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Changed the way the expression and DDS parsers work. Now the
+	expression scanner/parser can process strings directly. This means
+	that expression parsing is cleaner, somewhat faster and more
+	reliable since a temporary file is no longer created as part of
+	the parse process. Similarly, the DDS parser no longer requires
+	that a temporary file be created to parse the DDS bound to a data
+	document. 
+
+1998-11-23  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed a bug in DAS where the destructor would free memory that
+	was just garbage. I replaced the old genclass-based DASVHMap code
+	with an SLList of structs.
+
+1998-11-11  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixes for various memory leaks found while working on the FF
+	server.
+
+1998-11-05  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed error messages for CEs involving arrays. When an array
+	name was misspelled in a CE you got no error message, now you do.
+
+1998-10-21  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added projection functions to the CE syntax. These functions are
+	executed *during* the parse of the projection clause. They can be
+	used to add new (synthetic) variables to the DDS.
+
+1998-10-14  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* expr.y: Added parse of single array indeces to the projection
+	list in a CE. i[3] asks for the fourth element of the array i. The
+	old syntax i[3:3] still works.
+
+1998-09-17  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* The release (version 2.18) is the last that will use String.h.
+	  WRONG! 11/11/98 jhrg
+	
+1998-09-03  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Feature: CEs no longer require fully-qualified names for fileds
+	of ctor types.
+
+	* Makefile.in (clean): Added GNU to the list of directories
+	cleaned. This prevents sending out .o files with the source code.
+
+1998-04-07  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed Connect: leading spaces in a URL and/or CE caused either a
+	crash or other problem.
+
+1998-04-03  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added patches from Jake Hamby which fix various problems with
+	Sequences. 
+
+1998-03-27  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added targets for test coverage analysis.
+
+	* Added fix from Jake Hamby.
+
+	* Makefile.in (GNUHDRS): Added String.h & String.cc to the
+	distributions. 
+
+1998-03-19  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added error messages when array indices are out of range.
+
+	* Fixed yesterday's fix... Error objects are no longer compressed.
+	I moved compression into DDS::send (from DODSFilter::send_data)
+	and structured send() so that the mime header generators no longer
+	use a hack to write themselves without compression. Previously
+	set_mime_*() used to `write past' the compressor process and this
+	caused synchronization problems - which I tried to fix yesterday.
+	Now the headers are written and then the compressor is opened. 
+
+1998-03-18  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed an ugly bug where Error objects were compressed (sometimes
+	they still are) but the return MIME document header didn't say so.
+	Now the return document header says if the Error object is
+	compressed. Note that compressing Error objects is not going to
+	save any (real) space but once the compressing data sink is set up
+	*whatever* gets written to it will be compressed...
+
+1998-03-17  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added the ASCII filter to the set of things that comprise a DODS
+	server. Use .ascii or .asc as a URL suffix to get comma-separated
+	ASCII data back from a DODS server.
+
+	* Added boolean member functions is_simple_type(),
+	is_vector_type() and is_constructor_type(). This reduce the size
+	of various parts of the code (but I have not gone through and
+	replaced all the old code yet).
+
+	* Added some new mfuncs to the core. element_count() returns the
+	number of elements in a constructor type (one for a simple type).
+
+1998-03-09  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Removed the -fno-rtti flag from the DAP library build. The
+	library needs RTTI so that software written using exceptions can
+	catch derived exception classes.
+
+1998-02-11  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added the DODS_Cache.pm class (which was in the hdf-dods server
+	code only). This Perl module is not installed as part of the
+	default stuff in DODS_ROOT/etc.
+
+	* Added support for compression. Servers recognize the
+	Accept-Encoding header in a request document. when the value of
+	that header is `deflate' the zlib LZW algorithm is used to
+	compress data. Clients automatically respond to document that
+	contain the header Content-Encoding: deflate by un compressing the
+	data (a new feature of libwww 5.1). The new servers are compatible
+	with old clients and the new clients are compatible with old
+	servers (although neither combination can use compression).
+
+	* Added a help option to the servers (via an addition in
+	DODS_Dispatch.pm). Use this with the `file name' /help or the
+	extension .help.
+
+Tue Dec 16 00:32:31 1997  James Gallagher  <jimg at localhost>
+
+	* Added DODS_Dispatch.pm perl class. This class centralizes a lot
+	of the code that used to be replicated in each of the perl scripts
+	used to dispatch the various `methods' of a DODS server.
+
+Mon Dec 15 17:26:37 1997  James Gallagher  <jimg at localhost>
+
+	* Many small bug fixes that were fixed before being added to the
+	TODO list.
+
+	* Added DataDDS class which makes the version number read by
+	Connect available to any member function that can access a DDS
+	pointer (since DDS *s can reference DataDDS objects).
+
+	* Added the DODSFilter class to simplify writing servers that
+	conform to a set of standards Re: the placement and naming of
+	ancillary files, version numbers, etc.
+
+	* Added new Sequence processing code along with backward
+	compatibility. Nested sequences are sent more efficiently. In
+	addition, sequences may be followed by other variables in a Data
+	object (an old bug).
+
+	* Added new characters to those allowed in DDS NAME lexeme. This
+	means that a file with _ and . in the name will parse.
+
+Wed Aug 20 14:12:54 1997  James Gallagher  <jimg at localhost>
+
+	* Added newline after data in process_data() in geturl.cc.
+
+Thu Jun  5 16:08:10 1997  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* See TODO for a list of reported bugs fixed and outstanding.
+
+	* Changed the way request_data works so that Connect can now be
+	used to create clients that read not only from the network but
+	also from standard input.
+
+	* Wrote DODS_Dispatch.pm Perl `class' that can be used to write
+	the nph-* dispatch scripts. This should simplify maintenance of
+	those scripts since they was a lot of replication of code from one
+	script to another. Now must of the real functionality is
+	concentrated in the one file.
+
+	* When projections on Grids result in an object that is no longer
+	a `true' Grid (no longer satisfies Grid::check_semantics()) then
+	send the resulting variables as a Structure of Arrays or a simple
+	array (the latter if only one array remains after applying the
+	projection to the Grid.
+
+	* Changed the way servers report the version number of the core
+	software. The message is now generated by the *_dods data filter
+	program using its -v option (all the data filter programs
+	support this option). This gets rid of the dods-core-version perl
+	script. 
+
+	* Changed geturl so that it can read from stdin (similar to
+	writeval). 
+
+	* Fixed bugs in util.cc.
+
+Wed May 21 22:25:41 1997  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* See the TODO list for information on bugs found and fixed.
+
+	* Added DAS aliases and hierarchies.
+
+Sun Mar 23 17:01:12 1997  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed the nasty decompression bug where child process exit
+	status was never caught. This caused process tables to fill, etc.
+
+Thu Mar  6 21:14:38 1997  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* See TODO list for bugs fixed.
+
+Sun Feb  9 18:40:25 1997  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* See TODO for a list of bugs fixed.
+
+Thu Feb  6 16:17:06 1997  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Changed the return type of request_data() from DDS & to DDS *.
+	Also changed the return types of append_constraint() and
+	constraint_dds() from DDS & to DDS *. When request_data()
+	encounters an error it no longer exits; now it returns NULL.
+
+Wed Dec 18 11:18:05 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Version 2.10 prepared
+
+Wed Dec 11 20:15:10 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Created the Usage server.
+
+	* Fixed bugs in cgi_util.cc - error Content-Description items were
+	not processed.
+
+Tue Dec  3 09:43:02 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added to DDS::parse_constraint() two new variables: ostream os
+	and bool server. These are used to control processing of error
+	messages that are returned from the CE parser. Rather than have
+	the CE parser write all its error messages to stderr, the parser
+	now returns an error object. The new code in parse_constraint()
+	ensures that an `error' header is written to OS and that the error
+	object is serialized if the member function is run from within a
+	server. Since parse_constraint() is called from within
+	DDS::send(), users of the library don't need to do anything
+	different unless they have coded their own versions of send().
+
+	* Added code to ensure that variables can be used in the selection
+	part of a constraint expression without having to be also in the
+	projection part. This means that a CE can be used to request a
+	single variable (e.g., the sequence `s') but select by comparing
+	to other variables in the data set.
+
+Mon Dec  2 11:50:29 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added three new versions of int_ops to process all the possible
+	permutations of signed and unsigned integer operands. Ignore the
+	warnings in util.cc about comparisons between signed and unsigned.
+
+	* Added cases for unsigned integer variables in the Vector, Byte,
+	Int and Float classes. Also added cases in BaseType and some of
+	the Test* classes. This fixes problems with the processing of
+	this type.
+
+Wed Nov 27 11:02:44 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added DDS as a third argument to the user-defined functions in
+	the CE evaluator. This means that a function (which may be server
+	specific) may look at the value of any variable in the dataset,
+	not just those values passed as parameters. This will facilitate
+	creation of functions which use implicit relations between
+	variables when computing values or performing selections (e.g.,
+	when geo-location information depends on the implicit relation
+	between two or more arrays).
+
+	* Changed the way Makefile dependencies are processed so that
+	Makefile (re)generation is faster (since dependencies rarely
+	change). 
+
+Sun Nov 24 19:45:22 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Tested the library code in a number of situations and fixed many
+	little bugs.
+
+	* The asynchronous mode for data transfers is broken and is never
+	used. 
+
+	* Significantly improved processing of errors - web errors are now
+	handled correctly for the DAS and DDS - alas the data will still
+	exit when an error is encountered. Note that to fix this problem
+	I'll need to use exceptions *or* change the return type of the
+	request_data() member function to DDS * (from DDS &). Either one
+	will break everyone's code...
+
+	* Fixed the lame-looking progress indicator.
+
+	* dods_root is no longer a global variable that depends on run
+	time initialization from g++; now it is a function. This ensures
+	that the core software can be linked to program core using linkers
+	other than g++.
+
+	* Added better compressor function - look at jg_dods.cc to see how
+	it is used.
+
+	* Fixed broken decompression.
+
+Wed Nov 13 10:43:56 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added error MIME headers to the set that can be generated by
+	helper functions in cgi_util.cc. The error headers are necessary
+	since DODS now must generate all its own MIME headers (see the
+	section on NPH CGIs in the CGI spec). MIME error headers should be
+	used when an http or www error has been detected - don't use the
+	DODS error objects in those cases.
+
+	* Made changes in the Int data types so that expressions with
+	UInt32s should work. 
+
+	* Fixed some problems with the GUI. It should work more reliably
+	but I doubt that all the problems have been fixed. Needs testing.
+
+	* Now reports most www/http errors, although some clients still
+	can't seem to get the GUI to work (e.g., writeval) even though
+	geturl can.
+
+	* Now requires version 5.0a of the WWW Library.
+
+	* Many changes based on feedback from the initial version 2.09
+	distribution. 
+
+Tue Oct 29 08:23:30 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added UInt32 (32 bit unsigned integers) to the DAP. This
+	includes both using them in the DDS and the DAS. When an UInt32 is
+	used as an operand in a CE, the other operand is cast to unsigned
+	for the comparison operation.
+
+Fri Oct 18 09:35:07 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed various errors in the new Unsigned int classes.
+
+	* Changed the operation of Connect::request_das() and
+	request_dds(). They now pass any initial constraint along to the
+	respective servers. An initial constraint is one which is supplied
+	along with the URL at the time the Connect object is made.
+
+	* The functions set_mine_{text,binary} now produce complete
+	HTTP/MIME headers. Thus DODS servers can now be invoked using the
+	`nph' feature of CGI 1.1 (done by naming the DODS server dispatch
+	script `nph-*'). This solve two problems which appeared with large
+	data transfers: Transfers were cut-off before completion when a
+	server-determined timeout period elapsed and 2) Some large
+	transmissions had an extra byte added into the data stream.
+
+Tue Oct  8 09:23:57 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Modified geturl so that CEs can be passed in using ? in the URL
+	in addition to the program's -c option.
+
+	* Added `%' to the set of characters allowable in identifiers.
+
+	* Added code so that a constraint expression appended to a URL is
+ 	properly handled. The CE is stored in in the Connect object. When
+	a CE is passed to the request_data member function, Connect
+	correctly combines the projection and selection parts of that CE
+	with the matching parts of any initial CE. 
+
+	* Fixed up the grammar files for Bison 1.25
+
+Thu Sep 12 14:05:49 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added a new option to geturl; -D which can be used to get data. 
+
+	* Fixed Array::print_array; used indirectly by the new option to
+	geturl. 
+
+Mon Aug 26 13:18:21 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed various configure.in files so that the different size ints
+	are defined properly.
+
+	* Fixed up the config_dap.h problem in the jg-dods directory.
+
+	* Added classes for 32 bit floats, 32 bit unsigned ints and 16 bit
+	signed and unsigned ints. These are *not* built by default - I'll
+	let the various users have a chance to include these new classes in
+	their software before they are added to the build (and thus must
+	be sub-classed by users of the DAP).
+
+Fri Aug 16 09:34:00 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed configure tests for sem.h prototypes and the semctl union.
+	A new test which scans the sem.h header is in aclocal.m4 (in etc)
+	and the configure script uses that test.
+
+Tue Aug 13 10:54:02 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed bugs in Grid: bad constraint expressions would cause core
+	dumps and a bug on the SGI (maybe others) where valid Grids would
+	not parse.
+
+	* Added to the Error class so that its methods are more useful
+	for correcting errors and displaying messages (see Error.cc).
+
+	* Switched to parser_arg object on all the parsers. parser_arg is
+	a simple object used to pass values to and from the bison gnerated
+	parsers. You need bison 1.24 or newer.
+
+	* Added _unused_ to config_dap.h; this macro expands to gcc's
+	__attribute__((__unused__)) thing. I then tacked `__unused__' on the
+	char rcsid[] arrays to suppress warnings from gcc -Wall (and
+	highlite the warnings that should be fixed!)
+
+	* Fixed a bug in Clause where non-existent functions were
+	evaluated - this caused a core dump.
+
+Fri Aug  9 10:21:06 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Fixed bug in Connect where local accesses were not correctly
+	detected. Also modified geturl to print a diagnostic when supplied
+	with a local file name (or, more to the point, a name without
+	`http'). 
+
+Wed Jul 17 15:04:01 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Added expr-check target in Makefile.
+
+	* Added new tests for das, dds objects. Added tests for expr-test
+	driver. 
+
+Mon Jul  8 16:25:11 1996  James Gallagher  <jimg at dcz.cvo.oneworld.com>
+
+	* Gui.cc: Added compile-time switch HAVE_EXPECT which is used to
+	control use/requirement of expect and tcl. When defined as 1 Expect
+	and Tcl are used to communicate with a GUI subprocess. When 0,
+	Expect and Tcl are not used (thus the libraries are not required).
+	Note that without Expect the GUI used for the transmission
+	progress indicator and error reporting is not available.
+
+$Id: ChangeLog 24505 2011-04-26 00:16:05Z jimg $
+
diff --git a/Clause.cc b/Clause.cc
new file mode 100644
index 0000000..35aef43
--- /dev/null
+++ b/Clause.cc
@@ -0,0 +1,237 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1996,1998,1999
+// Please first read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+// jhrg,jimg James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the CE Clause class.
+
+
+#include "config.h"
+
+#include <cassert>
+#include <algorithm>
+
+#include "expr.h"
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "DDS.h"
+#include "Clause.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+Clause::Clause(const int oper, rvalue *a1, rvalue_list *rv)
+        : _op(oper), _b_func(0), _bt_func(0), _argc(0), _arg1(a1), _args(rv)
+{
+    assert(OK());
+}
+#if 1
+Clause::Clause(bool_func func, rvalue_list *rv)
+        : _op(0), _b_func(func), _bt_func(0), _argc(0), _arg1(0), _args(rv)
+{
+    assert(OK());
+
+    if (_args)   // account for null arg list
+        _argc = _args->size();
+    else
+        _argc = 0;
+}
+#endif
+Clause::Clause(btp_func func, rvalue_list *rv)
+        : _op(0), _b_func(0), _bt_func(func), _argc(0), _arg1(0), _args(rv)
+{
+    assert(OK());
+
+    if (_args)
+        _argc = _args->size();
+    else
+        _argc = 0;
+}
+
+Clause::Clause() : _op(0), _b_func(0), _bt_func(0), _argc(0), _arg1(0), _args(0)
+{}
+
+static inline void
+delete_rvalue(rvalue *rv)
+{
+    delete rv; rv = 0;
+}
+
+Clause::~Clause()
+{
+    if (_arg1) {
+        delete _arg1; _arg1 = 0;
+    }
+
+    if (_args) {
+        // _args is a pointer to a vector<rvalue*> and we must must delete
+        // each rvalue pointer here explicitly. 02/03/04 jhrg
+        for_each(_args->begin(), _args->end(), delete_rvalue);
+        delete _args; _args = 0;
+    }
+}
+
+/** @brief Checks the "representation invariant" of a clause. */
+bool
+Clause::OK()
+{
+    // Each clause object can contain one of: a relational clause, a boolean
+    // function clause or a BaseType pointer function clause. It must have a
+    // valid argument list.
+    //
+    // But, a valid arg list might contain zero arguments! 10/16/98 jhrg
+    bool relational = (_op && !_b_func && !_bt_func);
+#if 1
+    bool boolean = (!_op && _b_func && !_bt_func);
+#endif
+    bool basetype = (!_op && !_b_func && _bt_func);
+
+    if (relational)
+        return _arg1 && _args;
+    else if (boolean || basetype)
+        return true;  // Until we check arguments...10/16/98 jhrg
+    else
+        return false;
+}
+
+/** @brief Return true if the clause returns a boolean value. */
+bool
+Clause::boolean_clause()
+{
+    assert(OK());
+
+    return _op || _b_func;
+}
+
+/** @brief Return true if the clause returns a value in a BaseType pointer. */
+bool
+Clause::value_clause()
+{
+    assert(OK());
+
+    return (_bt_func != 0);
+}
+
+/** @brief Evaluate a clause which returns a boolean value
+    This method must only be evaluated for clauses with relational
+    expressions or boolean functions.
+
+    @param dds Use variables from this DDS when evaluating the
+    expression
+
+    @return True if the clause is true, false otherwise.
+    @exception InternalErr if called for a clause that returns a
+    BaseType pointer. */
+bool
+Clause::value(DDS &dds)
+{
+    assert(OK());
+    assert(_op || _b_func);
+
+    if (_op) {   // Is it a relational clause?
+        // rvalue::bvalue(...) returns the rvalue encapsulated in a
+        // BaseType *.
+        BaseType *btp = _arg1->bvalue(dds);
+        // The list of rvalues is an implicit logical OR, so assume
+        // FALSE and return TRUE for the first TRUE subclause.
+        bool result = false;
+        for (rvalue_list_iter i = _args->begin();
+             i != _args->end() && !result;
+             i++) {
+            result = result || btp->ops((*i)->bvalue(dds), _op);
+        }
+
+        return result;
+    }
+    else if (_b_func) {  // ...A bool function?
+        BaseType **argv = build_btp_args(_args, dds);
+
+        bool result = false;
+        (*_b_func)(_argc, argv, dds, &result);
+        delete[] argv;  // Cache me!
+        argv = 0;
+
+        return result;
+    }
+    else {
+        throw InternalErr(__FILE__, __LINE__,
+                          "A selection expression must contain only boolean clauses.");
+    }
+}
+
+/** @brief Evaluate a clause that returns a value via a BaseType
+    pointer.
+    This method should be called only for those clauses that return values.
+
+    @param dds Use variables from this DDS when evaluating the
+    expression
+    @param value A value-result parameter
+
+    @return True if the the BaseType pointer is not null, false otherwise.
+    @exception InternalErr if called for a clause that returns a
+    boolean value. Not that this method itself \e does return a
+    boolean value. */
+bool
+Clause::value(DDS &dds, BaseType **value)
+{
+    assert(OK());
+    assert(_bt_func);
+
+    if (_bt_func) {
+        // build_btp_args() is a function defined in RValue.cc. It no longer
+        // reads the values as it builds the arguments, that is now left up
+        // to the functions themselves. 9/25/06 jhrg
+        BaseType **argv = build_btp_args(_args, dds);
+
+        (*_bt_func)(_argc, argv, dds, value);
+
+        delete[] argv;  // Cache me!
+        argv = 0;
+
+        if (*value) {
+            (*value)->set_send_p(true);
+            (*value)->set_read_p(true);
+            return true;
+        }
+        else {
+            return false;
+        }
+    }
+    else {
+        throw InternalErr(__FILE__, __LINE__,
+                          "Clause::value() was called in a context expecting a BaseType pointer return, but the Clause was boolean-valued instead.");
+    }
+}
+
+} // namespace libdap
diff --git a/Clause.h b/Clause.h
new file mode 100644
index 0000000..1d985f9
--- /dev/null
+++ b/Clause.h
@@ -0,0 +1,135 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please first read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+// jhrg,jimg James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the CE Clause class.
+
+#ifndef _clause_h
+#define _clause_h
+
+
+#ifndef _expr_h
+#include "expr.h"
+#endif
+
+#ifndef _rvalue_h
+#include "RValue.h"
+#endif
+
+namespace libdap
+{
+
+/** The selection part of a a DAP constraint expression may contain one or
+    more clauses, separated by ampersands (\&). This is modeled in the DDS
+    class structure as a singly-linked list of Clause objects. In addition, a
+    constraint expression may be a single function call, also represented in
+    the DDS using an instance of Clause.
+
+    Each clause object can contain a representation of one of three
+    possible forms:
+
+    <ol>
+
+    <li> A relational clause, where an operator tests the relation
+    between two operands.  This kind of clause evaluates to a boolean
+    value. For example: <tt>a > b</tt>.
+
+    <li> A boolean function, where some function operates on
+    arguments in the clause to return a boolean value.  For example,
+    consider a scalar A and a list L.  The clause <tt>find(A,L)</tt> might
+    return TRUE if A is a member of L (if the <tt>find()</tt> function is
+    defined).
+
+    <li> A clause that returns a pointer to a DAP BaseType value.
+    This is a clause that evaluates to some data value (be it scalar
+    or vector).  For example, <tt>sig0()</tt> might be included in the
+    constraint expression parser to calculate density from pressure,
+    temperature, and salinity.  In this case, <tt>sig0(p,t,s)</tt> would be a
+    clause that evaluates to a data value.
+
+    </ol>
+
+    This might be a bit confusing; in the first, and by far more common, form
+    of constraint expressions (CEs) only the first two types of clauses may
+    appear. In the second form of the CE only the last type of clause may
+    occur. The Clause class, however, can store them all.
+
+    The Clause object holds the constraint expression <i>after</i> it
+    has been parsed.  The parser renders the relational operator into
+    an integer, and the functions into pointers.
+
+    @brief Holds a fragment of a constraint expression.
+    @see DDS::parse_constraint */
+struct Clause
+{
+
+private:
+    /** The relational operator, if any. */
+    int _op;
+    /** A pointer to a valid boolean function. */
+    bool_func _b_func;
+
+    /** A pointer to a valid function that returns a pointer to a
+    BaseType. */
+    btp_func _bt_func;
+
+    int _argc;   // arg count
+    rvalue *_arg1;  // only for operator
+    rvalue_list *_args;  // vector arg
+
+    Clause(const Clause &)
+    {}
+    Clause &operator=(const Clause &)
+    {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+    }
+
+public:
+    Clause(const int oper, rvalue *a1, rvalue_list *rv);
+    Clause(bool_func func, rvalue_list *rv);
+    Clause(btp_func func, rvalue_list *rv);
+    Clause();
+
+    virtual ~Clause();
+
+    bool OK();
+
+    bool boolean_clause();
+
+    bool value_clause();
+
+    bool value(DDS &dds);
+
+    bool value(DDS &dds, BaseType **value);
+};
+
+} // namespace libdap
+
+#endif // _clause_h
diff --git a/Connect.cc b/Connect.cc
new file mode 100644
index 0000000..908d5de
--- /dev/null
+++ b/Connect.cc
@@ -0,0 +1,1118 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//         Dan Holloway <dholloway at gso.uri.edu>
+//         Reza Nekovei <reza at intcomm.net>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-2002
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+//      dan             Dan Holloway <dholloway at gso.uri.edu>
+//      reza            Reza Nekovei <reza at intcomm.net>
+
+
+#include "config.h"
+
+//#define DODS_DEBUG
+#define FILE_METHODS 1
+
+static char rcsid[] not_used =
+    { "$Id: Connect.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include <cstring>
+#include <fstream>
+#include <algorithm>
+
+#include "debug.h"
+#include "DataDDS.h"
+#include "Connect.h"
+#include "escaping.h"
+#include "RCReader.h"
+#include "DDXParserSAX2.h"
+#if FILE_METHODS
+#include "XDRFileUnMarshaller.h"
+#else
+#include "fdiostream.h"
+#include "XDRStreamUnMarshaller.h"
+#endif
+#include "mime_util.h"
+
+using std::cerr;
+using std::endl;
+using std::ifstream;
+using std::ofstream;
+using std::min;
+
+namespace libdap {
+
+/** This private method process data from both local and remote sources. It
+    exists to eliminate duplication of code. */
+void
+Connect::process_data(DataDDS &data, Response *rs)
+{
+    DBG(cerr << "Entering Connect::process_data" << endl);
+
+    data.set_version(rs->get_version());
+    data.set_protocol(rs->get_protocol());
+
+    DBG(cerr << "Entering process_data: d_stream = " << rs << endl);
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream()))
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse the Error object returned by the server!");
+            throw e;
+        }
+
+    case web_error:
+        // Web errors (those reported in the return document's MIME header)
+        // are processed by the WWW library.
+        throw InternalErr(__FILE__, __LINE__, "An error was reported by the remote httpd; this should have been processed by HTTPConnect..");
+
+    case dap4_data_ddx: {
+            // Parse the DDX; throw an exception on error.
+	    DDXParser ddx_parser(data.get_factory());
+
+	    // Read the MPM boundary and then read the subsequent headers
+	    string boundary = read_multipart_boundary(rs->get_stream());
+	    DBG(cerr << "MPM Boundary: " << boundary << endl);
+	    read_multipart_headers(rs->get_stream(), "text/xml", dap4_ddx);
+
+	    // Parse the DDX, reading up to and including the next boundary.
+	    // Return the CID for the matching data part
+	    string data_cid;
+	    ddx_parser.intern_stream(rs->get_stream(), &data, data_cid, boundary);
+
+	    // Munge the CID into something we can work with
+	    data_cid = cid_to_header_value(data_cid);
+	    DBG(cerr << "Data CID: " << data_cid << endl);
+
+	    // Read the data part's MPM part headers (boundary was read by
+	    // DDXParse::intern)
+	    read_multipart_headers(rs->get_stream(),
+		    "application/octet-stream", dap4_data, data_cid);
+
+	    // Now read the data
+#if FILE_METHODS
+	    XDRFileUnMarshaller um( rs->get_stream() ) ;
+#else
+            fpistream in ( rs->get_stream() );
+	    XDRStreamUnMarshaller um( in ) ;
+#endif
+#if 0
+	    try {
+#endif
+        	for (DDS::Vars_iter i = data.var_begin(); i != data.var_end();
+                     i++) {
+                    (*i)->deserialize(um, &data);
+                }
+#if 0
+            }
+            catch (Error &e) {
+                throw ;
+            }
+#endif
+            return;
+        }
+
+    case dods_data:
+    default: {
+            // Parse the DDS; throw an exception on error.
+            data.parse(rs->get_stream());
+#if FILE_METHODS
+            XDRFileUnMarshaller um( rs->get_stream() ) ;
+#else
+            fpistream in ( rs->get_stream() );
+	    XDRStreamUnMarshaller um( in ) ;
+#endif
+            // Load the DDS with data.
+#if 0
+            try {
+#endif
+                for (DDS::Vars_iter i = data.var_begin(); i != data.var_end();
+                     i++) {
+                    (*i)->deserialize(um, &data);
+                }
+#if 0
+            }
+            catch (Error &e) {
+                throw ;
+            }
+#endif
+            return;
+        }
+    }
+}
+
+// Barely a parser... This is used when reading from local sources of DODS
+// Data objects. It simulates the important actions of the libwww MIME header
+// parser. Those actions fill in certain fields in the Connect object. jhrg
+// 5/20/97
+//
+// Make sure that this parser reads from data_source without disturbing the
+// information in data_source that follows the MIME header. Since the DDS
+// (which follows the MIME header) is parsed by a flex/bison scanner/parser,
+// make sure to use I/O calls that will mesh with ANSI C I/O calls. In the
+// old GNU libg++, the C++ calls were synchronized with the C calls, but that
+// may no longer be the case. 5/31/99 jhrg
+
+/** Use when you cannot use libcurl.
+
+    @note This method tests for MIME headers with lines terminated by CRLF
+    (\r\n) and Newlines (\n). In either case, the line terminators are removed
+    before each header is processed.
+
+    @param data_source Read from this stream.
+    @param rs Value/Result parameter. Dump version and type information here.
+    */
+void
+Connect::parse_mime(Response *rs)
+{
+    rs->set_version("dods/0.0"); // initial value; for backward compatibility.
+    rs->set_protocol("2.0");
+
+    FILE *data_source = rs->get_stream();
+    string mime = get_next_mime_header(data_source);
+    while (!mime.empty()) {
+	string header, value;
+	parse_mime_header(mime, header, value);
+
+        // Note that this is an ordered list
+        if (header == "content-description:") {
+            DBG(cout << header << ": " << value << endl);
+            rs->set_type(get_description_type(value));
+        }
+        // Use the value of xdods-server only if no other value has been read
+        else if (header == "xdods-server:"
+                 && rs->get_version() == "dods/0.0") {
+            DBG(cout << header << ": " << value << endl);
+            rs->set_version(value);
+        }
+        // This trumps 'xdods-server' and 'server'
+        else if (header == "xopendap-server:") {
+            DBG(cout << header << ": " << value << endl);
+            rs->set_version(value);
+        }
+        else if (header == "xdap:") {
+            DBG(cout << header << ": " << value << endl);
+            rs->set_protocol(value);
+        }
+        // Only look for 'server' if no other header supplies this info.
+        else if (rs->get_version() == "dods/0.0" && header == "server:") {
+            DBG(cout << header << ": " << value << endl);
+            rs->set_version(value);
+        }
+
+        mime = get_next_mime_header(data_source);
+    }
+}
+
+// public mfuncs
+
+/** The Connect constructor requires a <tt>name</tt>, which is the URL to
+    which the connection is to be made.
+
+    @param n The URL for the virtual connection.
+    @param uname Use this username for authentication. Null by default.
+    @param password Password to use for authentication. Null by default.
+    @brief Create an instance of Connect. */
+Connect::Connect(const string &n, string uname, string password)
+throw(Error, InternalErr)
+        : d_http(0), d_version("unknown"), d_protocol("2.0")
+{
+    string name = prune_spaces(n);
+
+    // Figure out if the URL starts with 'http', if so, make sure that we
+    // talk to an instance of HTTPConnect.
+    if (name.find("http") == 0) {
+        DBG(cerr << "Connect: The identifier is an http URL" << endl);
+        d_http = new HTTPConnect(RCReader::instance());
+
+        // Find and store any CE given with the URL.
+        string::size_type dotpos = name.find('?');
+        if (dotpos != name.npos) {
+            _URL = name.substr(0, dotpos);
+            string expr = name.substr(dotpos + 1);
+
+            dotpos = expr.find('&');
+            if (dotpos != expr.npos) {
+                _proj = expr.substr(0, dotpos);
+                _sel = expr.substr(dotpos); // XXX includes '&'
+            }
+            else {
+                _proj = expr;
+                _sel = "";
+            }
+        }
+        else {
+            _URL = name;
+            _proj = "";
+            _sel = "";
+        }
+
+        _local = false;
+    }
+    else {
+        DBG(cerr << "Connect: The identifier is a local data source." << endl);
+
+        d_http = 0;
+        _URL = "";
+        _local = true;  // local in this case means non-DAP
+    }
+
+    set_credentials(uname, password);
+}
+
+Connect::~Connect()
+{
+    DBG2(cerr << "Entering the Connect dtor" << endl);
+
+    if (d_http)
+        delete d_http; d_http = 0;
+
+    DBG2(cerr << "Leaving the Connect dtor" << endl);
+}
+
+/** Get version information from the server. This is a new method which will
+    ease the transition to DAP 4.
+
+    @note Use request_protocol() to get the DAP protocol version.
+
+    @return The DAP version string.
+    @see request_protocol() */
+string
+Connect::request_version()
+{
+    string version_url = _URL + ".ver";
+    if (_proj.length() + _sel.length())
+        version_url = version_url + "?" + id2www_ce(_proj + _sel);
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(version_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    delete rs; rs = 0;
+
+    return d_version;
+}
+
+/** Get protocol version  information from the server. This is a new method
+    which will ease the transition to DAP 4. Note that this method returns
+    the version of the DAP protocol implemented by the server. The
+    request_version() method returns the \e server's version number, not
+    the DAP protocol version.
+
+    @note This method actually asks the server for the protocol version - use
+    get_protocol() to get the protocol information from the most recent
+    response (e.g., from the last DDX response returned by the server).
+
+    @return The DAP protocol version string. */
+string
+Connect::request_protocol()
+{
+    string version_url = _URL + ".ver";
+    if (_proj.length() + _sel.length())
+        version_url = version_url + "?" + id2www_ce(_proj + _sel);
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(version_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    delete rs; rs = 0;
+
+    return d_protocol;
+}
+
+/** Reads the DAS corresponding to the dataset in the Connect
+    object's URL. Although DAP does not support using CEs with DAS
+    requests, if present in the Connect object's instance, they will be
+    escaped and passed as the query string of the request.
+
+    @brief Get the DAS from a server.
+    @param das Result. */
+void
+Connect::request_das(DAS &das)
+{
+    string das_url = _URL + ".das";
+    if (_proj.length() + _sel.length())
+        das_url = das_url + "?" + id2www_ce(_proj + _sel);
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(das_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream())) {
+            	delete rs; rs = 0;
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse error returned from server.");
+            }
+            delete rs; rs = 0;
+            throw e;
+        }
+
+    case web_error:
+        // We should never get here; a web error should be picked up read_url
+        // (called by fetch_url) and result in a thrown Error object.
+        break;
+
+    case dods_das:
+    default:
+        // DAS::parse throws an exception on error.
+        try {
+            das.parse(rs->get_stream()); // read and parse the das from a file
+        }
+        catch (Error &e) {
+            delete rs; rs = 0;
+            throw ;
+        }
+
+        break;
+    }
+
+    delete rs; rs = 0;
+}
+
+/** Reads the DAS corresponding to the dataset in the Connect
+    object's URL. Although DAP does not support using CEs with DAS
+    requests, if present in the Connect object's instance, they will be
+    escaped and passed as the query string of the request.
+
+    Different from request_das method in that this method uses the URL as
+    given without attaching .das or projections or selections.
+
+    @brief Get the DAS from a server.
+    @param das Result. */
+void
+Connect::request_das_url(DAS &das)
+{
+    string use_url = _URL + "?" + _proj + _sel ;
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(use_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream())) {
+            	delete rs; rs = 0;
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse error returned from server.");
+            }
+            delete rs; rs = 0;
+            throw e;
+        }
+
+    case web_error:
+        // We should never get here; a web error should be picked up read_url
+        // (called by fetch_url) and result in a thrown Error object.
+        break;
+
+    case dods_das:
+    default:
+        // DAS::parse throws an exception on error.
+        try {
+            das.parse(rs->get_stream()); // read and parse the das from a file
+        }
+        catch (Error &e) {
+            delete rs; rs = 0;
+            throw ;
+        }
+
+        break;
+    }
+
+    delete rs; rs = 0;
+}
+
+/** Reads the DDS corresponding to the dataset in the Connect object's URL.
+    If present in the Connect object's instance, a CE will be escaped,
+    combined with \c expr and passed as the query string of the request.
+
+    @note If you need the DDS to hold specializations of the type classes,
+    be sure to include the factory class which will instantiate those
+    specializations in the DDS. Either pass a pointer to the factory to
+    DDS constructor or use the DDS::set_factory() method after the
+    object is built.
+
+    @brief Get the DDS from a server.
+    @param dds Result.
+    @param expr Send this constraint expression to the server. */
+void
+Connect::request_dds(DDS &dds, string expr)
+{
+    string proj, sel;
+    string::size_type dotpos = expr.find('&');
+    if (dotpos != expr.npos) {
+        proj = expr.substr(0, dotpos);
+        sel = expr.substr(dotpos);
+    }
+    else {
+        proj = expr;
+        sel = "";
+    }
+
+    string dds_url = _URL + ".dds" + "?"
+                     + id2www_ce(_proj + proj + _sel + sel);
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(dds_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream())) {
+            	delete rs; rs = 0;
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse error returned from server.");
+            }
+            delete rs; rs = 0;
+            throw e;
+        }
+
+    case web_error:
+        // We should never get here; a web error should be picked up read_url
+        // (called by fetch_url) and result in a thrown Error object.
+        break;
+
+    case dods_dds:
+    default:
+        // DDS::prase throws an exception on error.
+        try {
+            dds.parse(rs->get_stream()); // read and parse the dds from a file
+        }
+        catch (Error &e) {
+            delete rs; rs = 0;
+            throw ;
+        }
+        break;
+    }
+
+    delete rs; rs = 0;
+}
+
+/** Reads the DDS corresponding to the dataset in the Connect object's URL.
+    If present in the Connect object's instance, a CE will be escaped,
+    combined with \c expr and passed as the query string of the request.
+
+    Different from request_dds method above in that this method assumes
+    URL is complete and does not add anything to the command, such as .dds
+    or projections or selections.
+
+    @note If you need the DDS to hold specializations of the type classes,
+    be sure to include the factory class which will instantiate those
+    specializations in the DDS. Either pass a pointer to the factory to
+    DDS constructor or use the DDS::set_factory() method after the
+    object is built.
+
+    @brief Get the DDS from a server.
+    @param dds Result. */
+void
+Connect::request_dds_url(DDS &dds)
+{
+    string use_url = _URL + "?" + _proj + _sel ;
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(use_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream())) {
+            	delete rs; rs = 0;
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse error returned from server.");
+            }
+            delete rs; rs = 0;
+            throw e;
+        }
+
+    case web_error:
+        // We should never get here; a web error should be picked up read_url
+        // (called by fetch_url) and result in a thrown Error object.
+        break;
+
+    case dods_dds:
+    default:
+        // DDS::prase throws an exception on error.
+        try {
+            dds.parse(rs->get_stream()); // read and parse the dds from a file
+        }
+        catch (Error &e) {
+            delete rs; rs = 0;
+            throw ;
+        }
+        break;
+    }
+
+    delete rs; rs = 0;
+}
+
+/** Reads the DDX corresponding to the dataset in the Connect object's URL.
+    If present in the Connect object's instance, a CE will be escaped,
+    combined with \c expr and passed as the query string of the request.
+
+    @note A DDX is represented as XML on the wire but in memory libdap uses a
+    DDS object with variables that hold their own attributes (the DDS itself holds
+    the global attributes).
+
+    @brief Get the DDX from a server.
+    @param dds Result.
+    @param expr Send this constraint expression to the server. */
+void
+Connect::request_ddx(DDS &dds, string expr)
+{
+    string proj, sel;
+    string::size_type dotpos = expr.find('&');
+    if (dotpos != expr.npos) {
+        proj = expr.substr(0, dotpos);
+        sel = expr.substr(dotpos);
+    }
+    else {
+        proj = expr;
+        sel = "";
+    }
+
+    string ddx_url = _URL + ".ddx" + "?"
+                     + id2www_ce(_proj + proj + _sel + sel);
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(ddx_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream())) {
+            	delete rs; rs = 0;
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse error returned from server.");
+            }
+            delete rs; rs = 0;
+            throw e;
+        }
+
+    case web_error:
+        // We should never get here; a web error should be picked up read_url
+        // (called by fetch_url) and result in a thrown Error object.
+        break;
+
+    case dap4_ddx:
+    case dods_ddx:
+	try {
+            string blob;
+
+            DDXParser ddxp(dds.get_factory());
+            ddxp.intern_stream(rs->get_stream(), &dds, blob);
+        }
+        catch (Error &e) {
+            delete rs; rs = 0;
+            throw ;
+        }
+        break;
+
+    default:
+    	delete rs; rs = 0;
+        throw Error("The site did not return a valid response (it lacked the\n\
+expected content description header value of 'dap4-ddx' and\n\
+instead returned '" + long_to_string(rs->get_type()) + "').\n\
+This may indicate that the server at the site is not correctly\n\
+configured, or that the URL has changed.");
+    }
+
+    delete rs; rs = 0;
+}
+
+/** @brief The 'url' version of request_ddx
+    @see Connect::request_ddx. */
+void
+Connect::request_ddx_url(DDS &dds)
+{
+    string use_url = _URL + "?" + _proj + _sel ;
+
+    Response *rs = 0;
+    try {
+        rs = d_http->fetch_url(use_url);
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+
+    d_version = rs->get_version();
+    d_protocol = rs->get_protocol();
+
+    switch (rs->get_type()) {
+    case dods_error: {
+            Error e;
+            if (!e.parse(rs->get_stream())) {
+            	delete rs; rs = 0;
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not parse error returned from server.");
+            }
+            delete rs; rs = 0;
+            throw e;
+        }
+
+    case web_error:
+        // We should never get here; a web error should be picked up read_url
+        // (called by fetch_url) and result in a thrown Error object.
+        break;
+
+    case dap4_ddx:
+    case dods_ddx:
+	try {
+            string blob;
+
+            DDXParser ddxp(dds.get_factory());
+            ddxp.intern_stream(rs->get_stream(), &dds, blob);
+        }
+        catch (Error &e) {
+            delete rs; rs = 0;
+            throw ;
+        }
+        break;
+
+    default:
+    	delete rs; rs = 0;
+        throw Error("The site did not return a valid response (it lacked the\n\
+expected content description header value of 'dap4-ddx' and\n\
+instead returned '" + long_to_string(rs->get_type()) + "').\n\
+This may indicate that the server at the site is not correctly\n\
+configured, or that the URL has changed.");
+    }
+
+    delete rs; rs = 0;
+}
+
+/** Reads the DataDDS object corresponding to the dataset in the Connect
+    object's URL. If present in the Connect object's instance, a CE will be
+    escaped, combined with \c expr and passed as the query string of the
+    request. The result is a DataDDS which contains the data values bound to
+    variables.
+
+    @note If you need the DataDDS to hold specializations of the type classes,
+    be sure to include the factory class which will instantiate those
+    specializations in the DataDDS. Either pass a pointer to the factory to
+    DataDDS constructor or use the DDS::set_factory() method after the
+    object is built.
+
+    @brief Get the DAS from a server.
+    @param data Result.
+    @param expr Send this constraint expression to the server. */
+void
+Connect::request_data(DataDDS &data, string expr)
+{
+    string proj, sel;
+    string::size_type dotpos = expr.find('&');
+    if (dotpos != expr.npos) {
+        proj = expr.substr(0, dotpos);
+        sel = expr.substr(dotpos);
+    }
+    else {
+        proj = expr;
+        sel = "";
+    }
+
+    string data_url = _URL + ".dods?"
+                      + id2www_ce(_proj + proj + _sel + sel);
+
+    Response *rs = 0;
+    // We need to catch Error exceptions to ensure calling close_output.
+    try {
+        rs = d_http->fetch_url(data_url);
+
+        d_version = rs->get_version();
+        d_protocol = rs->get_protocol();
+
+        process_data(data, rs);
+        delete rs; rs = 0;
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+}
+
+/** Reads the DataDDS object corresponding to the dataset in the Connect
+    object's URL. If present in the Connect object's instance, a CE will be
+    escaped, combined with \c expr and passed as the query string of the
+    request. The result is a DataDDS which contains the data values bound to
+    variables.
+
+    Different from request_data in that this method uses the syntax of the
+    new OPeNDAP server commands using dispatch
+
+    @note If you need the DataDDS to hold specializations of the type classes,
+    be sure to include the factory class which will instantiate those
+    specializations in the DataDDS. Either pass a pointer to the factory to
+    DataDDS constructor or use the DDS::set_factory() method after the
+    object is built.
+
+    @brief Get the DAS from a server.
+    @param data Result. */
+void
+Connect::request_data_url(DataDDS &data)
+{
+    string use_url = _URL + "?" + _proj + _sel ;
+    Response *rs = 0;
+    // We need to catch Error exceptions to ensure calling close_output.
+    try {
+        rs = d_http->fetch_url(use_url);
+
+        d_version = rs->get_version();
+        d_protocol = rs->get_protocol();
+
+        process_data(data, rs);
+        delete rs; rs = 0;
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+}
+
+void
+Connect::request_data_ddx(DataDDS &data, string expr)
+{
+    string proj, sel;
+    string::size_type dotpos = expr.find('&');
+    if (dotpos != expr.npos) {
+        proj = expr.substr(0, dotpos);
+        sel = expr.substr(dotpos);
+    }
+    else {
+        proj = expr;
+        sel = "";
+    }
+
+    string data_url = _URL + ".dap?"
+                      + id2www_ce(_proj + proj + _sel + sel);
+
+    Response *rs = 0;
+    // We need to catch Error exceptions to ensure calling close_output.
+    try {
+        rs = d_http->fetch_url(data_url);
+
+        d_version = rs->get_version();
+        d_protocol = rs->get_protocol();
+
+        process_data(data, rs);
+        delete rs; rs = 0;
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+}
+
+void
+Connect::request_data_ddx_url(DataDDS &data)
+{
+    string use_url = _URL + "?" + _proj + _sel ;
+    Response *rs = 0;
+    // We need to catch Error exceptions to ensure calling close_output.
+    try {
+        rs = d_http->fetch_url(use_url);
+
+        d_version = rs->get_version();
+        d_protocol = rs->get_protocol();
+
+        process_data(data, rs);
+        delete rs; rs = 0;
+    }
+    catch (Error &e) {
+        delete rs; rs = 0;
+        throw ;
+    }
+}
+
+/** @brief Read data which is preceded by MIME headers.
+    This method works for both data dds and data ddx responses.
+
+    @note If you need the DataDDS to hold specializations of the type classes,
+    be sure to include the factory class which will instantiate those
+    specializations in the DataDDS. Either pass a pointer to the factory to
+    DataDDS constructor or use the DDS::set_factory() method after the
+    object is built.
+
+    @see read_data_no_mime()
+    @param data Result.
+    @param rs Read from this Response object. */
+
+void
+Connect::read_data(DataDDS &data, Response *rs)
+{
+    if (!rs)
+        throw InternalErr(__FILE__, __LINE__, "Response object is null.");
+
+    // Read from data_source and parse the MIME headers specific to DAP2/4.
+    parse_mime(rs);
+
+    read_data_no_mime(data, rs);
+}
+
+// This function looks at the input stream and makes its best guess at what
+// lies in store for downstream processing code. Definitely heuristic.
+// Assumptions:
+// #1 The current file position is past any MIME headers (if they were present).
+// #2 We must reset the FILE* position to the start of the DDS or DDX headers
+static void
+divine_type_information(Response *rs)
+{
+    // Consume whitespace
+    char c = getc(rs->get_stream());
+    while (isspace(c)) {
+	c = getc(rs->get_stream());
+    }
+
+    // The heuristic here is that a DataDDX is a multipart MIME document and
+    // The first non space character found after the headers is the start of
+    // the first part which looks like '--<boundary>' while a DataDDS starts
+    // with a DDS (;Dataset {' ...). I take into account that our parsers have
+    // accepted both 'Dataset' and 'dataset' for a long time.
+    switch (c) {
+    case '-':
+	rs->set_type(dap4_data_ddx);
+	break;
+    case 'D':
+    case 'd':
+	rs->set_type(dods_data);
+	break;
+    default:
+	throw InternalErr(__FILE__, __LINE__, "Could not determine type of response object in stream.");
+    }
+
+    ungetc(c, rs->get_stream());
+}
+
+/** @brief Read data from a file which does not have response MIME headers.
+    This method is a companion to read_data(). While read_data() assumes that
+    the response has MIME headers, this method does not. If you call this
+    with a Response that does contain headers, it will throw an Error (and
+    the message is likely to be inscrutable).
+
+    @note This method will use the 'type' information in the Response object
+    to choose between processing the response as a data dds or data ddx. If
+    there is no type information, it will attempt to figure it out.
+
+    @param data Result.
+    @param rs Read from this Response object. */
+void
+Connect::read_data_no_mime(DataDDS &data, Response *rs)
+{
+    if (rs->get_type() == unknown_type)
+	divine_type_information(rs);
+
+    switch (rs->get_type()) {
+    case dods_data:
+	d_version = rs->get_version();
+	d_protocol = rs->get_protocol();
+	process_data(data, rs);
+	break;
+    case dap4_data_ddx:
+	process_data(data, rs);
+	d_version = rs->get_version();
+	d_protocol = data.get_protocol();
+	break;
+    default:
+	throw InternalErr(__FILE__, __LINE__, "Should have been a DataDDS or DataDDX.");
+    }
+}
+
+bool
+Connect::is_local()
+{
+    return _local;
+}
+
+/** Return the Connect object's URL in a string.  The URL was set by
+    the class constructor, and may not be reset.  If you want to
+    open another URL, you must create another Connect object.  There
+    is a Connections class created to handle the management of
+    multiple Connect objects.
+
+    @brief Get the object's URL.
+    @see Connections
+    @return A string containing the URL of the data to which the
+    Connect object refers.  If the object refers to local data,
+    the function returns the null string.
+    @param ce If TRUE, the returned URL will include any constraint
+    expression enclosed with the Connect object's URL (including the
+    <tt>?</tt>).  If FALSE, any constraint expression will be removed from
+    the URL.  The default is TRUE.
+*/
+string
+Connect::URL(bool ce)
+{
+    if (_local)
+        throw InternalErr(__FILE__, __LINE__,
+                          "URL(): This call is only valid for a DAP data source.");
+
+    if (ce)
+        return _URL + "?" + _proj + _sel;
+    else
+        return _URL;
+}
+
+/** Return the constraint expression (CE) part of the Connect URL. Note
+    that this CE is supplied as part of the URL passed to the
+    Connect's constructor.  It is not the CE passed to the
+    <tt>request_data()</tt> function.
+
+    @brief Get the Connect's constraint expression.
+    @return A string containing the constraint expression (if any)
+    submitted to the Connect object's constructor.  */
+string
+Connect::CE()
+{
+    if (_local)
+        throw InternalErr(__FILE__, __LINE__,
+                          "CE(): This call is only valid for a DAP data source.");
+
+    return _proj + _sel;
+}
+
+/** @brief Set the credentials for responding to challenges while dereferencing
+    URLs.
+    @param u The username.
+    @param p The password.
+    @see extract_auth_info() */
+void
+Connect::set_credentials(string u, string p)
+{
+    if (d_http)
+        d_http->set_credentials(u, p);
+}
+
+/** Set the \e accept deflate property.
+    @param deflate True if the client can accept compressed responses, False
+    otherwise. */
+void
+Connect::set_accept_deflate(bool deflate)
+{
+    if (d_http)
+        d_http->set_accept_deflate(deflate);
+}
+
+/** Set the \e XDAP-Accept property/header. This is used to send to a server
+    the (highest) DAP protocol version number that this client understands.
+
+    @param major The client dap protocol major version
+    @param minor The client dap protocol minor version */
+void
+Connect::set_xdap_protocol(int major, int minor)
+{
+    if (d_http)
+        d_http->set_xdap_protocol(major, minor);
+}
+
+/** Disable any further use of the client-side cache. In a future version
+    of this software, this should be handled so that the www library is
+    not initialized with the cache running by default. */
+void
+Connect::set_cache_enabled(bool cache)
+{
+    if (d_http)
+        d_http->set_cache_enabled(cache);
+}
+
+bool
+Connect::is_cache_enabled()
+{
+    bool status;
+    DBG(cerr << "Entering is_cache_enabled (" << hex << d_http << dec
+        << ")... ");
+    if (d_http)
+        status = d_http->is_cache_enabled();
+    else
+        status = false;
+    DBGN(cerr << "exiting" << endl);
+    return status;
+}
+
+} // namespace libdap
diff --git a/Connect.h b/Connect.h
new file mode 100644
index 0000000..8547788
--- /dev/null
+++ b/Connect.h
@@ -0,0 +1,226 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//         Dan Holloway <dan at hollywood.gso.uri.edu>
+//         Reza Nekovei <reza at intcomm.net>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999,2001,2002
+// Please first read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+// jhrg,jimg James Gallagher <jgallagher at gso.uri.edu>
+// dan  Dan Holloway <dholloway at gso.uri.edu>
+// reza  Reza Nekovei <rnekovei at ieee.org>
+
+// Connect objects are used as containers for information pertaining to a
+// connection that a user program makes to a dataset. The dataset may be
+// either local (i.e., a file on the user's own computer) or a remote
+// dataset. In the later case a DAP2 URL will be used to reference the
+// dataset.
+//
+// Connect contains methods which can be used to read the DOS DAS and DDS
+// objects from the remote dataset as well as reading reading data. The class
+// understands in a rudimentary way how DAP2 constraint expressions are
+// formed and how to manage the CEs generated by a API to request specific
+// variables with the URL initially presented to the class when the object
+// was instantiated.
+//
+// Connect also provides additional services such as error processing.
+//
+// Connect is not intended for use on the server-side.
+//
+// jhrg 9/29/94
+
+#ifndef _connect_h
+#define _connect_h
+
+
+#include <string>
+
+#ifndef _das_h
+#include "DAS.h"
+#endif
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+#ifndef _util_h
+#include "util.h"
+#endif
+
+#ifndef _datadds_h
+#include "DataDDS.h"
+#endif
+
+#ifndef _httpconnect_h
+#include "HTTPConnect.h"
+#endif
+
+#ifndef response_h
+#include "Response.h"
+#endif
+
+using std::string;
+
+namespace libdap
+{
+
+/** Connect objects are used as containers for information pertaining
+    to the connection a user program makes to a dataset. The
+    dataset may be either local (for example, a file on the user's own
+    computer) or a remote dataset. In the latter case a DAP2 URL will
+    be used to reference the dataset, instead of a filename.
+
+    Connect contains methods which can be used to read the DAP2 DAS and
+    DDS objects from the remote dataset as well as reading
+    data. The class understands in a rudimentary way how DAP2
+    constraint expressions are formed and how to manage them.
+
+    Connect also provides additional services such as automatic
+    decompression of compressed data and and error processing.
+
+    @note Update: I removed the DEFAULT_BASETYPE_FACTORY switch because it
+    caused more confusion than it avoided. See Trac #130.
+
+    @note The compile-time symbol DEFAULT_BASETYPE_FACTORY controls whether
+    the old (3.4 and earlier) DDS and DataDDS constructors are supported.
+    These constructors now use a default factory class (BaseTypeFactory,
+    implemented by this library) to instantiate Byte, ..., Grid variables. To
+    use the default ctor in your code you must also define this symbol. If
+    you \e do choose to define this and fail to provide a specialization of
+    BaseTypeFactory when your software needs one, you code may not link or
+    may fail at run time. In addition to the older ctors for DDS and DataDDS,
+    defining the symbol also makes some of the older methods in Connect
+    available (because those methods require the older DDS and DataDDS ctors.
+
+    @brief Holds information about the link from a DAP2 client to a
+    dataset.
+    @see DDS
+    @see DAS
+    @see Error
+    @author jhrg */
+
+class Connect
+{
+private:
+    bool _local;  // Is this a local connection?
+
+    HTTPConnect *d_http;
+    string _URL;  // URL to remote dataset (minus CE)
+    string _proj;  // Projection part of initial CE.
+    string _sel;  // Selection of initial CE
+
+    string d_version;           // Server implementation information
+    string d_protocol;          // DAP protocol from the server
+
+    void process_data(DataDDS &data, Response *rs);
+    // Use when you cannot use libwww/libcurl. Reads HTTP response.
+    void parse_mime(Response *rs);
+
+protected:
+    /** @name Suppress the C++ defaults for these. */
+    //@{
+    Connect() : d_http(0)
+    { }
+    Connect(const Connect &) : d_http(0)
+    { }
+    Connect &operator=(const Connect &)
+    {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented assignment");
+    }
+    //@}
+
+public:
+    Connect(const string &name, string uname = "", string password = "")
+    throw(Error, InternalErr);
+
+    virtual ~Connect();
+
+    bool is_local();
+
+    // *** Add get_* versions of accessors. 02/27/03 jhrg
+    virtual string URL(bool CE = true);
+    virtual string CE();
+
+    void set_credentials(string u, string p);
+    void set_accept_deflate(bool deflate);
+    void set_xdap_protocol(int major, int minor);
+
+    void set_cache_enabled(bool enabled);
+    bool is_cache_enabled();
+
+    void set_xdap_accept(int major, int minor);
+
+    /** Return the protocol/implementation version of the most recent
+    response. This is a poorly designed method, but it returns
+    information that is useful when used correctly. Before a response is
+    made, this contains the string "unknown." This should ultimately hold
+    the \e protocol version; it currently holds the \e implementation
+    version.
+
+        @see get_protocol()
+        @deprecated */
+    string get_version()
+    {
+        return d_version;
+    }
+
+    /** Return the DAP protocol version of the most recent
+        response. Before a response is made, this contains the string "2.0."
+        */
+    string get_protocol()
+    {
+        return d_protocol;
+    }
+
+    virtual string request_version();
+    virtual string request_protocol();
+
+    virtual void request_das(DAS &das);
+    virtual void request_das_url(DAS &das);
+
+    virtual void request_dds(DDS &dds, string expr = "");
+    virtual void request_dds_url(DDS &dds);
+
+    virtual void request_ddx(DDS &dds, string expr = "");
+    virtual void request_ddx_url(DDS &dds);
+
+    virtual void request_data(DataDDS &data, string expr = "");
+    virtual void request_data_url(DataDDS &data);
+
+    virtual void request_data_ddx(DataDDS &data, string expr = "");
+    virtual void request_data_ddx_url(DataDDS &data);
+
+    virtual void read_data(DataDDS &data, Response *rs);
+    virtual void read_data_no_mime(DataDDS &data, Response *rs);
+};
+
+} // namespace libdap
+
+#endif // _connect_h
diff --git a/ConstraintEvaluator.cc b/ConstraintEvaluator.cc
new file mode 100644
index 0000000..c1f02a5
--- /dev/null
+++ b/ConstraintEvaluator.cc
@@ -0,0 +1,467 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: ConstraintEvaluator.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include "ConstraintEvaluator.h"
+
+#include "ce_functions.h"
+#include "parser.h"
+#include "ce_parser.h"
+#include "debug.h"
+
+struct yy_buffer_state;
+yy_buffer_state *ce_expr_scan_string(const char *str);
+int ce_exprparse(void *arg);
+
+// Glue routines declared in expr.lex
+void ce_expr_switch_to_buffer(void *new_buffer);
+void ce_expr_delete_buffer(void * buffer);
+void *ce_expr_string(const char *yy_str);
+
+namespace libdap {
+
+ConstraintEvaluator::ConstraintEvaluator()
+{
+    register_functions(*this);
+}
+
+ConstraintEvaluator::~ConstraintEvaluator()
+{
+    // delete all the constants created by the parser for CE evaluation
+    for (Constants_iter j = constants.begin(); j != constants.end(); j++) {
+        BaseType *btp = *j ;
+        delete btp ; btp = 0;
+    }
+
+    for (Clause_iter k = expr.begin(); k != expr.end(); k++) {
+        Clause *cp = *k ;
+        delete cp ; cp = 0;
+    }
+}
+
+/** Returns the first clause in a parsed constraint expression. */
+ConstraintEvaluator::Clause_iter
+ConstraintEvaluator::clause_begin()
+{
+    return expr.begin() ;
+}
+
+/** Returns a reference to the end of the list of clauses in a parsed
+    constraint expression. It does not reference the last clause */
+ConstraintEvaluator::Clause_iter
+ConstraintEvaluator::clause_end()
+{
+    return expr.end() ;
+}
+
+/** Returns the value of the indicated clause of a constraint
+    expression. */
+bool
+ConstraintEvaluator::clause_value(Clause_iter &iter, DDS &dds/*, const string &***/)
+{
+    if (expr.empty())
+        throw InternalErr(__FILE__, __LINE__,
+                          "There are no CE clauses for *this* DDS object.");
+
+    return (*iter)->value(dds);
+}
+
+/** @brief Add a clause to a constraint expression.
+
+    This function adds an operator clause to the constraint
+    expression.
+
+    @param op An integer indicating the operator in use.  These
+    values are generated by \c bison.
+    @param arg1 A pointer to the argument on the left side of the
+    operator.
+    @param arg2 A pointer to a list of the arguments on the right
+    side of the operator.
+*/
+void
+ConstraintEvaluator::append_clause(int op, rvalue *arg1, rvalue_list *arg2)
+{
+    Clause *clause = new Clause(op, arg1, arg2);
+
+    expr.push_back(clause);
+}
+
+/** @brief Add a clause to a constraint expression.
+
+    This function adds a boolean function clause to the constraint
+    expression.
+
+    @param func A pointer to a boolean function from the list of
+    supported functions.
+    @param args A list of arguments to that function.
+*/
+void
+ConstraintEvaluator::append_clause(bool_func func, rvalue_list *args)
+{
+    Clause *clause = new Clause(func, args);
+
+    expr.push_back(clause);
+}
+
+/** @brief Add a clause to a constraint expression.
+
+    This function adds a real-valued (BaseType) function clause to
+    the constraint expression.
+
+    @param func A pointer to a BaseType function from the list of
+    supported functions.
+    @param args A list of arguments to that function.
+*/
+void
+ConstraintEvaluator::append_clause(btp_func func, rvalue_list *args)
+{
+    Clause *clause = new Clause(func, args);
+
+    expr.push_back(clause);
+}
+
+/** The Constraint Evaluator maintains a list of BaseType pointers for all the
+ 	 constants that the constraint expression parser generates. These objects
+ 	 are deleted by the Constraint Evaluator destructor. Note that there are no
+ 	 list accessors; these constants are never accessed from the list. The list
+ 	 is simply a convenient way to make sure the constants are disposed of
+ 	 properly.
+ */
+void
+ConstraintEvaluator::append_constant(BaseType *btp)
+{
+    constants.push_back(btp);
+}
+
+class func_name_is
+{
+private:
+    const string d_name;
+
+public:
+    func_name_is(const string &name): d_name(name)
+    {}
+    bool operator()(const ConstraintEvaluator::function f)
+    {
+        return f.name == d_name;
+    }
+};
+
+/** The Constraint Evaluator carries with it a list of external functions it
+    can use while evaluate a constraint expression. If a constraint contains
+    any of these functions, the entries in the list allow the parser to evaluate
+    it. The functions are of three types: those that return boolean values,
+    those that return real (also called BaseType) values, and those that
+    are applied during evaluation of the projection for side effect
+
+    @note The add_function() methods will replace a function of the same name,
+    so it is possible to overwrite functions in specific handlers if the
+    handler need special behavior to implement one of the standard functions.
+
+    @see ce_functions for the standard functions
+
+    These methods are used to manipulate this list of known
+    external functions.
+
+    @name External Function Accessors
+*/
+//@{
+/** @brief Add a boolean function to the list. */
+void
+ConstraintEvaluator::add_function(const string &name, bool_func f)
+{
+    functions.remove_if(func_name_is(name));
+    function func(name, f);
+    functions.push_back(func);
+}
+
+/** @brief Add a BaseType function to the list. */
+void
+ConstraintEvaluator::add_function(const string &name, btp_func f)
+{
+    functions.remove_if(func_name_is(name));
+    function func(name, f);
+    functions.push_back(func);
+}
+
+/** @brief Add a projection function to the list. */
+void
+ConstraintEvaluator::add_function(const string &name, proj_func f)
+{
+    functions.remove_if(func_name_is(name));
+    function func(name, f);
+    functions.push_back(func);
+}
+
+/** @brief Find a Boolean function with a given name in the function list. */
+bool
+ConstraintEvaluator::find_function(const string &name, bool_func *f) const
+{
+    if (functions.empty())
+        return false;
+
+    for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
+        if (name == (*i).name && (*f = (*i).b_func)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/** @brief Find a BaseType function with a given name in the function list. */
+bool
+ConstraintEvaluator::find_function(const string &name, btp_func *f) const
+{
+    if (functions.empty())
+        return false;
+
+    for (Functions_citer i = functions.begin(); i != functions.end(); i++) {
+        if (name == (*i).name && (*f = (*i).bt_func)) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+/** @brief Find a projection function with a given name in the function list. */
+bool
+ConstraintEvaluator::find_function(const string &name, proj_func *f) const
+{
+    if (functions.empty())
+        return false;
+
+    for (Functions_citer i = functions.begin(); i != functions.end(); i++)
+        if (name == (*i).name && (*f = (*i).p_func)) {
+            return true;
+        }
+
+    return false;
+}
+//@}
+
+/** @brief Does the current constraint expression return a BaseType
+    pointer?
+    This method does not evaluate the clause, it provides information to the
+    evaluator regarding _how_ to evaluate the clause.
+    @return True if the clause is a function that returns a BaseType* and
+    false otherwise */
+bool
+ConstraintEvaluator::functional_expression()
+{
+    if (expr.empty())
+        return false;
+
+    Clause *cp = expr[0] ;
+    return cp->value_clause();
+}
+
+/** @brief Evaluate a function-valued constraint expression. */
+BaseType *
+ConstraintEvaluator::eval_function(DDS &dds, const string &)
+{
+    if (expr.size() != 1)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The length of the list of CE clauses is not 1.");
+
+    Clause *cp = expr[0] ;
+    BaseType *result;
+    if (cp->value(dds, &result))
+        return result;
+    else
+        return NULL;
+}
+
+/** @brief Does the current constraint expression return a DDS pointer?
+
+    This method does not evaluate the clauses, it provides information to the
+    evaluator regarding _how_ to evaluate the clause.
+
+    @note Added for libdap 3.11
+
+    @return True if the clause is a function that returns a DDS* and
+    false otherwise */
+bool ConstraintEvaluator::function_clauses()
+{
+    if (expr.empty())
+	return false;
+
+    for (unsigned int i = 0; i < expr.size(); ++i) {
+	Clause *cp = expr[i];
+	if (!cp->value_clause())
+	    return false;
+    }
+
+    return true;
+}
+
+/** @brief Evaluate a function-valued constraint expression that contains
+    several function calls.
+
+    This method can be called for any function-valued constraint expression.
+    Unlike eval_function(), it will package the return value in a new DDS
+    object. The server should free this object once it has been serialized
+    and sent.
+
+    @note While there is another type of function that can appear in a CE (a
+    'projection function') those are evaluated by the ce parser - they are used
+    to insert new variables into the DDS as a side effect of CE evaluation.
+    That kind of function can never appear here; these are all functions that
+    return BaseType pointers.
+
+    @note Added for libdap 3.11 */
+DDS *
+ConstraintEvaluator::eval_function_clauses(DDS &dds)
+{
+    if (expr.empty())
+	throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty.");
+
+    DDS *fdds = new DDS(dds.get_factory(), "function_result_" + dds.get_dataset_name());
+    for (unsigned int i = 0; i < expr.size(); ++i) {
+	Clause *cp = expr[i];
+	BaseType *result;
+	if (cp->value(dds, &result)) {
+	    result->set_send_p(true);
+	    fdds->add_var(result);
+	}
+	else {
+		delete fdds;
+	    throw Error("A function was called but failed to return a value.");
+	}
+    }
+
+    return fdds;
+}
+
+/** @brief Evaluate a function-valued constraint expression that contains
+    several function calls. Takes and returns a DataDDS.
+
+    @see ConstraintEvaluator::eval_function_clauses(DataDDS &dds)
+    @note Added for libdap 3.11 */
+DataDDS *
+ConstraintEvaluator::eval_function_clauses(DataDDS &dds)
+{
+    if (expr.empty())
+	throw InternalErr(__FILE__, __LINE__, "The constraint expression is empty.");
+
+    DataDDS *fdds = new DataDDS(dds.get_factory(),
+				"function_result_" + dds.get_dataset_name(),
+				dds.get_version(), dds.get_protocol());
+
+    for (unsigned int i = 0; i < expr.size(); ++i) {
+	Clause *cp = expr[i];
+	BaseType *result;
+	if (cp->value(dds, &result)) {
+	    result->set_send_p(true);
+	    fdds->add_var(result);
+	}
+	else {
+		delete fdds;
+	    throw Error("A function was called but failed to return a value.");
+	}
+    }
+
+    return fdds;
+}
+
+/** @brief Does the current constraint expression return a boolean value? */
+bool
+ConstraintEvaluator::boolean_expression()
+{
+    if (expr.empty())
+        return false;
+
+    bool boolean = true;
+    for (Clause_iter i = expr.begin(); i != expr.end(); i++) {
+        boolean = boolean && (*i)->boolean_clause();
+    }
+
+    return boolean;
+}
+
+
+/** @brief Evaluate a boolean-valued constraint expression.
+    This is main method for the evaluator ans is called by the
+    BaseType::serialize() methods.
+
+    @param dds Use these variables when evaluating the expressions.
+    @param dataset This string is passed to the read() methods.
+    @return True if the expression is true, false otherwise. */
+bool
+ConstraintEvaluator::eval_selection(DDS &dds, const string &)
+{
+    if (expr.empty()) {
+        DBG(cerr << "No selection recorded" << endl);
+        return true;
+    }
+
+    DBG(cerr << "Eval selection" << endl);
+
+    // A CE is made up of zero or more clauses, each of which has a boolean
+    // value. The value of the CE is the logical AND of the clause
+    // values. See ConstraintEvaluator::clause::value(...) for information on logical ORs in
+    // CEs.
+    bool result = true;
+    for (Clause_iter i = expr.begin(); i != expr.end() && result; i++) {
+        // A selection expression *must* contain only boolean clauses!
+        if (!((*i)->boolean_clause()))
+            throw InternalErr(__FILE__, __LINE__,
+                              "A selection expression must contain only boolean clauses.");
+        result = result && (*i)->value(dds);
+    }
+
+    return result;
+}
+
+/** @brief Parse the constraint expression given the current DDS.
+
+    Evaluate the constraint expression; return the value of the expression.
+    As a side effect, mark the DDS so that BaseType's mfuncs can be used to
+    correctly read the variable's value and send it to the client.
+
+    @param constraint A string containing the constraint expression.
+    @param dds The DDS that provides the environment within which the
+    constraint is evaluated.
+    @exception Throws Error if the constraint does not parse. */
+void
+ConstraintEvaluator::parse_constraint(const string &constraint, DDS &dds)
+{
+    void *buffer = ce_expr_string(constraint.c_str());
+    ce_expr_switch_to_buffer(buffer);
+
+    ce_parser_arg arg(this, &dds);
+
+    // For all errors, exprparse will throw Error.
+    ce_exprparse((void *)&arg);
+
+    ce_expr_delete_buffer(buffer);
+}
+
+} // namespace libdap
diff --git a/ConstraintEvaluator.h b/ConstraintEvaluator.h
new file mode 100644
index 0000000..35020b1
--- /dev/null
+++ b/ConstraintEvaluator.h
@@ -0,0 +1,136 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef constraint_evaluator_h
+#define constraint_evaluator_h
+
+#include <list>
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef _datadds_h
+#include "DataDDS.h"
+#endif
+
+#ifndef _clause_h
+#include "Clause.h"
+#endif
+
+namespace libdap
+{
+
+/** @brief Evaluate a constraint expression */
+class ConstraintEvaluator
+{
+private:
+    // This struct is used to hold all the known `user defined' functions
+    // (including those that are `built-in').
+    struct function
+    {
+        string name;
+        bool_func b_func;
+        btp_func bt_func;
+        proj_func p_func;
+
+        function(const string &n, const bool_func f)
+                : name(n), b_func(f), bt_func(0), p_func(0)
+        {}
+        function(const string &n, const btp_func f)
+                : name(n), bt_func(f), p_func(0)
+        {}
+        function(const string &n, const proj_func f)
+                : name(n), bt_func(0), p_func(f)
+        {}
+        function(): name(""), bt_func(0), p_func(0)
+        {}
+    };
+
+    vector<Clause *> expr;      // List of CE Clauses
+
+    vector<BaseType *> constants;// List of temporary objects
+
+    list<function> functions; // Known external functions
+
+    // The default versions of these methods will break this class. Because
+    // Clause does not support deep copies, that class will need to be modified
+    // before these can be properly implemented. jhrg 4/3/06
+    ConstraintEvaluator(const ConstraintEvaluator &)
+    {}
+    ConstraintEvaluator &operator=(const ConstraintEvaluator &)
+    {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+    }
+
+    friend class func_name_is;
+
+public:
+    typedef std::vector<Clause *>::const_iterator Clause_citer ;
+    typedef std::vector<Clause *>::iterator Clause_iter ;
+
+    typedef std::vector<BaseType *>::const_iterator Constants_citer ;
+    typedef std::vector<BaseType *>::iterator Constants_iter ;
+
+    typedef std::list<function>::const_iterator Functions_citer ;
+    typedef std::list<function>::iterator Functions_iter ;
+
+    ConstraintEvaluator();
+    virtual ~ConstraintEvaluator();
+
+    void add_function(const string &name, bool_func f);
+    void add_function(const string &name, btp_func f);
+    void add_function(const string &name, proj_func f);
+
+    bool find_function(const string &name, bool_func *f) const;
+    bool find_function(const string &name, btp_func *f) const;
+    bool find_function(const string &name, proj_func *f) const;
+
+    void append_clause(int op, rvalue *arg1, rvalue_list *arg2);
+    void append_clause(bool_func func, rvalue_list *args);
+    void append_clause(btp_func func, rvalue_list *args);
+
+    bool functional_expression();
+    bool boolean_expression();
+    bool eval_selection(DDS &dds, const string &dataset);
+    BaseType *eval_function(DDS &dds, const string &dataset);
+
+    // New for libdap 3.11. These methods provide a way to evaluate multiple
+    // functions in one CE
+    bool function_clauses();
+    DDS *eval_function_clauses(DDS &dds);
+    DataDDS *eval_function_clauses(DataDDS &dds);
+
+    Clause_iter clause_begin();
+    Clause_iter clause_end();
+    bool clause_value(Clause_iter &i, DDS &dds);
+
+    void parse_constraint(const string &constraint, DDS &dds);
+    void append_constant(BaseType *btp);
+
+};
+
+} // namespace libdap
+
+#endif // constraint_evaluator_h
diff --git a/Constructor.cc b/Constructor.cc
new file mode 100644
index 0000000..d7e7daf
--- /dev/null
+++ b/Constructor.cc
@@ -0,0 +1,520 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+
+#include "config.h"
+
+#include <string>
+#include <algorithm>
+#include <functional>
+
+//#define DODS_DEBUG
+
+#include "Constructor.h"
+#include "Grid.h"
+
+#include "debug.h"
+#include "escaping.h"
+#include "Error.h"
+#include "InternalErr.h"
+
+
+using namespace std;
+
+namespace libdap {
+
+// Private member functions
+
+void
+Constructor::_duplicate(const Constructor &)
+{}
+
+// Public member functions
+
+Constructor::Constructor(const string &n, const Type &t)
+        : BaseType(n, t)
+{}
+
+/** Server-side constructor that takes the name of the variable to be
+ * created, the dataset name from which this variable is being created, and
+ * the type of data being stored in the Constructor. This is a protected
+ * constructor, available only to derived classes of Constructor
+ *
+ * @param n string containing the name of the variable to be created
+ * @param d string containing the name of the dataset from which this
+ * variable is being created
+ * @param t type of data being stored
+ */
+Constructor::Constructor(const string &n, const string &d, const Type &t)
+        : BaseType(n, d, t)
+{}
+
+Constructor::Constructor(const Constructor &rhs) : BaseType(rhs), _vars(0)
+{}
+
+Constructor::~Constructor()
+{}
+
+Constructor &
+Constructor::operator=(const Constructor &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs; // run BaseType=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+/** Returns an iterator referencing the first structure element. */
+Constructor::Vars_iter
+Constructor::var_begin()
+{
+    return _vars.begin() ;
+}
+
+/** @brief Look for the parent of an HDF4 dimension attribute
+
+    If this attribute container's name ends in the '_dim_?' suffix, look
+    for the variable to which it's attributes should be bound: For an array,
+    they should be held in a sub-table of the array; for a Structure or
+    Sequence, I don't think the HDF4 handler ever makes these (since those
+    types don't have 'dimension' in hdf-land);  and for a Grid, the attributes
+    belong with the map variables.
+
+    @note This method does check that the \e source really is an hdf4 dimension
+    attribute.
+
+    @param source The attribute container, an AttrTable::entry instance.
+    @return the BaseType to which these attributes belong or null if none
+    was found. */
+BaseType *
+Constructor::find_hdf4_dimension_attribute_home(AttrTable::entry *source)
+{
+    BaseType *btp;
+    string::size_type i = source->name.find("_dim_");
+    if (i != string::npos && (btp = var(source->name.substr(0, i)))) {
+        if (btp->is_vector_type()) {
+            return btp;
+        }
+        else if (btp->type() == dods_grid_c) {
+            // For a Grid, the hdf4 handler uses _dim_n for the n-th Map
+            // i+5 points to the character holding 'n'
+            int n = atoi(source->name.substr(i + 5).c_str());
+            DBG(cerr << "Found a Grid (" << btp->name() << ") and "
+                << source->name.substr(i) << ", extracted n: " << n << endl);
+            return *(dynamic_cast<Grid&>(*btp).map_begin() + n);
+        }
+    }
+
+    return 0;
+}
+
+#if 0
+/** Given an attribute container from a table, find or make a destination
+    for its contents in the current constructor variable. */
+AttrTable *
+Constructor::find_matching_container(AttrTable::entry *source,
+                                     BaseType **dest_variable)
+{
+    // The attribute entry 'source' must be a container
+    if (source->type != Attr_container)
+        throw InternalErr(__FILE__, __LINE__, "Constructor::find_matching_container");
+
+    // Use the name of the attribute container 'source' to figure out where
+    // to put its contents.
+    BaseType *btp;
+    if ((btp = var(source->name))) {
+        // ... matches a variable name? Use var's table
+        *dest_variable = btp;
+        return &btp->get_attr_table();
+    }
+    // As more special-case attribute containers come to light, add clauses
+    // here.
+    else if ((btp = find_hdf4_dimension_attribute_home(source))) {
+        // ... hdf4 dimension attribute? Make a sub table and use that.
+        // btp can only be an Array or a Grid Map (which is an array)
+        if (btp->get_parent()->type() == dods_grid_c) {
+            DBG(cerr << "Found a Grid" << endl);
+            *dest_variable = btp;
+            return &btp->get_attr_table();
+        }
+        else { // must be a plain Array
+            string::size_type i = source->name.find("_dim_");
+            string ext = source->name.substr(i + 1);
+            *dest_variable = btp;
+            return btp->get_attr_table().append_container(ext);
+        }
+    }
+    else {
+        // ... otherwise assume it's a global attribute.
+        AttrTable *at = get_attr_table().find_container(source->name);
+        if (!at) {
+            at = new AttrTable();       // Make a new global table if needed
+            get_attr_table().append_container(at, source->name);
+        }
+
+        *dest_variable = 0;
+        return at;
+    }
+}
+#endif
+#if 0
+/** Given an Attribute entry, scavenge attributes from it and load them into
+    this object and the variables it contains. Assume that the caller has
+    determined the table holds attributes pertinent to only this variable.
+
+    @note This method is technically \e unnecessary because a server (or
+    client) can easily add attributes directly using the DDS::get_attr_table
+    or BaseType::get_attr_table methods and then poke values in using any
+    of the methods AttrTable provides. This method exists to ease the
+    transition to DDS objects which contain attribute information for the
+    existing servers (Since they all make DAS objects separately from the
+    DDS). They could be modified to use the same AttrTable methods but
+    operate on the AttrTable instances in a DDS/BaseType instead of those in
+    a DAS.
+
+    @param entry Get attribute information from this Attribute table. Note
+    that even though the type of the argument is an AttrTable::entry, the
+    entry \e must be an attribute container.*/
+void
+Constructor::transfer_attributes(AttrTable::entry * entry)
+{
+    DBG(cerr << "Constructor::transfer_attributes, variable: " << name() <<
+        endl);
+    DBG(cerr << "Working on the '" << entry->
+        name << "' container." << endl);
+    if (entry->type != Attr_container)
+        throw InternalErr(__FILE__, __LINE__,
+                          "Constructor::transfer_attributes");
+
+    AttrTable *source = entry->attributes;
+    BaseType *dest_variable = 0;
+    AttrTable *dest = find_matching_container(entry, &dest_variable);
+
+    // foreach source attribute in the das_i container
+    AttrTable::Attr_iter source_p = source->attr_begin();
+    while (source_p != source->attr_end()) {
+        DBG(cerr << "Working on the '" << (*source_p)->
+            name << "' attribute" << endl);
+
+        if ((*source_p)->type == Attr_container) {
+            if (dest_variable && dest_variable->is_constructor_type()) {
+                dynamic_cast <Constructor & >(*dest_variable).transfer_attributes(*source_p);
+            }
+            else {
+                dest->append_container(new AttrTable(*(*source_p)->attributes),
+                                       (*source_p)->name);
+            }
+        }
+        else {
+            dest->append_attr(source->get_name(source_p),
+                              source->get_type(source_p),
+                              source->get_attr_vector(source_p));
+        }
+
+        ++source_p;
+    }
+}
+#endif
+
+/** Given an Attribute table, scavenge attributes from it and load them into
+    this object and the variables it contains.
+
+    This implementation differs from the version in BaseType in that each of
+    the children of the Constructor are passed an attribute container if one
+    is found that matches the name of this Constructor variable.
+
+    @param at_container Search for attributes in this container.
+    */
+void Constructor::transfer_attributes(AttrTable *at_container)
+{
+    AttrTable *at = at_container->get_attr_table(name());
+
+    if (at) {
+	at->set_is_global_attribute(false);
+
+	Vars_iter var = var_begin();
+	while (var != var_end()) {
+	    (*var)->transfer_attributes(at);
+	    var++;
+	}
+
+	// Trick: If an attribute that's within the container 'at' still has its
+	// is_global_attribute property set, then it's not really a global attr
+	// but instead an attribute that belongs to this Constructor.
+	AttrTable::Attr_iter at_p = at->attr_begin();
+	while (at_p != at->attr_end()) {
+	    if (at->is_global_attribute(at_p)) {
+		if (at->get_attr_type(at_p) == Attr_container)
+		    get_attr_table().append_container(new AttrTable(
+			    *at->get_attr_table(at_p)), at->get_name(at_p));
+		else
+		    get_attr_table().append_attr(at->get_name(at_p),
+			    at->get_type(at_p), at->get_attr_vector(at_p));
+	    }
+	    at_p++;
+	}
+
+    }
+}
+
+/** Returns an iterator referencing the end of the list of structure
+    elements. Does not reference the last structure element. */
+Constructor::Vars_iter
+Constructor::var_end()
+{
+    return _vars.end() ;
+}
+
+/** Return a reverse iterator that references the last element. */
+Constructor::Vars_riter
+Constructor::var_rbegin()
+{
+    return _vars.rbegin();
+}
+
+/** Return a reverse iterator that references a point 'before' the first
+    element. */
+Constructor::Vars_riter
+Constructor::var_rend()
+{
+    return _vars.rend();
+}
+
+/** Return the iterator for the \e ith variable.
+    @param i the index
+    @return The corresponding  Vars_iter */
+Constructor::Vars_iter
+Constructor::get_vars_iter(int i)
+{
+    return _vars.begin() + i;
+}
+
+/** Return the BaseType pointer for the \e ith variable.
+    @param i This index
+    @return The corresponding BaseType*. */
+BaseType *
+Constructor::get_var_index(int i)
+{
+    return *(_vars.begin() + i);
+}
+
+#if FILE_METHODS
+void
+Constructor::print_decl(FILE *out, string space, bool print_semi,
+                        bool constraint_info, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
+    for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->print_decl(out, space + "    ", true,
+                         constraint_info, constrained);
+    }
+    fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
+
+    if (constraint_info) { // Used by test drivers only.
+        if (send_p())
+            cout << ": Send True";
+        else
+            cout << ": Send False";
+    }
+
+    if (print_semi)
+        fprintf(out, ";\n") ;
+}
+#endif
+
+void
+Constructor::print_decl(ostream &out, string space, bool print_semi,
+                        bool constraint_info, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    out << space << type_name() << " {\n" ;
+    for (Vars_citer i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->print_decl(out, space + "    ", true,
+                         constraint_info, constrained);
+    }
+    out << space << "} " << id2www(name()) ;
+
+    if (constraint_info) { // Used by test drivers only.
+        if (send_p())
+            out << ": Send True";
+        else
+            out << ": Send False";
+    }
+
+    if (print_semi)
+	out << ";\n" ;
+}
+
+#if FILE_METHODS
+class PrintField : public unary_function<BaseType *, void>
+{
+    FILE *d_out;
+    string d_space;
+    bool d_constrained;
+public:
+    PrintField(FILE *o, string s, bool c)
+            : d_out(o), d_space(s), d_constrained(c)
+    {}
+
+    void operator()(BaseType *btp)
+    {
+        btp->print_xml(d_out, d_space, d_constrained);
+    }
+};
+
+void
+Constructor::print_xml(FILE *out, string space, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    bool has_attributes = false; // *** fix me
+    bool has_variables = (var_begin() != var_end());
+
+    fprintf(out, "%s<%s", space.c_str(), type_name().c_str());
+    if (!name().empty())
+        fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
+
+    if (has_attributes || has_variables) {
+        fprintf(out, ">\n");
+
+        get_attr_table().print_xml(out, space + "    ", constrained);
+
+        for_each(var_begin(), var_end(),
+                 PrintField(out, space + "    ", constrained));
+
+        fprintf(out, "%s</%s>\n", space.c_str(), type_name().c_str());
+    }
+    else {
+        fprintf(out, "/>\n");
+    }
+}
+#endif
+
+class PrintFieldStrm : public unary_function<BaseType *, void>
+{
+    ostream &d_out;
+    string d_space;
+    bool d_constrained;
+public:
+    PrintFieldStrm(ostream &o, string s, bool c)
+            : d_out(o), d_space(s), d_constrained(c)
+    {}
+
+    void operator()(BaseType *btp)
+    {
+        btp->print_xml(d_out, d_space, d_constrained);
+    }
+};
+
+void
+Constructor::print_xml(ostream &out, string space, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    bool has_attributes = false; // *** fix me
+    bool has_variables = (var_begin() != var_end());
+
+    out << space << "<" << type_name() ;
+    if (!name().empty())
+	out << " name=\"" << id2xml(name()) << "\"" ;
+
+    if (has_attributes || has_variables) {
+	out << ">\n" ;
+
+        get_attr_table().print_xml(out, space + "    ", constrained);
+
+        for_each(var_begin(), var_end(),
+                 PrintFieldStrm(out, space + "    ", constrained));
+
+	out << space << "</" << type_name() << ">\n" ;
+    }
+    else {
+	out << "/>\n" ;
+    }
+}
+
+/** True if the instance can be flattened and printed as a single table
+    of values. For Arrays and Grids this is always false. For Structures
+    and Sequences the conditions are more complex. The implementation
+    provided by this class always returns false. Other classes should
+    override this implementation.
+
+    @todo Change the name to is_flattenable or something like that. 05/16/03
+    jhrg
+
+    @brief Check to see whether this variable can be printed simply.
+    @return True if the instance can be printed as a single table of
+    values, false otherwise. */
+bool
+Constructor::is_linear()
+{
+    return false;
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Constructor::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Constructor::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "vars: " << endl ;
+    DapIndent::Indent() ;
+    Vars_citer i = _vars.begin() ;
+    Vars_citer ie = _vars.end() ;
+    for (; i != ie; i++) {
+        (*i)->dump(strm) ;
+    }
+    DapIndent::UnIndent() ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Constructor.h b/Constructor.h
new file mode 100644
index 0000000..12ccd1d
--- /dev/null
+++ b/Constructor.h
@@ -0,0 +1,103 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _constructor_h
+#define _constructor_h 1
+
+#include <vector>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** Common methods for all constructor types. */
+class Constructor: public BaseType
+{
+private:
+    Constructor();  // No default ctor.
+    BaseType *find_hdf4_dimension_attribute_home(AttrTable::entry *source);
+
+protected:
+    std::vector<BaseType *> _vars;
+
+    void _duplicate(const Constructor &s);
+#if 0
+    virtual AttrTable *find_matching_container(AttrTable::entry *source,
+            BaseType **dest_variable);
+#endif
+    Constructor(const string &n, const Type &t);
+    Constructor(const string &n, const string &d, const Type &t);
+
+    Constructor(const Constructor &copy_from);
+public:
+    typedef std::vector<BaseType *>::const_iterator Vars_citer ;
+    typedef std::vector<BaseType *>::iterator Vars_iter ;
+    typedef std::vector<BaseType *>::reverse_iterator Vars_riter ;
+
+    virtual ~Constructor();
+
+    Constructor &operator=(const Constructor &rhs);
+#if 0
+    virtual void transfer_attributes(AttrTable::entry *entry);
+#endif
+    virtual void transfer_attributes(AttrTable *at_container);
+
+    Vars_iter var_begin();
+    Vars_iter var_end();
+    Vars_riter var_rbegin();
+    Vars_riter var_rend();
+    Vars_iter get_vars_iter(int i);
+    BaseType *get_var_index(int i);
+
+    virtual bool is_linear();
+
+    virtual void print_decl(ostream &out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+
+    virtual void print_xml(ostream &out, string space = "    ",
+                           bool constrained = false);
+
+#if FILE_METHODS
+    virtual void print_decl(FILE *out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+    virtual void print_xml(FILE *out, string space = "    ",
+                           bool constrained = false);
+#endif
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _constructor_h
diff --git a/DAS.cc b/DAS.cc
new file mode 100644
index 0000000..a2b49c5
--- /dev/null
+++ b/DAS.cc
@@ -0,0 +1,423 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Methods for the class DAS - a class used to parse the dataset attribute
+// structure.
+//
+// jhrg 7/25/94
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: DAS.cc 24281 2011-03-09 00:22:31Z jimg $"
+    };
+
+
+#include <cstdio>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef WIN32
+#include <io.h>
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "DAS.h"
+#include "AttrTable.h"
+#include "Error.h"
+#include "InternalErr.h"
+#include "parser.h"
+#include "escaping.h"
+#include "debug.h"
+
+using std::cerr;
+using std::endl;
+
+// Glue routines declared in das.lex
+extern void das_switch_to_buffer(void *new_buffer);
+extern void das_delete_buffer(void * buffer);
+extern void *das_buffer(FILE *fp);
+
+extern void dasrestart(FILE *yyin);
+extern int dasparse(void *arg); // defined in das.tab.c
+
+namespace libdap {
+
+/** Create an empty DAS
+ */
+DAS::DAS() : DapObj(), d_container( 0 )
+{}
+
+#if 0
+DAS::DAS(AttrTable *attr, string name)
+{
+    append_container(attr, www2id(name));
+}
+#endif
+
+// FIXME: Need to create copy constructor and op=.
+
+/** @brief This deletes the pointers to AttrTables allocated during the parse
+ * (and at other times). jhrg 7/29/94
+ */
+DAS::~DAS()
+{}
+
+/** @brief Returns the name of the current attribute container when multiple
+ * files used to build this DAS
+ */
+string
+DAS::container_name()
+{
+    return _container_name ;
+}
+
+/** @brief Sets the name of the current attribute container when multiple
+ * files used to build this DAS.
+ *
+ * @param cn container name
+ */
+void
+DAS::container_name( const string &cn )
+{
+    // We want to find a top level attribute table with the given name. So
+    // set d_container to null first so that we aren't searching some
+    // previous container
+    if( cn != _container_name )
+    {
+	d_container = 0 ;
+	if( !cn.empty() )
+	{
+	    d_container = get_table( cn ) ;
+	    if( !d_container )
+	    {
+		d_container = add_table( cn, new AttrTable ) ;
+	    }
+	}
+	_container_name = cn;
+    }
+}
+
+/** @brief Returns the current attribute container when multiple files
+ * used to build this DAS.
+ *
+ * @return current attribute table for current container
+ */
+AttrTable *
+DAS::container()
+{
+    return d_container ;
+}
+
+/** @brief Returns the number of attributes in the current attribute table
+ *
+ * If the there is a container set, then return the number of variable
+ * attribute tables for the current container. If not set then return the
+ * number of current attribute tables in the outermost attribute table.
+ */
+unsigned int
+DAS::get_size() const
+{
+    if( d_container )
+    {
+	return d_container->get_size() ;
+    }
+    return d_attrs.get_size() ;
+}
+
+/** @brief erase all attributes in this DAS
+ */
+void
+DAS::erase()
+{
+    if( d_container )
+    {
+	d_container->erase() ;
+    }
+    else
+    {
+	d_attrs.erase() ;
+    }
+}
+
+/** @brief Returns a reference to the attribute table for the first variable.
+ */
+AttrTable::Attr_iter
+DAS::var_begin()
+{
+    if( d_container )
+    {
+	return d_container->attr_begin() ;
+    }
+    return d_attrs.attr_begin() ;
+}
+
+/** Returns a reference to the end of the attribute table. Does not
+ *  point to an attribute table.
+ */
+AttrTable::Attr_iter
+DAS::var_end()
+{
+    if( d_container )
+    {
+	return d_container->attr_end() ;
+    }
+    return d_attrs.attr_end() ;
+}
+
+/** @brief Returns the name of the referenced variable attribute table.
+ */
+string
+DAS::get_name(AttrTable::Attr_iter &i)
+{
+    if( d_container )
+    {
+	return d_container->get_name( i ) ;
+    }
+    return d_attrs.get_name( i ) ;
+}
+
+/** @brief Returns the referenced variable attribute table.
+ */
+AttrTable *
+DAS::get_table(AttrTable::Attr_iter &i)
+{
+    if( d_container )
+    {
+	return d_container->get_attr_table( i ) ;
+    }
+    return d_attrs.get_attr_table( i ) ;
+}
+
+/** @brief Returns the variable attribute table with the given name.
+ */
+AttrTable *
+DAS::get_table( const string &name )
+{
+    if( d_container )
+    {
+	return d_container->get_attr_table( name ) ;
+    }
+    return d_attrs.get_attr_table( name ) ;
+}
+
+//@}
+
+/** @brief Adds an attribute table to the DAS.
+    @name add_table()
+*/
+//@{
+
+/** @brief Adds a variable attribute table to the DAS or the current
+ * dataset container attribute table.
+ */
+AttrTable *
+DAS::add_table( const string &name, AttrTable *at )
+{
+    if( d_container )
+    {
+	at->set_is_global_attribute( false ) ;
+	return d_container->append_container( at, name ) ;
+    }
+    return d_attrs.append_container( at, name ) ;
+}
+
+//@}
+
+/** @brief Reads a DAS in from an external source.
+
+    @name parse()
+*/
+//@{
+
+
+/** @brief Reads a DAS from the named file.
+
+    Read attributes from a file. Returns false if unable to open
+    the file, otherwise returns the result of the mfunc parse. */
+void
+DAS::parse(string fname)
+{
+    FILE *in = fopen(fname.c_str(), "r");
+
+    if (!in) {
+        throw Error(cannot_read_file, "Could not open: " + fname);
+    }
+
+    parse(in);
+
+    int res = fclose(in);
+    if (res) {
+        DBG(cerr << "DAS::parse - Failed to close file " << (void *)in << endl ;) ;
+    }
+}
+
+/** @brief Read attributes from a file descriptor.
+
+    If the file descriptor cannot be fdopen'd, return false, otherwise
+    return the status of the mfunc parse.
+
+    \note Added call to dup() within fdopen so that once the FILE * is
+    closed the decriptor fd will not also be closed (instead the
+    duplicate descriptor will be closed). Thus further information can
+    be read from the descriptor fd.
+*/
+void
+DAS::parse(int fd)
+{
+#ifdef WIN32
+    FILE *in = fdopen(_dup(fd), "r");
+#else
+    FILE *in = fdopen(dup(fd), "r");
+#endif
+
+    if (!in) {
+        throw InternalErr(__FILE__, __LINE__, "Could not access file.");
+    }
+
+    parse(in);
+
+    int res = fclose(in);
+    if (res) {
+        DBG(cerr << "DAS::parse(fd) - Failed to close " << (void *)in << endl ;) ;
+    }
+}
+
+
+
+/** @brief Reads a DAS from an open file descriptor.
+
+    Read attributes from in (which defaults to stdin). If
+    dasrestart() fails, return false, otherwise return the status
+    of dasparse().
+*/
+void
+DAS::parse(FILE *in)
+{
+    if (!in) {
+        throw InternalErr(__FILE__, __LINE__, "Null input stream.");
+    }
+
+    void *buffer = das_buffer(in);
+    das_switch_to_buffer(buffer);
+
+    parser_arg arg(this);
+
+    bool status = dasparse((void *) & arg) == 0;
+
+    das_delete_buffer(buffer);
+
+    //  STATUS is the result of the parser function; if a recoverable error
+    //  was found it will be true but arg.status() will be false.
+    if (!status || !arg.status()) {// Check parse result
+        if (arg.error())
+            throw *arg.error();
+    }
+}
+
+//@}
+
+/** Creates an ASCII representation of a DAS on the given output
+    stream.
+
+    When an identifier contains a character that contains
+    characters that cannot be present in a URL (e.g., a space)
+    AttrTable::print replaces those characters with WWW
+    escape codes. 7/13/2001 jhrg
+
+    @param out output FILE on which to print the DAS
+    @param dereference If true, follow aliases. Default is false.
+*/
+
+void
+DAS::print(FILE *out, bool dereference)
+{
+    fprintf(out, "Attributes {\n") ;
+
+    d_attrs.print(out, "    ", dereference);
+
+    fprintf(out, "}\n") ;
+}
+
+/** Creates an ASCII representation of a DAS on the given output
+    stream.
+
+    When an identifier contains a character that contains
+    characters that cannot be present in a URL (e.g., a space)
+    AttrTable::print replaces those characters with WWW
+    escape codes. 7/13/2001 jhrg
+
+    @param out output ostream on which to print the DAS
+    @param dereference If true, follow aliases. Default is false.
+*/
+
+void
+DAS::print(ostream &out, bool dereference)
+{
+    out << "Attributes {\n" ;
+
+    d_attrs.print(out, "    ", dereference);
+
+    out << "}\n" ;
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and then calls parent dump
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+DAS::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "DAS::dump - ("
+         << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    if( d_container )
+    {
+	strm << DapIndent::LMarg << "current container: " << _container_name
+	     << endl ;
+    }
+    else
+    {
+	strm << DapIndent::LMarg << "current container: NONE" << endl ;
+    }
+    d_attrs.dump(strm) ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/DAS.h b/DAS.h
new file mode 100644
index 0000000..89217da
--- /dev/null
+++ b/DAS.h
@@ -0,0 +1,183 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Using the DASVHMap class, build a parser for the DAS and add functions
+// that provide access to the variables, their attributes and values.
+//
+// jhrg 7/25/94
+
+#ifndef _das_h
+#define _das_h 1
+
+
+#include <cstdio>
+#include <string>
+#include <iostream>
+
+//#include "Pix.h"
+
+#ifndef _attrtable_h
+#include "AttrTable.h"
+#endif
+
+using std::cout;
+
+namespace libdap
+{
+
+/** @brief Hold attribute data for a DAP2 dataset.
+
+    The Data Attribute Structure is a set of name-value pairs used to
+    describe the data in a particular dataset. The name-value pairs are
+    called the ``attributes''. The values may be of any of the DAP2 simple
+    data types (Byte, Int16, UInt16, Int32, UInt32, Float32, Float64, String
+    and URL), and may be scalar or vector. Note that all values are actually
+    stored as String data, making the easy to read/check using a web browser.
+
+    A value may also consist of a set of other name-value pairs.  This
+    makes it possible to nest collections of attributes, giving rise
+    to a hierarchy of attributes.  DAP2 uses this structure to provide
+    information about variables in a dataset.  For example, consider
+    the dataset used in the DDS example earlier.
+
+    In the following example of a DAS, several of the attribute
+    collections have names corresponding to the names of variables in
+    the DDS example.  The attributes in that collection are said to
+    belong to that variable.  For example, the <tt>lat</tt> variable has an
+    attribute ``units'' of ``degrees_north''.
+
+    <pre>
+    Attributes {
+        GLOBAL {
+            String title "Reynolds Optimum Interpolation (OI) SST";
+        }
+        lat {
+            String units "degrees_north";
+            String long_name "Latitude";
+            Float64 actual_range 89.5, -89.5;
+        }
+        lon {
+            String units "degrees_east";
+            String long_name "Longitude";
+            Float64 actual_range 0.5, 359.5;
+        }
+        time {
+            String units "days since 1-1-1 00:00:00";
+            String long_name "Time";
+            Float64 actual_range 726468., 729289.;
+            String delta_t "0000-00-07 00:00:00";
+        }
+        sst {
+            String long_name "Weekly Means of Sea Surface Temperature";
+            Float64 actual_range -1.8, 35.09;
+            String units "degC";
+            Float64 add_offset 0.;
+            Float64 scale_factor 0.0099999998;
+            Int32 missing_value 32767;
+        }
+    }
+    </pre>
+
+    Attributes may have arbitrary names, although in most datasets it
+    is important to choose these names so a reader will know what they
+    describe.  In the above example, the ``GLOBAL'' attribute provides
+    information about the entire dataset.
+
+    Data attribute information is an important part of the the data
+    provided to a DAP2 client by a server, and the DAS is how this
+    data is packaged for sending (and how it is received).
+
+    The DAS class is simply a sequence of attribute tables and names.
+    It may be thought of as the top level of the attribute hierarchy.
+
+    @see DDS
+    @see AttrTable */
+class DAS : public DapObj
+{
+private:
+    AttrTable *d_container ;
+    string _container_name ;
+    AttrTable d_attrs ;
+
+protected:
+    //AttrTable *das_find(string name);
+
+public:
+    DAS();
+    //DAS(AttrTable *attr_table, string name);
+
+    virtual ~DAS();
+
+    virtual string container_name() ;
+    virtual void container_name( const string &cn ) ;
+    virtual AttrTable *container() ;
+
+    /** @brief Returns the top most set of attributes
+     *
+     * This could be the top most variable attribute tables, or it could be
+     * the top most dataset container attribute tables, if we have multiple
+     * datasets being used to construct this DAS
+     */
+    virtual AttrTable *get_top_level_attributes()
+    {
+	if( d_container ) return d_container ;
+	return &d_attrs ;
+    }
+
+    virtual void erase() ;
+
+    virtual unsigned int get_size() const ;
+
+    AttrTable::Attr_iter var_begin() ;
+    AttrTable::Attr_iter var_end() ;
+
+    string get_name(AttrTable::Attr_iter &i);
+    AttrTable *get_table(AttrTable::Attr_iter &i);
+
+    virtual AttrTable *get_table(const string &name);
+
+    virtual AttrTable *add_table(const string &name, AttrTable *at);
+
+    /** Read a DAS by parsing the specified file*/
+    virtual void parse(string fname);
+    virtual void parse(int fd);
+    virtual void parse(FILE *in = stdin);
+
+    /** Print the DAS */
+    virtual void print(FILE *out, bool dereference = false);
+    virtual void print(ostream &out, bool dereference = false);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _das_h
diff --git a/DDS.cc b/DDS.cc
new file mode 100644
index 0000000..b5fa57c
--- /dev/null
+++ b/DDS.cc
@@ -0,0 +1,1209 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+//
+// jhrg 9/7/94
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: DDS.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include <cstdio>
+#include <sys/types.h>
+
+#ifdef WIN32
+#include <io.h>
+#include <process.h>
+#include <fstream>
+#else
+#include <unistd.h>    // for alarm and dup
+#include <sys/wait.h>
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <functional>
+
+//#define DODS_DEBUG
+//#define DODS_DEBUG2
+
+#include "GNURegex.h"
+
+#include "DAS.h"
+#include "Clause.h"
+#include "Error.h"
+#include "InternalErr.h"
+#include "Keywords2.h"
+
+#include "parser.h"
+#include "debug.h"
+#include "util.h"
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "escaping.h"
+
+const string c_default_dap20_schema_location = "http://xml.opendap.org/dap/dap2.xsd";
+const string c_default_dap32_schema_location = "http://xml.opendap.org/dap/dap3.2.xsd";
+
+const string c_dap20_namespace = "http://xml.opendap.org/ns/DAP2";
+const string c_dap32_namespace = "http://xml.opendap.org/ns/DAP/3.2#";
+
+const string grddl_transformation_dap32 = "http://xml.opendap.org/transforms/ddxToRdfTriples.xsl";
+
+const string c_xml_namespace = "http://www.w3.org/XML/1998/namespace";
+
+using namespace std;
+
+void ddsrestart(FILE *yyin); // Defined in dds.tab.c
+int ddsparse(void *arg);
+
+// Glue for the DDS parser defined in dds.lex
+void dds_switch_to_buffer(void *new_buffer);
+void dds_delete_buffer(void * buffer);
+void *dds_buffer(FILE *fp);
+
+namespace libdap {
+
+void
+DDS::duplicate(const DDS &dds)
+{
+    DBG(cerr << "Entering DDS::duplicate... " <<endl);
+    name = dds.name;
+    d_filename = dds.d_filename;
+    d_container_name = dds.d_container_name;
+    d_timeout = dds.d_timeout;
+    d_attr = dds.d_attr;
+
+    d_factory = dds.d_factory;
+    d_container = dds.d_container;
+    d_dap_major = dds.d_dap_major;
+    d_dap_minor = dds.d_dap_minor;
+
+    d_keywords = dds.d_keywords; // value copy; Keywords contains no pointers
+
+    DDS &dds_tmp = const_cast<DDS &>(dds);
+
+    // copy the things pointed to by the list, not just the pointers
+    for (Vars_iter i = dds_tmp.var_begin(); i != dds_tmp.var_end(); i++) {
+        add_var(*i); // add_var() dups the BaseType.
+    }
+}
+
+/** Make a DDS which uses the given BaseTypeFactory to create variables.
+    @param n The name of the dataset. Can also be set using the
+    set_dataset_name() method.
+    @param factory BaseTypeFactory which instantiates Byte, ..., Grid. The
+    caller is responsible for freeing the object \e after deleting this DDS.
+    Can also be set using set_factory(). Never delete until just before
+    deleting the DDS itself unless you intend to replace the factory with a
+    new instance.
+    @param n The name of the data set. Can also be set using
+    set_dataset_name(). */
+DDS::DDS(BaseTypeFactory *factory, const string &n)
+
+        : d_factory(factory), name(n), d_container(0),
+          d_dap_major(2), d_dap_minor(0),
+        d_request_xml_base(""), d_timeout(0), d_keywords()
+{
+    DBG(cerr << "Building a DDS with client major/minor: "
+            << d_dap_major << "." << d_dap_minor << endl);
+}
+
+/** The DDS copy constructor. */
+DDS::DDS(const DDS &rhs) : DapObj()
+{
+    DBG(cerr << "Entering DDS(const DDS &rhs) ..." << endl);
+    duplicate(rhs);
+    DBG(cerr << " bye." << endl);
+}
+
+DDS::~DDS()
+{
+    // delete all the variables in this DDS
+    for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
+        BaseType *btp = *i ;
+        delete btp ; btp = 0;
+    }
+}
+
+DDS &
+DDS::operator=(const DDS &rhs)
+{
+    DBG(cerr << "Entering DDS::operator= ..." << endl);
+    if (this == &rhs)
+        return *this;
+
+    duplicate(rhs);
+
+    DBG(cerr << " bye." << endl);
+    return *this;
+}
+
+/**
+ * This is the main method used to transfer attributes from a DAS object into a
+ * DDS. This uses the BaseType::transfer_attributes() method and the various
+ * implementations found here (in the constructors classes) and in handlers.
+ *
+ * This method uses a deep copy to transfer the attributes, so it is safe to
+ * delete the source DAS object passed to this method once it is done.
+ *
+ * @note To accommodate oddly built DAS objects produced by various handlers,
+ * specialize the methods there.
+ *
+ * @param das Transfer (copy) attributes from this DAS object.
+ */
+void
+DDS::transfer_attributes(DAS *das)
+{
+    // If there is a container set in the DDS then get the container from
+    // the DAS. If they are not the same container, then throw an exception
+    // (should be working on the same container). If the container does not
+    // exist in the DAS, then throw an exception
+    if( d_container ) {
+	if( das->container_name() != d_container_name )
+	    throw InternalErr(__FILE__, __LINE__, "Error transferring attributes: working on a container in dds, but not das" ) ;
+    }
+
+    // Give each variable a chance to claim its attributes.
+    AttrTable *top_level = das->get_top_level_attributes() ;
+
+    Vars_iter var = var_begin();
+    while (var != var_end()) {
+	(*var)->transfer_attributes(top_level);
+	var++;
+    }
+
+    // Now we transfer all of the attributes still marked as global to the
+    // global container in the DDS.
+
+    AttrTable::Attr_iter at_cont_p = top_level->attr_begin();
+    while (at_cont_p != top_level->attr_end()) {
+	// In truth, all of the top level attributes should be containers, but
+	// this test handles the abnormal case where somehow someone makes a
+	// top level attribute that is not a container by silently dropping it.
+	if ((*at_cont_p)->type == Attr_container
+		&& (*at_cont_p)->attributes->is_global_attribute()) {
+	    DBG(cerr << (*at_cont_p)->name << " is a global attribute." << endl);
+	    // copy the source container so that the DAS passed in can be
+	    // deleted after calling htis method.
+	    AttrTable *at = new AttrTable(*(*at_cont_p)->attributes);
+	    d_attr.append_container(at, at->get_name());
+	}
+
+	at_cont_p++;
+    }
+}
+
+/** Get and set the dataset's name.  This is the name of the dataset
+    itself, and is not to be confused with the name of the file or
+    disk on which it is stored.
+
+    @name Dataset Name Accessors */
+
+//@{
+
+/** Returns the dataset's name. */
+string
+DDS::get_dataset_name() const
+{
+    return name;
+}
+
+/** Sets the dataset name. */
+void
+DDS::set_dataset_name(const string &n)
+{
+    name = n;
+}
+
+//@}
+
+/** Get the attribute table for the global attributes. */
+AttrTable &
+DDS::get_attr_table()
+{
+    return d_attr;
+}
+
+/** Get and set the dataset's filename. This is the physical
+    location on a disk where the dataset exists.  The dataset name
+    is simply a title.
+
+    @name File Name Accessor
+    @see Dataset Name Accessors */
+
+//@{
+/** Gets the dataset file name. */
+string
+DDS::filename()
+{
+    return d_filename;
+}
+
+/** Set the dataset's filename. */
+void
+DDS::filename(const string &fn)
+{
+    d_filename = fn;
+}
+//@}
+
+void
+DDS::set_dap_major(int p)
+{
+    d_dap_major = p;
+
+    // This works because regardless of the order set_dap_major and set_dap_minor
+    // are called, once they both are called, the value in the string is
+    // correct. I protect against negative numbers because that would be
+    // nonsensical.
+    if (d_dap_minor >= 0) {
+	ostringstream oss;
+	oss << d_dap_major << "." << d_dap_minor;
+	d_dap_version = oss.str();
+    }
+}
+
+void
+DDS::set_dap_minor(int p)
+{
+    d_dap_minor = p;
+
+    if (d_dap_major >= 0) {
+	ostringstream oss;
+	oss << d_dap_major << "." << d_dap_minor;
+	d_dap_version = oss.str();
+    }
+}
+
+/** Given the dap protocol version either from a MIME header or from within
+    the DDX Dataset element, parse that string and set the DDS fields.
+
+    @param version_string The version string from the MIME (request) or XML
+    document.
+ */
+void
+DDS::set_dap_version(const string &version_string)
+{
+    istringstream iss(version_string);
+
+    int major = -1, minor = -1;
+    char dot;
+    if (!iss.eof() && !iss.fail())
+	iss >> major;
+    if (!iss.eof() && !iss.fail())
+	iss >> dot;
+    if (!iss.eof() && !iss.fail())
+	iss >> minor;
+
+    DBG(cerr << "Major: " << major << ", dot: " << dot <<", Minor: " << minor << endl);
+#if 0
+    if (major == -1 || minor == -1)
+        throw Error("Could not parse the client dap (XDAP-Accept header) value");
+#endif
+
+    d_dap_version = version_string;
+
+    set_dap_major(major == -1 ? 2 : major);
+    set_dap_minor(minor == -1 ? 0 : minor);
+}
+
+/** Given the dap protocol version, parse that string and set the DDS fields.
+    This version of th method takes a double - a value that would be passed
+    to a server-side function. This provides a way to set the protocol using
+    stuff in the URL.
+
+    @param d The protocol version requested by the client, as a double.
+ */
+void
+DDS::set_dap_version(double d)
+{
+    int major = d;
+    int minor = (d-major)*10;
+
+    DBG(cerr << "Major: " << major << ", Minor: " << minor << endl);
+
+    ostringstream oss;
+    oss << major << "." << minor;
+    d_dap_version = oss.str();
+
+    set_dap_major(major);
+    set_dap_minor(minor);
+}
+
+/** Get and set the current container. If there are multiple files being
+    used to build this DDS, using a container will set a virtual structure
+    for the current container.
+
+    @name Container Name Accessor
+    @see Dataset Name Accessors */
+
+//@{
+/** Gets the dataset file name. */
+string
+DDS::container_name()
+{
+    return d_container_name;
+}
+
+/** Set the current container name and get or create a structure for that
+ * name. */
+void
+DDS::container_name(const string &cn)
+{
+    // we want to search the DDS for the top level structure with the given
+    // name. Set the container to null so that we don't search some previous
+    // container.
+    d_container = 0 ;
+    if( !cn.empty() )
+    {
+	d_container = dynamic_cast<Structure *>( var( cn ) ) ;
+	if( !d_container )
+	{
+	    // create a structure for this container. Calling add_var
+	    // while_container is null will add the new structure to DDS and
+	    // not some sub structure. Adding the new structure makes a copy
+	    // of it.  So after adding it, go get it and set d_container.
+	    Structure *s = new Structure( cn ) ;
+	    add_var( s ) ;
+	    delete s ;
+	    s = 0 ;
+	    d_container = dynamic_cast<Structure *>( var( cn ) ) ;
+	}
+    }
+    d_container_name = cn;
+
+}
+
+/** Get the current container structure. */
+Structure *
+DDS::container()
+{
+    return d_container ;
+}
+
+//@}
+
+/** @brief Adds a copy of the variable to the DDS.
+    Using the ptr_duplicate() method, perform a deep copy on the variable
+    \e bt and adds the result to this DDS.
+    @note The copy will not copy data values.
+    @param bt Source variable. */
+void
+DDS::add_var(BaseType *bt)
+{
+    if (!bt)
+        throw InternalErr(__FILE__, __LINE__,
+                          "Trying to add a BaseType object with a NULL pointer.");
+
+    DBG2(cerr << "In DDS::add_var(), bt's address is: " << bt << endl);
+
+    BaseType *btp = bt->ptr_duplicate();
+    DBG2(cerr << "In DDS::add_var(), btp's address is: " << btp << endl);
+    if( d_container )
+    {
+        // Mem leak fix [mjohnson nov 2009]
+        // Structure::add_var() creates ANOTHER copy.
+	d_container->add_var( bt ) ;
+	// So we need to delete btp or else it leaks
+	delete btp; btp = 0;
+    }
+    else
+    {
+	vars.push_back(btp);
+    }
+}
+
+/** Remove the named variable from the DDS. This method is not smart about
+    looking up names. The variable must exist at the top level of the DDS and
+    must match \e exactly the name given.
+
+    @note Invalidates any iterators that reference the contents of the DDS.
+    @param n The name of the variable to remove. */
+void
+DDS::del_var(const string &n)
+{
+    if( d_container )
+    {
+	d_container->del_var( n ) ;
+	return ;
+    }
+
+    for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
+        if ((*i)->name() == n) {
+            BaseType *bt = *i ;
+            vars.erase(i) ;
+            delete bt ; bt = 0;
+            return;
+        }
+    }
+}
+
+/** Remove the variable referenced by the iterator and free its storage.
+
+    @note Invalidates any iterators that reference the contents of the DDS.
+    @param i The Vars_iter which refers to the variable. */
+void
+DDS::del_var(Vars_iter i)
+{
+    if (i != vars.end()) {
+        BaseType *bt = *i ;
+        vars.erase(i) ;
+        delete bt ; bt = 0;
+    }
+}
+
+/** Remove the variables referenced by the range of iterators and free their
+    storage.
+
+    @note Invalidates any iterators that reference the contents of the DDS.
+    @param i1 The start of the range.
+    @param i2 The end of the range. */
+void
+DDS::del_var(Vars_iter i1, Vars_iter i2)
+{
+    for (Vars_iter i_tmp = i1; i_tmp != i2; i_tmp++) {
+        BaseType *bt = *i_tmp ;
+        delete bt ; bt = 0;
+    }
+    vars.erase(i1, i2) ;
+}
+
+/** Search for for variable <i>n</i> as above but record all
+    compound type variables which ultimately contain <i>n</i> on
+    <i>s</i>. This stack can then be used to mark the contained
+    compound-type variables as part of the current projection.
+
+    @return A BaseType pointer to the variable <i>n</i> or 0 if <i>n</i>
+    could not be found. */
+BaseType *
+DDS::var(const string &n, BaseType::btp_stack &s)
+{
+    return var(n, &s);
+}
+/** @brief Find the variable with the given name.
+
+    Returns a pointer to the named variable. If the name contains one or
+    more field separators then the function looks for a variable whose
+    name matches exactly. If the name contains no field separators then
+    the function looks first in the top level and then in all subsequent
+    levels and returns the first occurrence found. In general, this
+    function searches constructor types in the order in which they appear
+    in the DDS, but there is no requirement that it do so.
+
+    @note If a dataset contains two constructor types which have field names
+    that are the same (say point.x and pair.x) you should use fully qualified
+    names to get each of those variables.
+
+    @param n The name of the variable to find.
+    @param s If given, this value-result parameter holds the path to the
+    returned BaseType. Thus, this method can return the FQN for the variable
+    \e n.
+    @return A BaseType pointer to the variable or null if not found. */
+BaseType *
+DDS::var(const string &n, BaseType::btp_stack *s)
+{
+    string name = www2id(n);
+    if( d_container )
+        return d_container->var( name, false, s ) ;
+
+    BaseType *v = exact_match(name, s);
+    if (v)
+        return v;
+
+    return leaf_match(name, s);
+}
+
+BaseType *
+DDS::leaf_match(const string &n, BaseType::btp_stack *s)
+{
+    DBG(cerr << "DDS::leaf_match: Looking for " << n << endl);
+
+    for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
+        BaseType *btp = *i;
+        DBG(cerr << "DDS::leaf_match: Looking for " << n << " in: " << btp->name() << endl);
+        // Look for the name in the dataset's top-level
+        if (btp->name() == n) {
+            DBG(cerr << "Found " << n << " in: " << btp->name() << endl);
+            return btp;
+        }
+
+        if (btp->is_constructor_type()) {
+            BaseType *found = btp->var(n, false, s);
+            if (found) {
+                DBG(cerr << "Found " << n << " in: " << btp->name() << endl);
+                return found;
+            }
+        }
+#if STRUCTURE_ARRAY_SYNTAX_OLD
+        if (btp->is_vector_type() && btp->var()->is_constructor_type()) {
+            s->push(btp);
+            BaseType *found = btp->var()->var(n, false, s);
+            if (found) {
+                DBG(cerr << "Found " << n << " in: " << btp->var()->name() << endl);
+                return found;
+            }
+        }
+#endif
+    }
+
+    return 0;   // It is not here.
+}
+
+BaseType *
+DDS::exact_match(const string &name, BaseType::btp_stack *s)
+{
+    for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
+        BaseType *btp = *i;
+        DBG2(cerr << "Looking for " << name << " in: " << btp << endl);
+        // Look for the name in the current ctor type or the top level
+        if (btp->name() == name) {
+            DBG2(cerr << "Found " << name << " in: " << btp << endl);
+            return btp;
+        }
+    }
+
+    string::size_type dot_pos = name.find(".");
+    if (dot_pos != string::npos) {
+        string aggregate = name.substr(0, dot_pos);
+        string field = name.substr(dot_pos + 1);
+
+        BaseType *agg_ptr = var(aggregate, s);
+        if (agg_ptr) {
+            DBG2(cerr << "Descending into " << agg_ptr->name() << endl);
+            return agg_ptr->var(field, true, s);
+        }
+        else
+            return 0;  // qualified names must be *fully* qualified
+    }
+
+    return 0;   // It is not here.
+}
+
+
+/** @brief Returns the first variable in the DDS. */
+
+DDS::Vars_iter
+DDS::var_begin()
+{
+    return vars.begin();
+}
+
+DDS::Vars_riter
+DDS::var_rbegin()
+{
+    return vars.rbegin();
+}
+
+DDS::Vars_iter
+DDS::var_end()
+{
+    return vars.end() ;
+}
+
+DDS::Vars_riter
+DDS::var_rend()
+{
+    return vars.rend() ;
+}
+
+/** Return the iterator for the \e ith variable.
+    @param i the index
+    @return The corresponding  Vars_iter */
+DDS::Vars_iter
+DDS::get_vars_iter(int i)
+{
+    return vars.begin() + i;
+}
+
+/** Return the \e ith variable.
+    @param i the index
+    @return The corresponding variable */
+BaseType *
+DDS::get_var_index(int i)
+{
+    return *(vars.begin() + i);
+}
+
+/** @brief Returns the number of variables in the DDS. */
+int
+DDS::num_var()
+{
+    return vars.size();
+}
+
+void
+DDS::timeout_on()
+{
+#ifndef WIN32
+    alarm(d_timeout);
+#endif
+}
+
+void
+DDS::timeout_off()
+{
+#ifndef WIN32
+    d_timeout = alarm(0);
+#endif
+}
+
+void
+DDS::set_timeout(int t)
+{
+    //  Has no effect under win32
+    d_timeout = t;
+}
+
+int
+DDS::get_timeout()
+{
+    //  Has to effect under win32
+    return d_timeout;
+}
+
+/** @brief Traverse DDS, set Sequence leaf nodes. */
+void
+DDS::tag_nested_sequences()
+{
+    for (Vars_iter i = vars.begin(); i != vars.end(); i++) {
+        if ((*i)->type() == dods_sequence_c)
+            dynamic_cast<Sequence&>(**i).set_leaf_sequence();
+        else if ((*i)->type() == dods_structure_c)
+            dynamic_cast<Structure&>(**i).set_leaf_sequence();
+    }
+}
+
+/** @brief Parse a DDS from a file with the given name. */
+void
+DDS::parse(string fname)
+{
+    FILE *in = fopen(fname.c_str(), "r");
+
+    if (!in) {
+        throw Error(cannot_read_file, "Could not open: " + fname);
+    }
+
+    try {
+        parse(in);
+        fclose(in);
+    }
+    catch (Error &e) {
+        fclose(in);
+        throw ;
+    }
+}
+
+
+/** @brief Parse a DDS from a file indicated by the input file descriptor. */
+void
+DDS::parse(int fd)
+{
+#ifdef WIN32
+    FILE *in = fdopen(_dup(fd), "r");
+#else
+    FILE *in = fdopen(dup(fd), "r");
+#endif
+
+    if (!in) {
+        throw InternalErr(__FILE__, __LINE__, "Could not access file.");
+    }
+
+    try {
+        parse(in);
+        fclose(in);
+    }
+    catch (Error &e) {
+        fclose(in);
+        throw ;
+    }
+}
+
+/** @brief Parse a DDS from a file indicated by the input file descriptor.
+    Read the persistent representation of a DDS from the FILE *in, parse it
+    and create a matching binary object.
+    @param in Read the persistent DDS from this FILE*.
+    @exception InternalErr Thrown if \c in is null
+    @exception Error Thrown if the parse fails. */
+void
+DDS::parse(FILE *in)
+{
+    if (!in) {
+        throw InternalErr(__FILE__, __LINE__, "Null input stream.");
+    }
+
+    void *buffer = dds_buffer(in);
+    dds_switch_to_buffer(buffer);
+
+    parser_arg arg(this);
+
+    bool status = ddsparse((void *) & arg) == 0;
+
+    dds_delete_buffer(buffer);
+
+    DBG2(cout << "Status from parser: " << status << endl);
+
+    //  STATUS is the result of the parser function; if a recoverable error
+    //  was found it will be true but arg.status() will be false.
+    if (!status || !arg.status()) {// Check parse result
+        if (arg.error())
+            throw *arg.error();
+    }
+}
+
+#if FILE_METHODS
+/** @brief Print the entire DDS to the specified file. */
+void
+DDS::print(FILE *out)
+{
+#if 0
+    ostringstream oss;
+    print(oss);
+
+    fwrite(oss.str().c_str(), oss.str().length(), 1, out);
+#else
+    fprintf(out, "Dataset {\n") ;
+
+    for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
+        (*i)->print_decl(out) ;
+    }
+
+    fprintf(out, "} %s;\n", id2www(name).c_str()) ;
+
+    return ;
+#endif
+}
+#endif
+
+/** @brief Print the entire DDS to the specified ostream. */
+void
+DDS::print(ostream &out)
+{
+    out << "Dataset {\n" ;
+
+    for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
+        (*i)->print_decl(out) ;
+    }
+
+    out << "} " << id2www(name) << ";\n" ;
+
+    return ;
+}
+
+#if FILE_METHODS
+/** @brief Print a constrained DDS to the specified file.
+
+    Print those parts (variables) of the DDS structure to OS that
+    are marked to be sent after evaluating the constraint
+    expression.
+
+    \note This function only works for scalars at the top level.
+
+    @returns true.
+*/
+void
+DDS::print_constrained(FILE *out)
+{
+    fprintf(out, "Dataset {\n") ;
+
+    for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
+        // for each variable, indent with four spaces, print a trailing
+        // semicolon, do not print debugging information, print only
+        // variables in the current projection.
+        (*i)->print_decl(out, "    ", true, false, true) ;
+    }
+
+    fprintf(out, "} %s;\n", id2www(name).c_str()) ;
+
+    return;
+}
+#endif
+
+/** @brief Print a constrained DDS to the specified ostream.
+
+    Print those parts (variables) of the DDS structure to OS that
+    are marked to be sent after evaluating the constraint
+    expression.
+
+    \note This function only works for scalars at the top level.
+
+    @returns true.
+*/
+void
+DDS::print_constrained(ostream &out)
+{
+    out << "Dataset {\n" ;
+
+    for (Vars_citer i = vars.begin(); i != vars.end(); i++) {
+        // for each variable, indent with four spaces, print a trailing
+        // semicolon, do not print debugging information, print only
+        // variables in the current projection.
+        (*i)->print_decl(out, "    ", true, false, true) ;
+    }
+
+    out << "} " << id2www(name) << ";\n" ;
+
+    return;
+}
+
+#if FILE_METHODS
+class VariablePrintXML : public unary_function<BaseType *, void>
+{
+    FILE *d_out;
+    bool d_constrained;
+public:
+    VariablePrintXML(FILE *out, bool constrained)
+            : d_out(out), d_constrained(constrained)
+    {}
+    void operator()(BaseType *bt)
+    {
+        bt->print_xml(d_out, "    ", d_constrained);
+    }
+};
+
+/** Print an XML representation of this DDS. This method is used to generate
+    the part of the DDX response. The \c Dataset tag is \e not written by
+    this code. The caller of this method must handle writing that and
+    including the \c dataBLOB tag.
+
+    @param out Destination.
+    @param constrained True if the output should be limited to just those
+    variables that are in the projection of the current constraint
+    expression.
+    @param blob The dataBLOB href. */
+void
+DDS::print_xml(FILE *out, bool constrained, const string &blob)
+{
+    fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
+
+    fprintf(out, "<Dataset name=\"%s\"\n", id2xml(name).c_str());
+
+    fprintf(out, "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
+
+    fprintf(out,"method=\"FILE*\"\n");
+    fprintf(out, "dap_major=\"%d\"\n", get_dap_major());
+    fprintf(out, "dap_minor=\"%d\"\n", get_dap_minor());
+
+    // Are we responding to a 3.2 or 2.0 client? We will have to improve on
+    // this at some point... jhrg
+    if (get_dap_major() == 3 && get_dap_minor() == 2) {
+    fprintf(out, "xmlns=\"%s\"\n", c_dap32_namespace.c_str());
+
+    fprintf(out, "xsi:schemaLocation=\"%s  %s\">\n\n",
+            c_dap32_namespace.c_str(), c_default_dap32_schema_location.c_str());
+    }
+    else {
+        fprintf(out, "xmlns=\"%s\"\n", c_dap20_namespace.c_str());
+        fprintf(out, "xsi:schemaLocation=\"%s  %s\">\n\n",
+                c_dap20_namespace.c_str(), c_default_dap20_schema_location.c_str());
+    }
+
+
+    d_attr.print_xml(out, "    ", constrained);
+
+    fprintf(out, "\n");
+
+    for_each(var_begin(), var_end(), VariablePrintXML(out, constrained));
+
+    fprintf(out, "\n");
+
+    // Only print this for the 2.0, 3.0 and 3.1 versions - which are essentially
+    // the same. jhrg
+    if (get_dap_major() == 2 && get_dap_minor() == 0) {
+        fprintf(out, "    <dataBLOB href=\"\"/>\n");
+    }
+    else if (!blob.empty()
+	     && (get_dap_major() == 3 && get_dap_minor() >= 2)
+	     || get_dap_major() >= 4) {
+	fprintf(out, "    <blob href=\"cid:%s\"/>\n", blob.c_str());
+    }
+
+
+    fprintf(out, "</Dataset>\n");
+}
+#endif
+
+class VariablePrintXMLStrm : public unary_function<BaseType *, void>
+{
+    ostream &d_out;
+    bool d_constrained;
+public:
+    VariablePrintXMLStrm(ostream &out, bool constrained)
+            : d_out(out), d_constrained(constrained)
+    {}
+    void operator()(BaseType *bt)
+    {
+        bt->print_xml(d_out, "    ", d_constrained);
+    }
+};
+
+/** Print an XML representation of this DDS. This method is used to generate
+    the part of the DDX response. The \c Dataset tag is \e not written by
+    this code. The caller of this method must handle writing that and
+    including the \c dataBLOB tag.
+
+    @param out Destination ostream.
+    @param constrained True if the output should be limited to just those
+    variables that are in the projection of the current constraint
+    expression.
+    @param blob The dataBLOB href. */
+void
+DDS::print_xml(ostream &out, bool constrained, const string &blob)
+{
+    out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ;
+
+    out << "<Dataset name=\"" << id2xml(name) << "\"\n" ;
+
+    out << "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" ;
+
+    // Are we responding to a 3.2 or 2.0 client? We will have to improve on
+    // this at some point... jhrg
+    if (get_dap_major() == 3 && get_dap_minor() == 2) {
+        out << "xsi:schemaLocation=\"" << c_dap32_namespace
+            << "  " << c_default_dap32_schema_location << "\"\n" ;
+
+        out << "xmlns:grddl=\"http://www.w3.org/2003/g/data-view#\"\n";
+        out << "grddl:transformation=\"" << grddl_transformation_dap32 <<"\"\n";
+
+        out << "xmlns=\"" << c_dap32_namespace << "\"\n" ;
+        out << "xmlns:dap=\"" << c_dap32_namespace << "\"\n" ;
+
+        out << "dapVersion=\"" << get_dap_major() << "."
+            << get_dap_minor() << "\"";
+
+        if (!get_request_xml_base().empty()) {
+            out << "\n";
+            out << "xmlns:xml=\"" << c_xml_namespace << "\"\n";
+            out << "xml:base=\"" << get_request_xml_base() << "\"";
+        }
+
+        // Close the Dataset element
+        out << ">\n";
+    }
+    else {
+        out << "xmlns=\"" << c_dap20_namespace << "\"\n" ;
+        out << "xsi:schemaLocation=\"" << c_dap20_namespace
+            << "  " << c_default_dap20_schema_location << "\">\n\n" ;
+    }
+
+    d_attr.print_xml(out, "    ", constrained);
+
+    out << "\n" ;
+
+    for_each(var_begin(), var_end(), VariablePrintXMLStrm(out, constrained));
+
+    out << "\n" ;
+
+    // Only print this for the 2.0, 3.0 and 3.1 versions - which are essentially
+    // the same.
+    // For DAP 3.2 and greater, use the new syntax and value. The 'blob' is
+    // actually the CID of the MIME part that holds the data.
+    if (get_dap_major() == 2 && get_dap_minor() == 0) {
+        out << "    <dataBLOB href=\"\"/>\n" ;
+    }
+    else if (!blob.empty()
+	     && (get_dap_major() == 3 && get_dap_minor() >= 2)
+	     || get_dap_major() >= 4) {
+	out << "    <blob href=\"cid:" << blob << "\"/>\n";
+    }
+
+    out << "</Dataset>\n" ;
+}
+
+// Used by DDS::send() when returning data from a function call.
+/** @brief Check the semantics of each of the variables represented in the
+    DDS.
+
+    Check the semantics of the DDS describing a complete dataset. If ALL is
+    true, check not only the semantics of THIS->TABLE, but also recursively
+    all ctor types in the THIS->TABLE. By default, ALL is false since parsing
+    a DDS input file runs semantic checks on all variables (but not the
+    dataset itself.
+
+    @return TRUE if the conventions for the DDS are not violated, FALSE
+    otherwise.
+    @param all If true, recursively check the individual members of
+    compound variables.
+    @see BaseType::check_semantics */
+bool
+DDS::check_semantics(bool all)
+{
+    // The dataset must have a name
+    if (name == "") {
+        cerr << "A dataset must have a name" << endl;
+        return false;
+    }
+
+    string msg;
+    if (!unique_names(vars, name, "Dataset", msg))
+        return false;
+
+    if (all)
+        for (Vars_iter i = vars.begin(); i != vars.end(); i++)
+            if (!(*i)->check_semantics(msg, true))
+                return false;
+
+    return true;
+}
+
+/** @brief Mark the <tt>send_p</tt> flag of the named variable to
+    <i>state</i>.
+
+    Mark the named variable by setting its SEND_P flag to STATE (true
+    indicates that it is to be sent). Names must be fully qualified.
+
+    @note For aggregate types this sets each part to STATE when STATE is
+    True. Thus, if State is True and N is `exp1.test', then both `exp1' and
+    `test' have their SEND_P flag set to True. If STATE is False, then the
+    SEND_P flag of the `test' is set to False, but `exp1' is left
+    unchanged. This means that a single variable can be removed from the
+    current projection without removing all the other children of its
+    parent. See the mfunc set_send_p().
+
+    @return True if the named variable was found, false otherwise.
+
+    @todo This should throw an exception on error!!!
+
+    @todo These methods that use the btp_stack to keep track of the path from
+    the top of a dataset to a particular variable can be rewritten to use the
+    parent field instead.
+
+    @todo All the methods that use names to identify variables should have
+    counterparts that take BaseType pointers.
+*/
+bool
+DDS::mark(const string &n, bool state)
+{
+    BaseType::btp_stack *s = new BaseType::btp_stack;
+
+    DBG2(cerr << "DDS::mark: Looking for " << n << endl);
+
+    BaseType *variable = var(n, s);
+    if (!variable) {
+        DBG2(cerr << "Could not find variable " << n << endl);
+        delete s; s = 0;
+        return false;
+    }
+    variable->set_send_p(state);
+
+    DBG2(cerr << "DDS::mark: Set variable " << variable->name()
+            << " (a " << variable->type_name() << ")" << endl);
+
+    // Now check the btp_stack and run BaseType::set_send_p for every
+    // BaseType pointer on the stack. Using BaseType::set_send_p() will
+    // set the property for a Constructor but not its contained variables
+    // which preserves the semantics of projecting just one field.
+    while (!s->empty()) {
+        s->top()->BaseType::set_send_p(state);
+
+        DBG2(cerr << "DDS::mark: Set variable " << s->top()->name()
+                << " (a " << s->top()->type_name() << ")" << endl);
+        string parent_name = (s->top()->get_parent()) ? s->top()->get_parent()->name(): "none";
+        string parent_type = (s->top()->get_parent()) ? s->top()->get_parent()->type_name(): "none";
+        DBG2(cerr << "DDS::mark: Parent variable " << parent_name << " (a " << parent_type << ")" << endl);
+
+        s->pop();
+    }
+
+    delete s ; s = 0;
+
+    return true;
+}
+
+/** Mark the member variable <tt>send_p</tt> flags to
+    <i>state</i>.
+
+    @return Void
+*/
+void
+DDS::mark_all(bool state)
+{
+    for (Vars_iter i = vars.begin(); i != vars.end(); i++)
+        (*i)->set_send_p(state);
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and then calls parent dump
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+DDS::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "DDS::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    strm << DapIndent::LMarg << "name: " << name << endl ;
+    strm << DapIndent::LMarg << "filename: " << d_filename << endl ;
+    strm << DapIndent::LMarg << "protocol major: " << d_dap_major << endl;
+    strm << DapIndent::LMarg << "protocol minor: " << d_dap_minor << endl;
+    strm << DapIndent::LMarg << "factory: " << (void *)d_factory << endl ;
+
+    strm << DapIndent::LMarg << "global attributes:" << endl ;
+    DapIndent::Indent() ;
+    d_attr.dump(strm) ;
+    DapIndent::UnIndent() ;
+
+    if (vars.size()) {
+        strm << DapIndent::LMarg << "vars:" << endl ;
+        DapIndent::Indent() ;
+        Vars_citer i = vars.begin() ;
+        Vars_citer ie = vars.end() ;
+        for (; i != ie; i++) {
+            (*i)->dump(strm) ;
+        }
+        DapIndent::UnIndent() ;
+    }
+    else {
+        strm << DapIndent::LMarg << "vars: none" << endl ;
+    }
+
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
diff --git a/DDS.h b/DDS.h
new file mode 100644
index 0000000..e81ca0b
--- /dev/null
+++ b/DDS.h
@@ -0,0 +1,337 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Provide access to the DDS. This class is used to parse DDS text files, to
+// produce a printed representation of the in-memory variable table, and to
+// update the table on a per-variable basis.
+//
+// jhrg 9/8/94
+
+#ifndef _dds_h
+#define _dds_h 1
+
+#include <cstdio>
+#include <iostream>
+#include <string>
+#include <vector>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _constructor_h
+#include "Constructor.h"
+#endif
+
+#ifndef base_type_factory_h
+#include "BaseTypeFactory.h"
+#endif
+
+#ifndef _das_h
+#include "DAS.h"
+#endif
+
+#ifndef A_DapObj_h
+#include "DapObj.h"
+#endif
+
+#ifndef KEYWORDS_H_
+#include "Keywords2.h"
+#endif
+
+using std::cout;
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** The DAP2 Data Descriptor Object (DDS) is a data structure used by
+    the DAP2 software to describe datasets and subsets of those
+    datasets.  The DDS may be thought of as the declarations for the
+    data structures that will hold data requested by some DAP2 client.
+    Part of the job of a DAP2 server is to build a suitable DDS for a
+    specific dataset and to send it to the client.  Depending on the
+    data access API in use, this may involve reading part of the
+    dataset and inferring the DDS.  Other APIs may require the server
+    simply to read some ancillary data file with the DDS in it.
+
+    On the server side, in addition to the data declarations, the DDS
+    holds the clauses of any constraint expression that may have
+    accompanied the data request from the DAP2 client.  The DDS object
+    includes methods for modifying the DDS according to the given
+    constraint expression.  It also has methods for directly modifying
+    a DDS, and for transmitting it from a server to a client.
+
+    For the client, the DDS object includes methods for reading the
+    persistent form of the object sent from a server. This includes parsing
+    the ASCII representation of the object and, possibly, reading data
+    received from a server into a data object.
+
+    Note that the class DDS is used to instantiate both DDS and DataDDS
+    objects. A DDS that is empty (contains no actual data) is used by servers
+    to send structural information to the client. The same DDS can becomes a
+    DataDDS when data values are bound to the variables it defines.
+
+    For a complete description of the DDS layout and protocol, please
+    refer to <i>The OPeNDAP User Guide</i>.
+
+    The DDS has an ASCII representation, which is what is transmitted
+    from a DAP2 server to a client.  Here is the DDS representation of
+    an entire dataset containing a time series of worldwide grids of
+    sea surface temperatures:
+
+    <pre>
+    Dataset {
+        Float64 lat[lat = 180];
+        Float64 lon[lon = 360];
+        Float64 time[time = 404];
+        Grid {
+         ARRAY:
+            Int32 sst[time = 404][lat = 180][lon = 360];
+         MAPS:
+            Float64 time[time = 404];
+            Float64 lat[lat = 180];
+            Float64 lon[lon = 360];
+        } sst;
+    } weekly;
+    </pre>
+
+    If the data request to this dataset includes a constraint
+    expression, the corresponding DDS might be different.  For
+    example, if the request was only for northern hemisphere data
+    at a specific time, the above DDS might be modified to appear like
+    this:
+
+    <pre>
+    Dataset {
+        Grid {
+         ARRAY:
+            Int32 sst[time = 1][lat = 90][lon = 360];
+         MAPS:
+            Float64 time[time = 1];
+            Float64 lat[lat = 90];
+            Float64 lon[lon = 360];
+        } sst;
+    } weekly;
+    </pre>
+
+    Since the constraint has narrowed the area of interest, the range
+    of latitude values has been halved, and there is only one time
+    value in the returned array.  Note that the simple arrays (<tt>lat</tt>,
+    <tt>lon</tt>, and <tt>time</tt>) described in the dataset are also
+    part of the <tt>sst</tt> Grid object.  They can be requested by
+    themselves or as part of that larger object.
+
+    See the <i>The OPeNDAP User Guide</i>, or the documentation of the
+    BaseType class for descriptions of the DAP2 data types.
+
+    @note Make sure to pass a valid pointer to the DDS constructor or use
+    the set_factory() method before actually using the DDS. Also make sure
+    that the Factory's lifetime thereafter is the same as the DDS's. Never
+    delete the factory until you're done using the DDS.
+
+    @note Update: I removed the DEFAULT_BASETYPE_FACTORY switch because it
+    caused more confusion than it avoided. See Trac #130. jhrg
+
+    @note The compile-time symbol DEFAULT_BASETYPE_FACTORY controls whether
+    the old (3.4 and earlier) DDS and DataDDS constructors are supported.
+    These constructors now use a default factory class (BaseTypeFactory,
+    implemented by this library) to instantiate Byte, ..., Grid variables. To
+    use the default ctor in your code you must also define this symbol. If
+    you \e do choose to define this and fail to provide a specialization of
+    BaseTypeFactory when your software needs one, you code may not link or
+    may fail at run time. In addition to the older ctors for DDS and DataDDS,
+    defining the symbol also makes some of the older methods in Connect
+    available (because those methods require the older DDS and DataDDS ctors.
+
+    @see BaseType
+    @see DAS */
+
+class DDS : public DapObj
+{
+private:
+    BaseTypeFactory *d_factory;
+
+    string name;                // The dataset name
+    string d_filename;		// File name (or other OS identifier) for
+    string d_container_name;	// name of container structure
+    Structure *d_container;	// current container for container name
+				// dataset or part of dataset.
+
+    int d_dap_major;       	// The protocol major version number
+    int d_dap_minor;       	// ... and minor version number
+    string d_dap_version; 	// String version of the protocol
+    string d_request_xml_base;
+
+    AttrTable d_attr;           // Global attributes.
+
+    vector<BaseType *> vars;    // Variables at the top level
+
+    BaseType *find_hdf4_dimension_attribute_home(AttrTable::entry *source);
+
+    int d_timeout;              // alarm time in seconds. If greater than
+                                // zero, raise the alarm signal if more than
+                                // d_timeout seconds are spent reading data.
+    Keywords d_keywords;	// Holds keywords parsed from the CE
+
+    friend class DDSTest;
+
+protected:
+    void duplicate(const DDS &dds);
+    BaseType *leaf_match(const string &name, BaseType::btp_stack *s = 0);
+    BaseType *exact_match(const string &name, BaseType::btp_stack *s = 0);
+
+public:
+    typedef std::vector<BaseType *>::const_iterator Vars_citer ;
+    typedef std::vector<BaseType *>::iterator Vars_iter ;
+    typedef std::vector<BaseType *>::reverse_iterator Vars_riter ;
+
+    DDS(BaseTypeFactory *factory, const string &n = "");
+    DDS(const DDS &dds);
+
+    virtual ~DDS();
+
+    DDS & operator=(const DDS &rhs);
+
+    virtual void transfer_attributes(DAS *das);
+
+    string get_dataset_name() const;
+    void set_dataset_name(const string &n);
+
+    /** Return the factory which makes instances of the Byte, ..., Grid
+        type classes. Specialize BaseTypeFactory so that a DDS will be
+        populated with your client or server's specialized types.
+        @return An instance of BaseTypeFactory. */
+    BaseTypeFactory *get_factory() const
+    {
+        return d_factory;
+    }
+
+    /** Set the factory class used to instantiate variables during the
+        parse of a DDS.
+        @param factory The factory this DDS should use. Caller must free
+        factory when done with this DDS.
+        @return The old factory.
+        @see BaseTypeFactory */
+    BaseTypeFactory *set_factory(BaseTypeFactory *factory)
+    {
+        BaseTypeFactory *t = d_factory;
+        d_factory = factory;
+        return t;
+    }
+
+    virtual AttrTable &get_attr_table();
+
+    string filename();
+    void filename(const string &fn);
+
+    /// Get the DAP major version as sent by the client
+    int get_dap_major() const { return d_dap_major; }
+    /// Get the DAP minor version as sent by the client
+    int get_dap_minor() const { return d_dap_minor; }
+
+    /// Set the DAP major version (typically using info from the client)
+    void set_dap_major(int p);
+    /// Set the DAP minor version (typically using info from the client)
+    void set_dap_minor(int p);
+
+    void set_dap_version(const string &version_string);
+    void set_dap_version(double d);
+
+    string get_dap_version() const { return d_dap_version; }
+
+    Keywords &get_keywords() { return d_keywords; }
+
+    /// Get the URL that will return this DDS/DDX/DataThing
+    string get_request_xml_base() const { return d_request_xml_base; }
+
+    /// @see get_request_xml_base
+    void set_request_xml_base(const string &xb) { d_request_xml_base = xb; }
+
+    string container_name() ;
+    void container_name( const string &cn ) ;
+    Structure *container() ;
+
+    void add_var(BaseType *bt);
+
+    /// Removes a variable from the DDS.
+    void del_var(const string &n);
+
+    BaseType *var(const string &n, BaseType::btp_stack &s);
+    BaseType *var(const string &n, BaseType::btp_stack *s = 0);
+    int num_var();
+
+    /// Return an iterator to the first variable
+    Vars_iter var_begin();
+    /// Return a reverse iterator
+    Vars_riter var_rbegin();
+    /// Return an iterator
+    Vars_iter var_end();
+    /// Return a reverse iterator
+    Vars_riter var_rend();
+    /// Get an iterator
+    Vars_iter get_vars_iter(int i);
+    /// Get a variable
+    BaseType *get_var_index(int i);
+    /// Removes a variable from the DDS.
+    void del_var(Vars_iter i);
+    /// Removes a range of variables from the DDS.
+    void del_var(Vars_iter i1, Vars_iter i2);
+
+    void timeout_on();
+    void timeout_off();
+    void set_timeout(int t);
+    int get_timeout();
+
+    void parse(string fname);
+    void parse(int fd);
+    void parse(FILE *in = stdin);
+#if FILE_METHODS
+    void print(FILE *out);
+    void print_constrained(FILE *out);
+    void print_xml(FILE *out, bool constrained, const string &blob = "");
+#endif
+    void print(ostream &out);
+    void print_constrained(ostream &out);
+    void print_xml(ostream &out, bool constrained, const string &blob = "");
+
+    void mark_all(bool state);
+    bool mark(const string &name, bool state);
+    bool check_semantics(bool all = false);
+
+    void tag_nested_sequences();
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _dds_h
diff --git a/DDXExceptions.h b/DDXExceptions.h
new file mode 100644
index 0000000..89dbf77
--- /dev/null
+++ b/DDXExceptions.h
@@ -0,0 +1,49 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef ddx_exceptions_h
+#define ddx_exceptions_h
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+namespace libdap
+{
+
+/** Thrown when the DDX response cannot be parsed.. */
+class DDXParseFailed : public Error
+{
+public:
+    DDXParseFailed() : Error("The DDX response document parse failed.")
+    {}
+    DDXParseFailed(const string &msg) :
+            Error(string("The DDX response document parse failed: ") + msg)
+    {}
+};
+
+} // namespace libdap
+
+#endif // ddx_exceptions_h
diff --git a/DDXParserSAX2.cc b/DDXParserSAX2.cc
new file mode 100644
index 0000000..f300ada
--- /dev/null
+++ b/DDXParserSAX2.cc
@@ -0,0 +1,1223 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+//#define DODS_DEBUG 1
+//#define DODS_DEBUG2 1
+
+#include <cstring>
+#include <cstdarg>
+
+#include "BaseType.h"
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDXParserSAX2.h"
+
+#include "util.h"
+#include "mime_util.h"
+#include "debug.h"
+
+namespace libdap {
+
+static const not_used char *states[] =
+    {
+        "start",
+
+        "dataset",
+
+        "attribute_container",
+        "attribute",
+        "attribute_value",
+        "other_xml_attribute",
+
+        "alias",
+
+        "simple_type",
+
+        "array",
+        "dimension",
+
+        "grid",
+        "map",
+
+        "structure",
+        "sequence",
+
+        "blob href",
+
+        "unknown",
+        "error"
+    };
+
+// Glue the BaseTypeFactory to the enum-based factory defined statically
+// here.
+
+BaseType *DDXParser::factory(Type t, const string & name)
+{
+    switch (t) {
+    case dods_byte_c:
+        return d_factory->NewByte(name);
+        break;
+
+    case dods_int16_c:
+        return d_factory->NewInt16(name);
+        break;
+
+    case dods_uint16_c:
+        return d_factory->NewUInt16(name);
+        break;
+
+    case dods_int32_c:
+        return d_factory->NewInt32(name);
+        break;
+
+    case dods_uint32_c:
+        return d_factory->NewUInt32(name);
+        break;
+
+    case dods_float32_c:
+        return d_factory->NewFloat32(name);
+        break;
+
+    case dods_float64_c:
+        return d_factory->NewFloat64(name);
+        break;
+
+    case dods_str_c:
+        return d_factory->NewStr(name);
+        break;
+
+    case dods_url_c:
+        return d_factory->NewUrl(name);
+        break;
+
+    case dods_array_c:
+        return d_factory->NewArray(name);
+        break;
+
+    case dods_structure_c:
+        return d_factory->NewStructure(name);
+        break;
+
+    case dods_sequence_c:
+        return d_factory->NewSequence(name);
+        break;
+
+    case dods_grid_c:
+        return d_factory->NewGrid(name);
+        break;
+
+    default:
+        return 0;
+    }
+}
+
+/** Get the Type enumeration value which matches the given name. */
+static Type get_type(const char *name)
+{
+    if (strcmp(name, "Byte") == 0)
+        return dods_byte_c;
+
+    if (strcmp(name, "Int16") == 0)
+        return dods_int16_c;
+
+    if (strcmp(name, "UInt16") == 0)
+        return dods_uint16_c;
+
+    if (strcmp(name, "Int32") == 0)
+        return dods_int32_c;
+
+    if (strcmp(name, "UInt32") == 0)
+        return dods_uint32_c;
+
+    if (strcmp(name, "Float32") == 0)
+        return dods_float32_c;
+
+    if (strcmp(name, "Float64") == 0)
+        return dods_float64_c;
+
+    if (strcmp(name, "String") == 0)
+        return dods_str_c;
+
+    if (strcmp(name, "Url") == 0)
+        return dods_url_c;
+
+    if (strcmp(name, "Array") == 0)
+        return dods_array_c;
+
+    if (strcmp(name, "Structure") == 0)
+        return dods_structure_c;
+
+    if (strcmp(name, "Sequence") == 0)
+        return dods_sequence_c;
+
+    if (strcmp(name, "Grid") == 0)
+        return dods_grid_c;
+
+    return dods_null_c;
+}
+
+static Type is_simple_type(const char *name)
+{
+    Type t = get_type(name);
+    switch (t) {
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+    case dods_str_c:
+    case dods_url_c:
+        return t;
+    default:
+        return dods_null_c;
+    }
+}
+
+static bool is_not(const char *name, const char *tag)
+{
+    return strcmp(name, tag) != 0;
+}
+
+void DDXParser::set_state(DDXParser::ParseState state)
+{
+    s.push(state);
+}
+
+DDXParser::ParseState DDXParser::get_state() const
+{
+    return s.top();
+}
+
+void DDXParser::pop_state()
+{
+    s.pop();
+}
+
+/** Dump XML attributes to local store so they can be easily manipulated.
+    Attribute names are always folded to lower case.
+    @param attrs The XML attribute array */
+void DDXParser::transfer_xml_attrs(const xmlChar **attributes, int nb_attributes)
+{
+    if (!attribute_table.empty())
+        attribute_table.clear(); // erase old attributes
+
+    unsigned int index = 0;
+    for (int i = 0; i < nb_attributes; ++i, index += 5) {
+        // Make a value using the attribute name and the prefix, namespace URI
+        // and the value. The prefix might be null.
+        attribute_table.insert(map<string, XMLAttribute>::value_type(
+                string((const char *)attributes[index]),
+                XMLAttribute(attributes + index + 1)));
+
+        DBG(cerr << "Attribute '" << (const char *)attributes[index] << "': "
+                << attribute_table[(const char *)attributes[index]].value << endl);
+    }
+}
+
+void DDXParser::transfer_xml_ns(const xmlChar **namespaces, int nb_namespaces)
+{
+    for (int i = 0; i < nb_namespaces; ++i ) {
+        // make a value with the prefix and namespace URI. The prefix might be
+        // null.
+        namespace_table.insert(map<string,string>::value_type(
+                namespaces[i*2] != 0 ? (const char *)namespaces[i*2] : "",
+                (const char *)namespaces[i*2+1]));
+    }
+}
+
+/** Is an attribute present? Attribute names are always lower case.
+    @note To use this method, first call transfer_xml_attrs.
+    @param attr The XML attribute
+    @return True if the XML attribute was present in the last tag */
+bool DDXParser::check_required_attribute(const string & attr)
+{
+    map < string, XMLAttribute >::iterator i = attribute_table.find(attr);
+    if (i == attribute_table.end())
+        ddx_fatal_error(this, "Required attribute '%s' not found.",
+                        attr.c_str());
+    return true;
+}
+
+/** Is an attribute present? Attribute names are always lower case.
+    @note To use this method, first call transfer_xml_attrs.
+    @param attr The XML attribute
+    @return True if the XML attribute was present in the last/current tag,
+    false otherwise. */
+bool DDXParser::check_attribute(const string & attr)
+{
+    return (attribute_table.find(attr) != attribute_table.end());
+}
+
+/** Given that an \c Attribute tag has just been read, determine whether the
+    element is a container or a simple type, set the state and, for a simple
+    type record the type and name for use when \c value elements are found.
+
+    @note Modified to discriminate between OtherXML and the older DAP2.0
+    attribute types (container, Byte, ...).
+
+    @param attrs The array of XML attribute values */
+void DDXParser::process_attribute_element(const xmlChar **attrs, int nb_attributes)
+{
+    // These methods set the state to parser_error if a problem is found.
+    transfer_xml_attrs(attrs, nb_attributes);
+
+    bool error = !(check_required_attribute(string("name"))
+                   && check_required_attribute(string("type")));
+    if (error)
+        return;
+
+    if (attribute_table["type"].value == "Container") {
+        set_state(inside_attribute_container);
+
+        AttrTable *child;
+        AttrTable *parent = at_stack.top();
+
+        child = parent->append_container(attribute_table["name"].value);
+        at_stack.push(child);   // save.
+        DBG2(cerr << "Pushing at" << endl);
+    }
+    else if (attribute_table["type"].value == "OtherXML") {
+        set_state(inside_other_xml_attribute);
+
+        dods_attr_name = attribute_table["name"].value;
+        dods_attr_type = attribute_table["type"].value;
+    }
+    else {
+        set_state(inside_attribute);
+        // *** Modify parser. Add a special state for inside OtherXML since it
+        // does not use the <value> element.
+
+        dods_attr_name = attribute_table["name"].value;
+        dods_attr_type = attribute_table["type"].value;
+    }
+}
+
+/** Given that an \c Alias tag has just been read, set the state and process
+    the alias.
+    @param attrs The XML attribute array */
+void DDXParser::process_attribute_alias(const xmlChar **attrs, int nb_attributes)
+{
+    transfer_xml_attrs(attrs, nb_attributes);
+    if (check_required_attribute(string("name"))
+        && check_required_attribute(string("attribute"))) {
+        set_state(inside_alias);
+        at_stack.top()->attr_alias(attribute_table["name"].value,
+                                   attribute_table["attribute"].value);
+    }
+}
+
+/** Given that a tag which opens a variable declaration has just been read,
+    create the variable. Once created, push the variable onto the stack of
+    variables, push that variables attribute table onto the attribute table
+    stack and update the state of the parser.
+    @param t The type of variable to create.
+    @param s The next state of the parser.
+    @param attrs the attributes read with the tag */
+void DDXParser::process_variable(Type t, ParseState s, const xmlChar **attrs,
+        int nb_attributes)
+{
+    transfer_xml_attrs(attrs, nb_attributes);
+
+    set_state(s);
+    if (bt_stack.top()->type() == dods_array_c
+            || check_required_attribute("name")) { // throws on error/false
+        BaseType *btp = factory(t, attribute_table["name"].value);
+        if (!btp)
+            ddx_fatal_error(
+                    this,
+                    "Internal parser error; could not instantiate the variable '%s'.",
+                    attribute_table["name"].value.c_str());
+
+        // Once we make the new variable, we not only load it on to the
+        // BaseType stack, we also load its AttrTable on the AttrTable stack.
+        // The attribute processing software always operates on the AttrTable
+        // at the top of the AttrTable stack (at_stack).
+        bt_stack.push(btp);
+        at_stack.push(&btp->get_attr_table());
+    }
+}
+
+/** Given that a \c dimension tag has just been read, add that information to
+    the array on the top of the BaseType stack.
+    @param attrs The XML attributes included in the \c dimension tag */
+void DDXParser::process_dimension(const xmlChar **attrs, int nb_attributes)
+{
+    transfer_xml_attrs(attrs, nb_attributes);
+    if (check_required_attribute(string("size"))) {
+        set_state(inside_dimension);
+        Array *ap = dynamic_cast < Array * >(bt_stack.top());
+		if (!ap) {
+			ddx_fatal_error(this, "Parse error: Expected an array variable.");
+			return;
+		}
+		
+        ap->append_dim(atoi(attribute_table["size"].value.c_str()),
+                       attribute_table["name"].value);
+    }
+}
+
+/** Given that a \c blob tag has just been read, extract and save the CID
+    included in the element. */
+void DDXParser::process_blob(const xmlChar **attrs, int nb_attributes)
+{
+    transfer_xml_attrs(attrs, nb_attributes);
+    if (check_required_attribute(string("href"))) {
+        set_state(inside_blob_href);
+        *blob_href = attribute_table["href"].value;
+    }
+}
+
+/** Check to see if the current tag is either an \c Attribute or an \c Alias
+    start tag. This method is a glorified macro...
+
+    @param name The start tag name
+    @param attrs The tag's XML attributes
+    @return True if the tag was an \c Attribute or \c Alias tag */
+inline bool
+DDXParser::is_attribute_or_alias(const char *name, const xmlChar **attrs,
+        int nb_attributes)
+{
+    if (strcmp(name, "Attribute") == 0) {
+        process_attribute_element(attrs, nb_attributes);
+        // next state: inside_attribtue or inside_attribute_container
+        return true;
+    }
+    else if (strcmp(name, "Alias") == 0) {
+        process_attribute_alias(attrs, nb_attributes);
+        // next state: inside_alias
+        return true;
+    }
+
+    return false;
+}
+
+/** Check to see if the current tag is the start of a variable declaration.
+    If so, process it. A glorified macro...
+    @param name The start tag name
+    @param attrs The tag's XML attributes
+    @return True if the tag was a variable tag */
+inline bool DDXParser::is_variable(const char *name, const xmlChar **attrs,
+        int nb_attributes)
+{
+    Type t;
+    if ((t = is_simple_type(name)) != dods_null_c) {
+        process_variable(t, inside_simple_type, attrs, nb_attributes);
+        return true;
+    }
+    else if (strcmp(name, "Array") == 0) {
+        process_variable(dods_array_c, inside_array, attrs, nb_attributes);
+        return true;
+    }
+    else if (strcmp(name, "Structure") == 0) {
+        process_variable(dods_structure_c, inside_structure, attrs, nb_attributes);
+        return true;
+    }
+    else if (strcmp(name, "Sequence") == 0) {
+        process_variable(dods_sequence_c, inside_sequence, attrs, nb_attributes);
+        return true;
+    }
+    else if (strcmp(name, "Grid") == 0) {
+        process_variable(dods_grid_c, inside_grid, attrs, nb_attributes);
+        return true;
+    }
+
+    return false;
+}
+
+void DDXParser::finish_variable(const char *tag, Type t, const char *expected)
+{
+    if (strcmp(tag, expected) != 0) {
+        DDXParser::ddx_fatal_error(this,
+                                   "Expected an end tag for a %s; found '%s' instead.",
+                                   expected, tag);
+        return;
+    }
+
+    pop_state();
+
+    BaseType *btp = bt_stack.top();
+
+    bt_stack.pop();
+    at_stack.pop();
+
+    if (btp->type() != t) {
+        DDXParser::ddx_fatal_error(this,
+                                   "Internal error: Expected a %s variable.",
+                                   expected);
+        return;
+    }
+    // Once libxml2 validates, this can go away. 05/30/03 jhrg
+    if (t == dods_array_c
+        && dynamic_cast < Array * >(btp)->dimensions() == 0) {
+        DDXParser::ddx_fatal_error(this,
+                                   "No dimension element included in the Array '%s'.",
+                                   btp->name().c_str());
+        return;
+    }
+
+    BaseType *parent = bt_stack.top();
+
+    if (!(parent->is_vector_type() || parent->is_constructor_type())) {
+        DDXParser::ddx_fatal_error(this,
+                                   "Tried to add the array variable '%s' to a non-constructor type (%s %s).",
+                                   tag,
+                                   bt_stack.top()->type_name().c_str(),
+                                   bt_stack.top()->name().c_str());
+        return;
+    }
+
+    parent->add_var(btp);
+}
+
+/** @name SAX Parser Callbacks
+
+    These methods are declared static in the class header. This gives them C
+    linkage which allows them to be used as callbacks by the SAX parser
+    engine. */
+//@{
+
+/** Initialize the SAX parser state object. This object is passed to each
+    callback as a void pointer. The initial state is parser_start.
+
+    @param p The SAX parser  */
+void DDXParser::ddx_start_document(void * p)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+    parser->error_msg = "";
+    parser->char_data = "";
+
+    // init attr table stack.
+    parser->at_stack.push(&parser->dds->get_attr_table());
+
+    // Trick; DDS *should* be a child of Structure. To simplify parsing,
+    // stuff a Structure on the bt_stack and dump the top level variables
+    // there. Once we're done, transfer the variables to the DDS.
+    parser->bt_stack.push(new Structure("dummy_dds"));
+
+    parser->set_state(parser_start);
+
+    DBG2(cerr << "Parser state: " << states[parser->get_state()] << endl);
+}
+
+/** Clean up after finishing a parse.
+    @param p The SAX parser  */
+void DDXParser::ddx_end_document(void * p)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+    DBG2(cerr << "Ending state == " << states[parser->get_state()] <<
+         endl);
+
+    if (parser->get_state() != parser_start)
+        DDXParser::ddx_fatal_error(parser,
+                                   "The document contained unbalanced tags.");
+
+    // If we've found any sort of error, don't make the DDX; intern() will
+    // take care of the error.
+    if (parser->get_state() == parser_error)
+        return;
+
+    // Pop the temporary Structure off the stack and transfer its variables
+    // to the DDS.
+    Constructor *cp = dynamic_cast < Constructor * >(parser->bt_stack.top());
+    if (!cp) {
+    	ddx_fatal_error(parser, "Parse error: Expected a Structure, Sequence or Grid variable.");
+		return;
+    }
+    
+    for (Constructor::Vars_iter i = cp->var_begin(); i != cp->var_end();
+         ++i)
+        parser->dds->add_var(*i);
+
+    parser->bt_stack.pop();
+    delete cp;
+}
+
+void DDXParser::ddx_sax2_start_element(void *p,
+        const xmlChar *l, const xmlChar *prefix, const xmlChar *URI,
+        int nb_namespaces, const xmlChar **namespaces,
+        int nb_attributes, int /*nb_defaulted*/, const xmlChar **attributes)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+    const char *localname = (const char *)l;
+
+    DBG2(cerr << "start element: " << localname << ", states: "
+         << states[parser->get_state()]);
+
+    switch (parser->get_state()) {
+    case parser_start:
+        if (strcmp(localname, "Dataset") == 0) {
+            parser->set_state(inside_dataset);
+            parser->root_ns = URI != 0 ? (const char *)URI: "";
+            parser->transfer_xml_attrs(attributes, nb_attributes);
+
+            if (parser->check_required_attribute(string("name")))
+                parser->dds->set_dataset_name(parser->attribute_table["name"].value);
+
+            if (parser->check_attribute("dapVersion"))
+                parser->dds->set_dap_version(parser->attribute_table["dapVersion"].value);
+        }
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected response to start with a Dataset element; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_dataset:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (parser->is_variable(localname, attributes, nb_attributes))
+            break;
+        else if (strcmp(localname, "blob") == 0 || strcmp(localname, "dataBLOB") == 0) {
+            parser->process_blob(attributes, nb_attributes);
+            // next state: inside_data_blob
+        }
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an Attribute, Alias or variable element; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_attribute_container:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an Attribute or Alias element; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_attribute:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (strcmp(localname, "value") == 0)
+            parser->set_state(inside_attribute_value);
+        else
+            ddx_fatal_error(parser,
+                            "Expected an 'Attribute', 'Alias' or 'value' element; found '%s' instead.",
+                            localname);
+        break;
+
+    case inside_attribute_value:
+        ddx_fatal_error(parser,
+                        "Internal parser error; unexpected state, inside value while processing element '%s'.",
+                        localname);
+        break;
+
+    case inside_other_xml_attribute:
+        DBGN(cerr << endl << "\t inside_other_xml_attribute: " << localname << endl);
+
+        parser->other_xml_depth++;
+
+        // Accumulate the elements here
+
+        parser->other_xml.append("<");
+        if (prefix) {
+            parser->other_xml.append((const char *)prefix);
+            parser->other_xml.append(":");
+        }
+        parser->other_xml.append(localname);
+
+        if (nb_namespaces != 0) {
+            parser->transfer_xml_ns(namespaces, nb_namespaces);
+
+            for (map<string,string>::iterator i = parser->namespace_table.begin();
+                i != parser->namespace_table.end();
+                ++i) {
+                parser->other_xml.append(" xmlns");
+                if (!i->first.empty()) {
+                    parser->other_xml.append(":");
+                    parser->other_xml.append(i->first);
+                }
+                parser->other_xml.append("=\"");
+                parser->other_xml.append(i->second);
+                parser->other_xml.append("\"");
+            }
+        }
+
+        if (nb_attributes != 0) {
+            parser->transfer_xml_attrs(attributes, nb_attributes);
+            for (XMLAttrMap::iterator i = parser->attr_table_begin();
+                i != parser->attr_table_end();
+                ++i) {
+                parser->other_xml.append(" ");
+                if (!i->second.prefix.empty()) {
+                    parser->other_xml.append(i->second.prefix);
+                    parser->other_xml.append(":");
+                }
+                parser->other_xml.append(i->first);
+                parser->other_xml.append("=\"");
+                parser->other_xml.append(i->second.value);
+                parser->other_xml.append("\"");
+            }
+        }
+
+        parser->other_xml.append(">");
+        break;
+
+    case inside_alias:
+        ddx_fatal_error(parser,
+                        "Internal parser error; unexpected state, inside alias while processing element '%s'.",
+                        localname);
+        break;
+
+    case inside_simple_type:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else
+            ddx_fatal_error(parser,
+                            "Expected an 'Attribute' or 'Alias' element; found '%s' instead.",
+                            localname);
+        break;
+
+    case inside_array:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (is_not(localname, "Array")
+                && parser->is_variable(localname, attributes, nb_attributes))
+            break;
+        else if (strcmp(localname, "dimension") == 0) {
+            parser->process_dimension(attributes, nb_attributes);
+            // next state: inside_dimension
+        }
+        else
+            ddx_fatal_error(parser,
+                            "Expected an 'Attribute' or 'Alias' element; found '%s' instead.",
+                            localname);
+        break;
+
+    case inside_dimension:
+        ddx_fatal_error(parser,
+                        "Internal parser error; unexpected state, inside dimension while processing element '%s'.",
+                        localname);
+        break;
+
+    case inside_structure:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (parser->is_variable(localname, attributes, nb_attributes))
+            break;
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an Attribute, Alias or variable element; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_sequence:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (parser->is_variable(localname, attributes, nb_attributes))
+            break;
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an Attribute, Alias or variable element; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_grid:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (strcmp(localname, "Array") == 0)
+            parser->process_variable(dods_array_c, inside_array, attributes, nb_attributes);
+        else if (strcmp(localname, "Map") == 0)
+            parser->process_variable(dods_array_c, inside_map, attributes, nb_attributes);
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an Attribute, Alias or variable element; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_map:
+        if (parser->is_attribute_or_alias(localname, attributes, nb_attributes))
+            break;
+        else if (is_not(localname, "Array") && is_not(localname, "Sequence")
+                 && is_not(localname, "Grid")
+                 && parser->is_variable(localname, attributes, nb_attributes))
+            break;
+        else if (strcmp(localname, "dimension") == 0) {
+            parser->process_dimension(attributes, nb_attributes);
+            // next state: inside_dimension
+        }
+        else
+            ddx_fatal_error(parser,
+                            "Expected an 'Attribute', 'Alias', variable or 'dimension' element; found '%s' instead.",
+                            localname);
+        break;
+
+    case inside_blob_href:
+        ddx_fatal_error(parser,
+                        "Internal parser error; unexpected state, inside blob href while processing element '%s'.",
+                        localname);
+        break;
+
+    case parser_unknown:
+        // *** Never used? If so remove/error
+        parser->set_state(parser_unknown);
+        break;
+
+    case parser_error:
+        break;
+    }
+
+    DBGN(cerr << " ... " << states[parser->get_state()] << endl);
+}
+
+void DDXParser::ddx_sax2_end_element(void *p, const xmlChar *l,
+        const xmlChar *prefix, const xmlChar *URI)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+    const char *localname = (const char *)l;
+
+    DBG2(cerr << "End element " << localname << " (state "
+         << states[parser->get_state()] << ")" << endl);
+
+    switch (parser->get_state()) {
+    case parser_start:
+        ddx_fatal_error(parser,
+                        "Internal parser error; unexpected state, inside start state while processing element '%s'.",
+                        localname);
+        break;
+
+    case inside_dataset:
+        if (strcmp(localname, "Dataset") == 0)
+            parser->pop_state();
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end Dataset tag; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_attribute_container:
+        if (strcmp(localname, "Attribute") == 0) {
+            parser->pop_state();
+            parser->at_stack.pop();     // pop when leaving a container.
+        }
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end Attribute tag; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_attribute:
+        if (strcmp(localname, "Attribute") == 0)
+            parser->pop_state();
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end Attribute tag; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_attribute_value:
+        if (strcmp(localname, "value") == 0) {
+            parser->pop_state();
+            AttrTable *atp = parser->at_stack.top();
+            atp->append_attr(parser->dods_attr_name,
+                             parser->dods_attr_type, parser->char_data);
+            parser->char_data = "";     // Null this after use.
+        }
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end value tag; found '%s' instead.",
+                                       localname);
+
+        break;
+
+    case inside_other_xml_attribute: {
+            if (strcmp(localname, "Attribute") == 0
+                    && parser->root_ns == (const char *)URI) {
+
+                DBGN(cerr << endl << "\t Popping the 'inside_other_xml_attribute' state"
+                        << endl);
+
+                parser->pop_state();
+
+                AttrTable *atp = parser->at_stack.top();
+                atp->append_attr(parser->dods_attr_name,
+                        parser->dods_attr_type, parser->other_xml);
+
+                parser->other_xml = ""; // Null this after use.
+            }
+            else {
+                DBGN(cerr << endl << "\t inside_other_xml_attribute: " << localname
+                        << ", depth: " << parser->other_xml_depth << endl);
+                if (parser->other_xml_depth == 0)
+                    DDXParser::ddx_fatal_error(parser,
+                                               "Expected an OtherXML attribute to end! Instead I found '%s'",
+                                               localname);
+                parser->other_xml_depth--;
+
+                parser->other_xml.append("</");
+                if (prefix) {
+                    parser->other_xml.append((const char *)prefix);
+                    parser->other_xml.append(":");
+                }
+                parser->other_xml.append(localname);
+                parser->other_xml.append(">");
+            }
+            break;
+        }
+        // Alias is busted in libdap++ 05/29/03 jhrg
+    case inside_alias:
+        parser->pop_state();
+        break;
+
+    case inside_simple_type:
+        if (is_simple_type(localname) != dods_null_c) {
+            parser->pop_state();
+            BaseType *btp = parser->bt_stack.top();
+            parser->bt_stack.pop();
+            parser->at_stack.pop();
+
+            BaseType *parent = parser->bt_stack.top();
+
+            if (parent->is_vector_type() || parent->is_constructor_type())
+                parent->add_var(btp);
+            else
+                DDXParser::ddx_fatal_error(parser,
+                                           "Tried to add the simple-type variable '%s' to a non-constructor type (%s %s).",
+                                           localname,
+                                           parser->bt_stack.top()->
+                                           type_name().c_str(),
+                                           parser->bt_stack.top()->name().
+                                           c_str());
+        }
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end tag for a simple type; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_array:
+        parser->finish_variable(localname, dods_array_c, "Array");
+        break;
+
+    case inside_dimension:
+        if (strcmp(localname, "dimension") == 0)
+            parser->pop_state();
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end dimension tag; found '%s' instead.",
+                                       localname);
+        break;
+
+    case inside_structure:
+        parser->finish_variable(localname, dods_structure_c, "Structure");
+        break;
+
+    case inside_sequence:
+        parser->finish_variable(localname, dods_sequence_c, "Sequence");
+        break;
+
+    case inside_grid:
+        parser->finish_variable(localname, dods_grid_c, "Grid");
+        break;
+
+    case inside_map:
+        parser->finish_variable(localname, dods_array_c, "Map");
+        break;
+
+    case inside_blob_href:
+        if (strcmp(localname, "blob") == 0 || strcmp(localname, "dataBLOB") == 0)
+            parser->pop_state();
+        else
+            DDXParser::ddx_fatal_error(parser,
+                                       "Expected an end dataBLOB/blob tag; found '%s' instead.",
+                                       localname);
+        break;
+
+    case parser_unknown:
+        parser->pop_state();
+        break;
+
+    case parser_error:
+        break;
+    }
+
+
+    DBGN(cerr << " ... " << states[parser->get_state()] << endl);
+}
+
+/** Process/accumulate character data. This may be called more than once for
+    one logical clump of data. Only save character data when processing
+    'value' elements; throw away all other characters. */
+void DDXParser::ddx_get_characters(void * p, const xmlChar * ch, int len)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+
+    switch (parser->get_state()) {
+        case inside_attribute_value:
+            parser->char_data.append((const char *)(ch), len);
+            DBG2(cerr << "Characters: '" << parser->char_data << "'" << endl);
+            break;
+
+        case inside_other_xml_attribute:
+            parser->other_xml.append((const char *)(ch), len);
+            DBG2(cerr << "Other XML Characters: '" << parser->other_xml << "'" << endl);
+            break;
+
+        default:
+            break;
+    }
+}
+
+/** Read whitespace that's not really important for content. This is used
+    only for the OtherXML attribute type to preserve formating of the XML.
+    Doing so makes the attribute value far easier to read.
+ */
+void DDXParser::ddx_ignoreable_whitespace(void *p, const xmlChar *ch,
+        int len)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+
+    switch (parser->get_state()) {
+         case inside_other_xml_attribute:
+             parser->other_xml.append((const char *)(ch), len);
+             break;
+
+         default:
+             break;
+    }
+}
+
+/** Get characters in a cdata block. DAP does not use CData, but XML in an
+    OtherXML attribute (the value of that DAP attribute) might use it. This
+    callback also allows CData when the parser is in the 'parser_unknown'
+    state since some future DAP element might use it.
+ */
+void DDXParser::ddx_get_cdata(void *p, const xmlChar *value, int len)
+{
+    DDXParser *parser = static_cast<DDXParser*>(p);
+
+    switch (parser->get_state()) {
+         case inside_other_xml_attribute:
+             parser->other_xml.append((const char *)(value), len);
+             break;
+
+         case parser_unknown:
+             break;
+
+         default:
+             DDXParser::ddx_fatal_error(parser,
+                                        "Found a CData block but none are allowed by DAP.");
+
+             break;
+    }
+}
+
+/** Handle the standard XML entities.
+
+    @param parser The SAX parser
+    @param name The XML entity. */
+xmlEntityPtr DDXParser::ddx_get_entity(void *, const xmlChar * name)
+{
+    return xmlGetPredefinedEntity(name);
+}
+
+/** Process an XML fatal error. Note that SAX provides for warnings, errors
+    and fatal errors. This code treats them all as fatal errors since there's
+    typically no way to tell a user about the error since there's often no
+    user interface for this software.
+
+    @param p The SAX parser
+    @param msg A printf-style format string. */
+void DDXParser::ddx_fatal_error(void * p, const char *msg, ...)
+{
+    va_list args;
+    DDXParser *parser = static_cast<DDXParser*>(p);
+
+    parser->set_state(parser_error);
+
+    va_start(args, msg);
+    char str[1024];
+    vsnprintf(str, 1024, msg, args);
+    va_end(args);
+
+    int line = xmlSAX2GetLineNumber(parser->ctxt);
+
+    parser->error_msg += "At line " + long_to_string(line) + ": ";
+    parser->error_msg += string(str) + string("\n");
+}
+
+//@}
+
+void DDXParser::cleanup_parse(xmlParserCtxtPtr & context) const
+{
+    if (!context->wellFormed) {
+        context->sax = NULL;
+        xmlFreeParserCtxt(context);
+        throw
+        DDXParseFailed(string
+                       ("\nThe DDX is not a well formed XML document.\n")
+                       + error_msg);
+    }
+
+    if (!context->valid) {
+        context->sax = NULL;
+        xmlFreeParserCtxt(context);
+        throw DDXParseFailed(string("\nThe DDX is not a valid document.\n")
+                             + error_msg);
+    }
+
+    if (get_state() == parser_error) {
+        context->sax = NULL;
+        xmlFreeParserCtxt(context);
+        throw DDXParseFailed(string("\nError parsing DDX response.\n") +
+                             error_msg);
+    }
+
+    context->sax = NULL;
+    xmlFreeParserCtxt(context);
+}
+
+/** @brief Read the DDX from a stream instead of a file.
+    @see DDXParser::intern(). */
+void DDXParser::intern_stream(FILE *in, DDS *dest_dds, string &cid,
+	const string &boundary)
+{
+    // Code example from libxml2 docs re: read from a stream.
+
+    if (!in || feof(in) || ferror(in))
+        throw InternalErr(__FILE__, __LINE__,
+                          "Input stream not open or read error");
+
+    const int size = 1024;
+    char chars[size];
+
+    int res = fread(chars, 1, 4, in);
+    if (res > 0) {
+        xmlParserCtxtPtr context =
+            xmlCreatePushParserCtxt(NULL, NULL, chars, res, "stream");
+
+        ctxt = context;         // need ctxt for error messages
+        dds = dest_dds;         // dump values here
+        blob_href = &cid; 	// cid goes here
+
+        xmlSAXHandler ddx_sax_parser;
+        memset( &ddx_sax_parser, 0, sizeof(xmlSAXHandler) );
+
+        ddx_sax_parser.getEntity = &DDXParser::ddx_get_entity;
+        ddx_sax_parser.startDocument = &DDXParser::ddx_start_document;
+        ddx_sax_parser.endDocument = &DDXParser::ddx_end_document;
+        ddx_sax_parser.characters = &DDXParser::ddx_get_characters;
+        ddx_sax_parser.ignorableWhitespace = &DDXParser::ddx_ignoreable_whitespace;
+        ddx_sax_parser.cdataBlock = &DDXParser::ddx_get_cdata;
+        ddx_sax_parser.warning = &DDXParser::ddx_fatal_error;
+        ddx_sax_parser.error = &DDXParser::ddx_fatal_error;
+        ddx_sax_parser.fatalError = &DDXParser::ddx_fatal_error;
+        ddx_sax_parser.initialized = XML_SAX2_MAGIC;
+        ddx_sax_parser.startElementNs = &DDXParser::ddx_sax2_start_element;
+        ddx_sax_parser.endElementNs = &DDXParser::ddx_sax2_end_element;
+
+        context->sax = &ddx_sax_parser;
+        context->userData = this;
+        context->validate = true;
+
+
+        while ((fgets(chars, size, in) > 0) && !is_boundary(chars, boundary)) {
+            chars[size-1] = '\0';
+            DBG(cerr << "line: " << chars << endl);
+            xmlParseChunk(ctxt, chars, strlen(chars), 0);
+        }
+        // This call ends the parse: The fourth argument of xmlParseChunk is
+        // the bool 'terminate.'
+        xmlParseChunk(ctxt, chars, 0, 1);
+
+        cleanup_parse(context);
+    }
+}
+
+
+/** Parse a DDX document stored in a file. The XML in the document is parsed
+    and a binary DDX is built. This implementation stores the result in a DDS
+    object where each instance of BaseType can hold an AttrTable object.
+
+    @param document Read the DDX from this file.
+    @param dest_dds Value/result parameter; dumps the information to this DDS
+    instance.
+    @param cid Value/result parameter; puts the href which references the \c
+    CID.
+    @exception DDXParseFailed Thrown if the XML document could not be
+    read or parsed. */
+void DDXParser::intern(const string & document, DDS * dest_dds, string &cid)
+{
+    // Create the context pointer explicitly so that we can store a pointer
+    // to it in the DDXParser instance. This provides a way to generate our
+    // own error messages *with* line numbers. The messages are pretty
+    // meaningless otherwise. This means that we use an interface from the
+    // 'parser internals' header, and not the 'parser' header. However, this
+    // interface is also used in one of the documented examples, so it's
+    // probably pretty stable. 06/02/03 jhrg
+    xmlParserCtxtPtr context = xmlCreateFileParserCtxt(document.c_str());
+    if (!context)
+        throw
+        DDXParseFailed(string
+                       ("Could not initialize the parser with the file: '")
+                       + document + string("'."));
+
+    dds = dest_dds;             // dump values here
+    blob_href = &cid;
+    ctxt = context;             // need ctxt for error messages
+
+    xmlSAXHandler ddx_sax_parser;
+    memset( &ddx_sax_parser, 0, sizeof(xmlSAXHandler) );
+
+    ddx_sax_parser.getEntity = &DDXParser::ddx_get_entity;
+    ddx_sax_parser.startDocument = &DDXParser::ddx_start_document;
+    ddx_sax_parser.endDocument = &DDXParser::ddx_end_document;
+    ddx_sax_parser.characters = &DDXParser::ddx_get_characters;
+    ddx_sax_parser.ignorableWhitespace = &DDXParser::ddx_ignoreable_whitespace;
+    ddx_sax_parser.cdataBlock = &DDXParser::ddx_get_cdata;
+    ddx_sax_parser.warning = &DDXParser::ddx_fatal_error;
+    ddx_sax_parser.error = &DDXParser::ddx_fatal_error;
+    ddx_sax_parser.fatalError = &DDXParser::ddx_fatal_error;
+    ddx_sax_parser.initialized = XML_SAX2_MAGIC;
+    ddx_sax_parser.startElementNs = &DDXParser::ddx_sax2_start_element;
+    ddx_sax_parser.endElementNs = &DDXParser::ddx_sax2_end_element;
+
+    context->sax = &ddx_sax_parser;
+    context->userData = this;
+    context->validate = false;
+
+    xmlParseDocument(context);
+
+    cleanup_parse(context);
+}
+
+} // namespace libdap
diff --git a/DDXParserSAX2.h b/DDXParserSAX2.h
new file mode 100644
index 0000000..51b009f
--- /dev/null
+++ b/DDXParserSAX2.h
@@ -0,0 +1,267 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef ddx_parser_h
+#define ddx_parser_h
+
+#include <string>
+#include <map>
+#include <stack>
+
+#include <libxml/parserInternals.h>
+
+#ifndef ddx_exceptions_h
+#include "DDXExceptions.h"
+#endif
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef base_type_factory_h
+#include "BaseTypeFactory.h"
+#endif
+
+namespace libdap
+{
+
+/** Parse the XML text which encodes the network/persistent representation of
+    the DDX object. In the current implementation, the DDX is held by an
+    instance of the class DDS which in turn holds variables which include
+    attributes. That is, the binary \e implementation of a DDX uses the old
+    DDS, BaseType and AttrTable classes, albeit arranged in a slightly new
+    way.
+
+    This parser for the DDX \e document uses the SAX interface of \c libxml2.
+    Static methods are used as callbacks for the SAX parser. These static
+    methods are public because making them private complicates compilation.
+    They should not be called by anything other than the \e intern method.
+    They do not throw exceptions because exceptions from within callbacks are
+    not reliable or portable. To signal errors, the methods record
+    information in the DDXParser object. Once the error handler is called,
+    construction of an DDX/DDS object ends even though the SAX parser still
+    calls the various callback functions. The parser treats \e warnings, \e
+    errors and \e fatal_errors the same way; when any are found parsing
+    stops. The \e intern method throws an DDXParseFailed exception if an
+    error was found.
+
+    Note that this class uses the C++-supplied default definitions for the
+    default and copy constructors as well as the destructor and assignment
+    operator.
+
+    @see DDS */
+class DDXParser
+{
+private:
+    /** States used by DDXParserState. These are the states of the SAX parser
+    state-machine. */
+    enum ParseState {
+        parser_start,
+
+        inside_dataset,
+
+        inside_attribute_container,
+        inside_attribute,
+        inside_attribute_value,
+        inside_other_xml_attribute,
+
+        inside_alias,
+
+        // This covers Byte, ..., Url.
+        inside_simple_type,
+
+        inside_array,
+        inside_dimension,
+
+        inside_grid,
+        inside_map,
+
+        inside_structure,
+        inside_sequence,
+
+        inside_blob_href,
+
+        parser_unknown,
+        parser_error
+    };
+
+    BaseTypeFactory *d_factory;
+
+    // These stacks hold the state of the parse as it progresses.
+    stack<ParseState> s; // Current parse state
+    stack<BaseType*> bt_stack; // current variable(s)
+    stack<AttrTable*> at_stack; // current attribute table
+
+    // Accumulate stuff inside an 'OtherXML' DAP attribute here
+    string other_xml;
+
+    // When we're parsing unknown XML, how deeply is it nested? This is used
+    // for the OtherXML DAP attributes.
+    unsigned int other_xml_depth;
+    unsigned int unknown_depth;
+
+    // These are used for processing errors.
+    string error_msg;  // Error message(s), if any.
+    xmlParserCtxtPtr ctxt; // used for error message line numbers
+
+    // The results of the parse operation are stored in these fields.
+    DDS *dds;   // dump DDX here
+    string *blob_href;  // put href to blob here
+
+    // These hold temporary values read during the parse.
+    string dods_attr_name; // DAP2 attributes, not XML attributes
+    string dods_attr_type; // ... not XML ...
+    string char_data;  // char data in value elements; null after use
+    string root_ns;     // What is the namespace of the root node (Dataset)
+
+    class XMLAttribute {
+        public:
+        string prefix;
+        string nsURI;
+        string value;
+
+        void clone(const XMLAttribute &src) {
+            prefix = src.prefix;
+            nsURI = src.nsURI;
+            value = src.value;
+        }
+
+        XMLAttribute() : prefix(""), nsURI(""), value("") {}
+        XMLAttribute(const string &p, const string &ns, const string &v)
+            : prefix(p), nsURI(ns), value(v) {}
+        // 'attributes' as passed from libxml2 is a five element array but this
+        // ctor gets the back four elements.
+        XMLAttribute(const xmlChar **attributes/*[4]*/) {
+            prefix = attributes[0] != 0 ? (const char *)attributes[0]: "";
+            nsURI = attributes[1] != 0 ? (const char *)attributes[1]: "";
+            value = string((const char *)attributes[2], (const char *)attributes[3]);
+        }
+        XMLAttribute(const XMLAttribute &rhs) {
+            clone(rhs);
+        }
+        XMLAttribute &operator=(const XMLAttribute &rhs) {
+            if (this == &rhs)
+                return *this;
+            clone(rhs);
+            return *this;
+        }
+    };
+
+    typedef map<string, XMLAttribute> XMLAttrMap;
+    XMLAttrMap attribute_table; // dump XML attributes here
+
+    XMLAttrMap::iterator attr_table_begin() {
+        return attribute_table.begin();
+    }
+
+    XMLAttrMap::iterator attr_table_end() {
+        return attribute_table.end();
+    }
+
+    map<string, string> namespace_table;
+
+    // These are kind of silly...
+    void set_state(DDXParser::ParseState state);
+    DDXParser::ParseState get_state() const;
+    void pop_state();
+
+    // Glue for the BaseTypeFactory class.
+    BaseType *factory(Type t, const string &name);
+
+    // Common cleanup code for intern() and intern_stream()
+    void cleanup_parse(xmlParserCtxtPtr &context) const;
+
+    /** @name Parser Actions
+
+    These methods are the 'actions' carried out by the start_element and
+    end_element callbacks. Most of what takes place in those has been
+    factored out to this set of functions. */
+    //@{
+    void transfer_xml_attrs(const xmlChar **attrs, int nb_attributes);
+    void transfer_xml_ns(const xmlChar **namespaces, int nb_namespaces);
+    bool check_required_attribute(const string &attr);
+    bool check_attribute(const string & attr);
+
+    void process_attribute_element(const xmlChar **attrs, int nb_attrs);
+    void process_attribute_alias(const xmlChar **attrs, int nb_attrs);
+
+    void process_variable(Type t, ParseState s, const xmlChar **attrs,
+            int nb_attributes);
+
+    void process_dimension(const xmlChar **attrs, int nb_attrs);
+    void process_blob(const xmlChar **attrs, int nb_attrs);
+
+    bool is_attribute_or_alias(const char *name, const xmlChar **attrs,
+            int nb_attributes);
+    bool is_variable(const char *name, const xmlChar **attrs, int nb_attributes);
+
+    void finish_variable(const char *tag, Type t, const char *expected);
+    //@}
+
+    /// Define the default ctor here to prevent its use.
+    DDXParser() {}
+    //{throw InternalErr(__FILE__, __LINE__, "DDXParser internal ctor called!");}
+
+    friend class DDXParserTest;
+
+public:
+    DDXParser(BaseTypeFactory *factory)
+        : d_factory(factory),
+        other_xml(""), other_xml_depth(0), unknown_depth(0),
+        error_msg(""), ctxt(0), dds(0), blob_href(0),
+        dods_attr_name(""), dods_attr_type(""),
+        char_data(""), root_ns("")
+    {}
+
+    void intern(const string &document, DDS *dest_dds, string &cid);
+    void intern_stream(FILE *in, DDS *dds, string &cid,
+		const string &boundary = "");
+
+    static void ddx_start_document(void *parser);
+    static void ddx_end_document(void *parser);
+
+    static void ddx_sax2_start_element(void *parser,
+            const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
+            int nb_namespaces, const xmlChar **namespaces, int nb_attributes,
+            int nb_defaulted, const xmlChar **attributes);
+    static void ddx_sax2_end_element(void *parser, const xmlChar *localname,
+            const xmlChar *prefix, const xmlChar *URI);
+
+    static void ddx_get_characters(void *parser, const xmlChar *ch, int len);
+    static void ddx_ignoreable_whitespace(void *parser,
+            const xmlChar * ch, int len);
+    static void ddx_get_cdata(void *parser, const xmlChar *value, int len);
+
+    static xmlEntityPtr ddx_get_entity(void *parser, const xmlChar *name);
+    static void ddx_fatal_error(void *parser, const char *msg, ...);
+};
+
+} // namespace libdap
+
+#endif // ddx_parser_h
diff --git a/DODSFilter.cc b/DODSFilter.cc
new file mode 100644
index 0000000..034254c
--- /dev/null
+++ b/DODSFilter.cc
@@ -0,0 +1,1344 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation of the DODSFilter class. This class is used to build dods
+// filter programs which, along with a CGI program, comprise OPeNDAP servers.
+// jhrg 8/26/97
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: DODSFilter.cc 24281 2011-03-09 00:22:31Z jimg $"
+    };
+
+#include <signal.h>
+
+#ifndef WIN32
+#include <unistd.h>   // for getopt
+#include <sys/wait.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include <iostream>
+#include <string>
+#include <algorithm>
+#include <cstdlib>
+#include <cstring>
+
+#include <uuid/uuid.h>	// used to build CID header value for data ddx
+
+#include <GetOpt.h>
+
+#include "DAS.h"
+#include "DDS.h"
+#include "debug.h"
+#include "mime_util.h"
+#include "Ancillary.h"
+#include "util.h"
+#include "escaping.h"
+#include "DODSFilter.h"
+#if FILE_METHODS
+#include "XDRFileMarshaller.h"
+#endif
+#include "XDRStreamMarshaller.h"
+#include "InternalErr.h"
+
+#ifndef WIN32
+#include "SignalHandler.h"
+#include "EventHandler.h"
+#include "AlarmHandler.h"
+#endif
+
+#define CRLF "\r\n"             // Change here, expr-test.cc and DODSFilter.cc
+
+//#undef FILE_METHODS
+
+using namespace std;
+
+namespace libdap {
+
+const string usage =
+    "Usage: <handler name> -o <response> -u <url> [options ...] [data set]\n\
+    \n\
+    options: -o <response>: DAS, DDS, DataDDS, DDX, BLOB or Version (Required)\n\
+    -u <url>: The complete URL minus the CE (required for DDX)\n\
+    -c: Compress the response using the deflate algorithm.\n\
+    -e <expr>: When returning a DataDDS, use <expr> as the constraint.\n\
+    -v <version>: Use <version> as the version number\n\
+    -d <dir>: Look for ancillary file in <dir> (deprecated).\n\
+    -f <file>: Look for ancillary data in <file> (deprecated).\n\
+    -r <dir>: Use <dir> as a cache directory\n\
+    -l <time>: Conditional request; if data source is unchanged since\n\
+    <time>, return an HTTP 304 response.\n\
+    -t <seconds>: Timeout the handler after <seconds>.\n\
+    -h: This message.";
+
+/** Create an instance of DODSFilter using the command line
+arguments passed by the CGI (or other) program.  The default
+constructor is private; this and the copy constructor (which is
+just the default copy constructor) are the only way to create an
+instance of DODSFilter.
+
+These are the valid options:
+
+<dl>
+<dt><i>filename</i><dd>
+The name of the file on which the filter is to operate.  Usually
+this would be the file whose data has been requested. In fact, this class
+can be specialized and <i>any meaning</i> can be associated to this
+string. It could be the name of a database, for example.
+
+<dt><tt>-o</tt> <i>response</i><dd>
+
+Specifies the type of response desired. The \e response is a string
+and must be one of \c DAS, \c DDS, \c DataDDS or \c Version. Note
+that \c Version returns version information in the body of the response
+and is useful for debugging, et cetera. Each response returns version
+information in an HTTP header for internal use by a client.
+
+<dt><tt>-c</tt><dd>
+Send compressed data. Data are compressed using the deflate program.
+
+<dt><tt>-e</tt> <i>expression</i><dd>
+This option specifies a non-blank constraint expression used to
+subsample a dataset.
+
+<dt><tt>-v</tt> <i>cgi-version</i><dd> Set the CGI/Server version to
+<tt>cgi-version</tt>. This is a way for the caller to set version
+information passed back to the client either as the response to a
+version request of in the response headers.
+
+<dt><tt>-d</tt> <i>ancdir</i><dd>
+Specifies that ancillary data be sought in the <i>ancdir</i>
+directory. <i>ancdir</i> must end in '/'.
+
+<dt><tt>-f</tt> <i>ancfile</i><dd>
+Specifies that ancillary data may be found in a file called
+<i>ancfile</i>.
+
+<dt><tt>-r</tt> <i>cache directory</i><dd>
+Specify a directory to use if/when files are to be cached. Not all
+handlers support caching and each uses its own rules tailored to a
+specific file or data type.
+
+<dt><tt>-t</tt> <i>timeout</i><dd> Specifies a a timeout value in
+seconds. If the server runs longer than \e timeout seconds, an Error is
+returned to the client explaining that the request has timed out.
+
+<dt><tt>-l</tt> <i>time</i><dd> Indicates that the request is a
+conditional request; send a complete response if and only if the data has
+changed since <i>time</i>. If it has not changed since <i>time</i>, then
+send a 304 (Not Modified) response. The <i>time</i> parameter is the
+<tt>Last-Modified</tt> time from an If-Modified-Since condition GET
+request. It is given in seconds since the start of the Unix epoch
+(Midnight, 1 Jan 1970).
+
+</dl>
+
+ at brief DODSFilter constructor. */
+
+DODSFilter::DODSFilter(int argc, char *argv[]) throw(Error)
+{
+    initialize(argc, argv);
+
+    DBG(cerr << "d_comp: " << d_comp << endl);
+    DBG(cerr << "d_ce: " << d_ce << endl);
+    DBG(cerr << "d_cgi_ver: " << d_cgi_ver << endl);
+    DBG(cerr << "d_response: " << d_response << endl);
+    DBG(cerr << "d_anc_dir: " << d_anc_dir << endl);
+    DBG(cerr << "d_anc_file: " << d_anc_file << endl);
+    DBG(cerr << "d_cache_dir: " << d_cache_dir << endl);
+    DBG(cerr << "d_conditional_request: " << d_conditional_request << endl);
+    DBG(cerr << "d_if_modified_since: " << d_if_modified_since << endl);
+    DBG(cerr << "d_url: " << d_url << endl);
+    DBG(cerr << "d_timeout: " << d_timeout << endl);
+}
+
+DODSFilter::~DODSFilter()
+{
+}
+
+/** Called when initializing a DODSFilter that's not going to be passed a
+command line arguments. */
+void
+DODSFilter::initialize()
+{
+    // Set default values. Don't use the C++ constructor initialization so
+    // that a subclass can have more control over this process.
+    d_comp = false;
+    d_bad_options = false;
+    d_conditional_request = false;
+    d_dataset = "";
+    d_ce = "";
+    d_cgi_ver = "";
+    d_anc_dir = "";
+    d_anc_file = "";
+    d_cache_dir = "";
+    d_response = Unknown_Response;;
+    d_anc_das_lmt = 0;
+    d_anc_dds_lmt = 0;
+    d_if_modified_since = -1;
+    d_url = "";
+    d_program_name = "Unknown";
+    d_timeout = 0;
+
+#ifdef WIN32
+    //  We want serving from win32 to behave in a manner
+    //  similar to the UNIX way - no CR->NL terminated lines
+    //  in files. Hence stdout goes to binary mode.
+    _setmode(_fileno(stdout), _O_BINARY);
+#endif
+}
+
+/** Initialize. Specializations can call this once an empty DODSFilter has
+been created using the default constructor. Using a method such as this
+provides a way to specialize the process_options() method and then have
+that specialization called by the subclass' constructor.
+
+This class and any class that specializes it should call this method in
+its constructor. Note that when this method is called, the object is \e
+not fully constructed.
+
+ at param argc The argument count
+ at param argv The vector of char * argument strings. */
+void
+DODSFilter::initialize(int argc, char *argv[])
+{
+    initialize();
+
+    d_program_name = argv[0];
+
+    // This should be specialized by a subclass. This may throw Error.
+    int next_arg = process_options(argc, argv);
+
+    // Look at what's left after processing the command line options. Either
+    // there MUST be a dataset name OR the caller is asking for version
+    // information. If neither is true, then the options are bad.
+    if (next_arg < argc) {
+        d_dataset = argv[next_arg];
+        d_dataset = www2id(d_dataset, "%", "%20");
+    }
+    else if (get_response() != Version_Response)
+        print_usage();   // Throws Error
+}
+
+/** Processing the command line options passed to the filter is handled by
+this method so that specializations can change the options easily.
+
+ at param argc The argument count
+ at param argv The vector of char * argument strings.
+ at return The index of the next, unprocessed, argument. This must be the
+identifier passed to the filter program that identifies the data source.
+It's often a file name. */
+int
+DODSFilter::process_options(int argc, char *argv[])
+{
+    DBG(cerr << "Entering process_options... ");
+
+    int option_char;
+    GetOpt getopt (argc, argv, "ce: v: d: f: r: l: o: u: t: ");
+
+    while ((option_char = getopt()) != EOF) {
+        switch (option_char) {
+        case 'c': d_comp = true; break;
+        case 'e': set_ce(getopt.optarg); break;
+        case 'v': set_cgi_version(getopt.optarg); break;
+        case 'd': d_anc_dir = getopt.optarg; break;
+        case 'f': d_anc_file = getopt.optarg; break;
+        case 'r': d_cache_dir = getopt.optarg; break;
+        case 'o': set_response(getopt.optarg); break;
+        case 'u': set_URL(getopt.optarg); break;
+        case 't': d_timeout = atoi(getopt.optarg); break;
+        case 'l':
+            d_conditional_request = true;
+            d_if_modified_since
+            = static_cast<time_t>(strtol(getopt.optarg, NULL, 10));
+            break;
+        case 'h': print_usage(); exit(1);
+        default: print_usage(); // Throws Error
+        }
+    }
+
+    DBGN(cerr << "exiting." << endl);
+
+    return getopt.optind; // return the index of the next argument
+}
+
+/** @brief Is this request conditional?
+
+ at return True if the request is conditional.
+ at see get_request_if_modified_since(). */
+bool
+DODSFilter::is_conditional() const
+{
+    return d_conditional_request;
+}
+
+/** Set the CGI/Server version number. Servers use this when answering
+requests for version information. The version `number' should include
+both the name of the server (e.g., <tt>ff_dods</tt>) as well
+as the version
+number. Since this information is typically divined by configure,
+it's up to the executable to poke the correct value in using this
+method.
+
+Note that the -v switch that this class understands is deprecated
+since it is usually called by Perl code. It makes more sense to have
+the actual C++ software set the version string.
+
+ at param version A version string for this server. */
+void
+DODSFilter::set_cgi_version(string version)
+{
+    d_cgi_ver = version;
+}
+
+/** Return the version information passed to the instance when it was
+created. This string is passed to the DODSFilter ctor using the -v
+option.
+
+ at return The version string supplied at initialization. */
+string
+DODSFilter::get_cgi_version() const
+{
+    return d_cgi_ver;
+}
+
+/** Return the entire constraint expression in a string.  This
+includes both the projection and selection clauses, but not the
+question mark.
+
+ at brief Get the constraint expression.
+ at return A string object that contains the constraint expression. */
+string
+DODSFilter::get_ce() const
+{
+    return d_ce;
+}
+
+void
+DODSFilter::set_ce(string _ce)
+{
+    d_ce = www2id(_ce, "%", "%20");
+}
+
+/** The ``dataset name'' is the filename or other string that the
+filter program will use to access the data. In some cases this
+will indicate a disk file containing the data.  In others, it
+may represent a database query or some other exotic data
+access method.
+
+ at brief Get the dataset name.
+ at return A string object that contains the name of the dataset. */
+string
+DODSFilter::get_dataset_name() const
+{
+    return d_dataset;
+}
+
+void
+DODSFilter::set_dataset_name(const string ds)
+{
+    d_dataset = www2id(ds, "%", "%20");
+}
+
+/** Get the URL. This returns the URL, minus the constraint originally sent
+to the server.
+ at return The URL. */
+string
+DODSFilter::get_URL() const
+{
+    return d_url;
+}
+
+/** Set the URL. Set the URL sent to the server.
+ at param url The URL, minus the constraint. */
+void
+DODSFilter::set_URL(const string &url)
+{
+    if (url.find('?') != url.npos)
+        print_usage();  // Throws Error
+
+    d_url = url;
+}
+
+/** To read version information that is specific to a certain
+dataset, override this method with an implementation that does
+what you want. By default, this returns an empty string.
+
+ at brief Get the version information for the dataset.
+ at return A string object that contains the dataset version
+information.  */
+string
+DODSFilter::get_dataset_version() const
+{
+    return "";
+}
+
+/** Set the response to be returned. Valid response names are "DAS", "DDS",
+"DataDDS, "Version".
+
+ at param r The name of the object.
+ at exception InternalErr Thrown if the response is not one of the valid
+names. */
+void DODSFilter::set_response(const string &r)
+{
+    if (r == "DAS" || r == "das") {
+	d_response = DAS_Response;
+	d_action = "das" ;
+    }
+    else if (r == "DDS" || r == "dds") {
+	d_response = DDS_Response;
+	d_action = "dds" ;
+    }
+    else if (r == "DataDDS" || r == "dods") {
+	d_response = DataDDS_Response;
+	d_action = "dods" ;
+    }
+    else if (r == "DDX" || r == "ddx") {
+	d_response = DDX_Response;
+	d_action = "ddx" ;
+    }
+    else if (r == "DataDDX" || r == "dataddx") {
+	d_response = DataDDX_Response;
+	d_action = "dataddx" ;
+    }
+    else if (r == "Version") {
+	d_response = Version_Response;
+	d_action = "version" ;
+    }
+    else
+	print_usage();   // Throws Error
+}
+
+/** Get the enum name of the response to be returned. */
+DODSFilter::Response
+DODSFilter::get_response() const
+{
+    return d_response;
+}
+
+/** Get the string name of the response to be returned. */
+string DODSFilter::get_action() const
+{
+    return d_action;
+}
+
+/** Get the dataset's last modified time. This returns the time at which
+    the dataset was last modified as defined by UNIX's notion of
+    modification. This does not take into account the modification of an
+    ancillary DAS or DDS. Time is given in seconds since the epoch (1 Jan
+    1970 00:00:00 GMT).
+
+    This method perform a simple check on the file named by the dataset
+    given when the DODSFilter instance was created. If the dataset is not
+    a filter, this method returns the current time. Servers which provide
+    access to non-file-based data should subclass DODSFilter and supply a
+    more suitable version of this method.
+
+    From the stat(2) man page: ``Traditionally, <tt>st_mtime</tt>
+    is changed by mknod(2), utime(2), and write(2). The
+    <tt>st_mtime</tt> is not changed for
+    changes in owner, group, hard link count, or mode.''
+
+    @return Time of the last modification in seconds since the epoch.
+    @see get_das_last_modified_time()
+    @see get_dds_last_modified_time() */
+time_t
+DODSFilter::get_dataset_last_modified_time() const
+{
+    return last_modified_time(d_dataset);
+}
+
+/** Get the last modified time for the dataset's DAS. This time, given in
+    seconds since the epoch (1 Jan 1970 00:00:00 GMT), is the greater of
+    the datasets's and any ancillary DAS' last modified time.
+
+    @param anc_location A directory to search for ancillary files (in
+    addition to the CWD).
+    @return Time of last modification of the DAS.
+    @see get_dataset_last_modified_time()
+    @see get_dds_last_modified_time() */
+time_t
+DODSFilter::get_das_last_modified_time(const string &anc_location) const
+{
+    DBG(cerr << "DODSFilter::get_das_last_modified_time(anc_location="
+        << anc_location << "call faf(das) d_dataset=" << d_dataset
+        << " d_anc_file=" << d_anc_file << endl);
+
+    string name
+    = Ancillary::find_ancillary_file(d_dataset, "das",
+                          (anc_location == "") ? d_anc_dir : anc_location,
+                          d_anc_file);
+
+    return max((name != "") ? last_modified_time(name) : 0,
+               get_dataset_last_modified_time());
+}
+
+/** Get the last modified time for the dataset's DDS. This time, given in
+    seconds since the epoch (1 Jan 1970 00:00:00 GMT), is the greater of
+    the datasets's and any ancillary DDS' last modified time.
+
+    @return Time of last modification of the DDS.
+    @see get_dataset_last_modified_time()
+    @see get_dds_last_modified_time() */
+time_t
+DODSFilter::get_dds_last_modified_time(const string &anc_location) const
+{
+    DBG(cerr << "DODSFilter::get_das_last_modified_time(anc_location="
+        << anc_location << "call faf(dds) d_dataset=" << d_dataset
+        << " d_anc_file=" << d_anc_file << endl);
+
+    string name
+    = Ancillary::find_ancillary_file(d_dataset, "dds",
+                          (anc_location == "") ? d_anc_dir : anc_location,
+                          d_anc_file);
+
+    return max((name != "") ? last_modified_time(name) : 0,
+               get_dataset_last_modified_time());
+}
+
+/** Get the last modified time to be used for a particular data request.
+    This method should look at both the constraint expression and any
+    ancillary files for this dataset. The implementation provided here
+    returns the latest time returned by the <tt>get_dataset</tt>...(),
+    <tt>get_das</tt>...() and <tt>get_dds</tt>...() methods and
+    does not currently check the CE.
+
+    @param anc_location A directory to search for ancillary files (in
+    addition to the CWD).
+    @return Time of last modification of the data.
+    @see get_dataset_last_modified_time()
+    @see get_das_last_modified_time()
+    @see get_dds_last_modified_time() */
+time_t
+DODSFilter::get_data_last_modified_time(const string &anc_location) const
+{
+    DBG(cerr << "DODSFilter::get_das_last_modified_time(anc_location="
+        << anc_location << "call faf(both) d_dataset=" << d_dataset
+        << " d_anc_file=" << d_anc_file << endl);
+
+    string dds_name
+    = Ancillary::find_ancillary_file(d_dataset, "dds",
+                          (anc_location == "") ? d_anc_dir : anc_location,
+                          d_anc_file);
+    string das_name
+    = Ancillary::find_ancillary_file(d_dataset, "das",
+                          (anc_location == "") ? d_anc_dir : anc_location,
+                          d_anc_file);
+
+    time_t m = max((das_name != "") ? last_modified_time(das_name) : (time_t)0,
+                   (dds_name != "") ? last_modified_time(dds_name) : (time_t)0);
+    // Note that this is a call to get_dataset_... not get_data_...
+    time_t n = get_dataset_last_modified_time();
+
+    return max(m, n);
+}
+
+/** Get the value of a conditional request's If-Modified-Since header.
+    This value is used to determine if the request should get a full
+    response or a Not Modified (304) response. The time is given in
+    seconds since the Unix epoch (midnight, 1 Jan 1970). If no time was
+    given with the request, this methods returns -1.
+
+    @return If-Modified-Since time from a condition GET request. */
+time_t
+DODSFilter::get_request_if_modified_since() const
+{
+    return d_if_modified_since;
+}
+
+/** The <tt>cache_dir</tt> is used to hold the cached .dds and .das files.
+    By default, this returns an empty string (store cache files in
+    current directory.
+
+    @brief Get the cache directory.
+    @return A string object that contains the cache file directory.  */
+string
+DODSFilter::get_cache_dir() const
+{
+    return d_cache_dir;
+}
+
+/** Set the server's timeout value. A value of zero (the default) means no
+    timeout.
+
+    @param t Server timeout in seconds. Default is zero (no timeout). */
+void
+DODSFilter::set_timeout(int t)
+{
+    d_timeout = t;
+}
+
+/** Get the server's timeout value. */
+int
+DODSFilter::get_timeout() const
+{
+    return d_timeout;
+}
+
+#if FILE_METHODS
+/** Use values of this instance to establish a timeout alarm for the server.
+    If the timeout value is zero, do nothing.
+
+    @todo When the alarm handler is called, two CRLF pairs are dumped to the
+    stream and then an Error object is sent. No attempt is made to write the
+    'correct' MIME headers for an Error object. Instead, a savvy client will
+    know that when an exception is thrown during a deserialize operation, it
+    should scan ahead in the input stream for an Error object. Add this, or a
+    sensible variant once libdap++ supports reliable error delivery. Dumb
+    clients will never get the Error object... */
+
+void
+DODSFilter::establish_timeout(FILE *stream) const
+{
+#ifndef WIN32
+    if (d_timeout > 0) {
+        SignalHandler *sh = SignalHandler::instance();
+        EventHandler *old_eh = sh->register_handler(SIGALRM, new AlarmHandler(stream));
+        delete old_eh;
+        alarm(d_timeout);
+    }
+#endif
+}
+#endif
+
+// FIXME
+void
+DODSFilter::establish_timeout(ostream &stream) const
+{
+#ifndef WIN32
+    if (d_timeout > 0) {
+        SignalHandler *sh = SignalHandler::instance();
+        EventHandler *old_eh = sh->register_handler(SIGALRM, new AlarmHandler(stream));
+        delete old_eh;
+        alarm(d_timeout);
+    }
+#endif
+}
+
+static const char *emessage = "DODS internal server error; usage error. Please report this to the dataset maintainer, or to the opendap-tech at opendap.org mailing list.";
+
+/** This message is printed when the filter program is incorrectly
+    invoked by the dispatch CGI.  This is an error in the server
+    installation or the CGI implementation, so the error message is
+    written to stderr instead of stdout.  A server's stderr messages
+    show up in the httpd log file. In addition, an error object is
+    sent back to the client program telling them that the server is
+    broken.
+
+    @brief Print usage information for a filter program. */
+void
+DODSFilter::print_usage() const
+{
+    // Write a message to the WWW server error log file.
+    ErrMsgT(usage.c_str());
+
+    throw Error(unknown_error, emessage);
+}
+
+/** This function formats and sends to stdout version
+    information from the httpd server, the server dispatch scripts,
+    the DODS core software, and (optionally) the dataset.
+
+    @brief Send version information back to the client program. */
+void
+DODSFilter::send_version_info() const
+{
+    do_version(d_cgi_ver, get_dataset_version());
+}
+
+#if FILE_METHODS
+/** This function formats and prints an ASCII representation of a
+    DAS on stdout.  This has the effect of sending the DAS object
+    back to the client program.
+
+    @brief Transmit a DAS.
+    @param out The output FILE to which the DAS is to be sent.
+    @param das The DAS object to be sent.
+    @param anc_location The directory in which the external DAS file resides.
+    @param with_mime_headers If true (the default) send MIME headers.
+    @return void
+    @see DAS */
+void
+DODSFilter::send_das(FILE *out, DAS &das, const string &anc_location,
+                     bool with_mime_headers) const
+{
+    time_t das_lmt = get_das_last_modified_time(anc_location);
+    if (is_conditional()
+        && das_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(out);
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_text(out, dods_das, d_cgi_ver, x_plain, das_lmt);
+        das.print(out);
+    }
+    fflush(out) ;
+}
+#endif
+
+/** This function formats and prints an ASCII representation of a
+    DAS on stdout.  This has the effect of sending the DAS object
+    back to the client program.
+
+    @brief Transmit a DAS.
+    @param out The output stream to which the DAS is to be sent.
+    @param das The DAS object to be sent.
+    @param anc_location The directory in which the external DAS file resides.
+    @param with_mime_headers If true (the default) send MIME headers.
+    @return void
+    @see DAS */
+void
+DODSFilter::send_das(ostream &out, DAS &das, const string &anc_location,
+                     bool with_mime_headers) const
+{
+    time_t das_lmt = get_das_last_modified_time(anc_location);
+    if (is_conditional()
+        && das_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(out);
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_text(out, dods_das, d_cgi_ver, x_plain, das_lmt);
+        das.print(out);
+    }
+    out << flush ;
+}
+
+void
+DODSFilter::send_das(DAS &das, const string &anc_location,
+                     bool with_mime_headers) const
+{
+    send_das(cout, das, anc_location, with_mime_headers);
+}
+
+#if FILE_METHODS
+/** This function formats and prints an ASCII representation of a
+    DDS on stdout.  When called by a CGI program, this has the
+    effect of sending a DDS object back to the client
+    program. Either an entire DDS or a constrained DDS may be sent.
+
+    @brief Transmit a DDS.
+    @param out The output FILE to which the DAS is to be sent.
+    @param dds The DDS to send back to a client.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param constrained If this argument is true, evaluate the
+    current constraint expression and send the `constrained DDS'
+    back to the client.
+    @param anc_location The directory in which the external DAS file resides.
+    @param with_mime_headers If true (the default) send MIME headers.
+    @return void
+    @see DDS */
+void
+DODSFilter::send_dds(FILE *out, DDS &dds, ConstraintEvaluator &eval,
+                     bool constrained,
+                     const string &anc_location,
+                     bool with_mime_headers) const
+{
+    // If constrained, parse the constraint. Throws Error or InternalErr.
+    if (constrained)
+        eval.parse_constraint(d_ce, dds);
+
+    if (eval.functional_expression())
+        throw Error("Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
+
+    time_t dds_lmt = get_dds_last_modified_time(anc_location);
+    if (is_conditional()
+        && dds_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(out);
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_text(out, dods_dds, d_cgi_ver, x_plain, dds_lmt);
+        if (constrained)
+            dds.print_constrained(out);
+        else
+            dds.print(out);
+    }
+
+    fflush(out) ;
+}
+#endif
+
+/** This function formats and prints an ASCII representation of a
+    DDS on stdout.  When called by a CGI program, this has the
+    effect of sending a DDS object back to the client
+    program. Either an entire DDS or a constrained DDS may be sent.
+
+    @brief Transmit a DDS.
+    @param out The output stream to which the DAS is to be sent.
+    @param dds The DDS to send back to a client.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param constrained If this argument is true, evaluate the
+    current constraint expression and send the `constrained DDS'
+    back to the client.
+    @param anc_location The directory in which the external DAS file resides.
+    @param with_mime_headers If true (the default) send MIME headers.
+    @return void
+    @see DDS */
+void
+DODSFilter::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval,
+                     bool constrained,
+                     const string &anc_location,
+                     bool with_mime_headers) const
+{
+    // If constrained, parse the constraint. Throws Error or InternalErr.
+    if (constrained)
+        eval.parse_constraint(d_ce, dds);
+
+    if (eval.functional_expression())
+        throw Error("Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
+
+    time_t dds_lmt = get_dds_last_modified_time(anc_location);
+    if (is_conditional()
+        && dds_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(out);
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_text(out, dods_dds, d_cgi_ver, x_plain, dds_lmt);
+        if (constrained)
+            dds.print_constrained(out);
+        else
+            dds.print(out);
+    }
+
+    out << flush ;
+}
+
+void
+DODSFilter::send_dds(DDS &dds, ConstraintEvaluator &eval,
+                     bool constrained, const string &anc_location,
+                     bool with_mime_headers) const
+{
+    send_dds(cout, dds, eval, constrained, anc_location, with_mime_headers);
+}
+
+#if FILE_METHODS
+// 'lmt' unused. Should it be used to supply a LMT or removed from the
+// method? jhrg 8/9/05
+void
+DODSFilter::functional_constraint(BaseType &var, DDS &dds,
+                                  ConstraintEvaluator &eval, FILE *out) const
+{
+    fprintf(out, "Dataset {\n");
+    var.print_decl(out, "    ", true, false, true);
+    fprintf(out, "} function_value;\n");
+    fprintf(out, "Data:\n");
+
+    fflush(out);
+
+    XDRFileMarshaller m( out ) ;
+
+    try {
+        // In the following call to serialize, suppress CE evaluation.
+        var.serialize(eval, dds, m, false);
+    }
+    catch (Error &e) {
+        throw;
+    }
+}
+#endif
+
+// 'lmt' unused. Should it be used to supply a LMT or removed from the
+// method? jhrg 8/9/05
+void
+DODSFilter::functional_constraint(BaseType &var, DDS &dds,
+                                  ConstraintEvaluator &eval, ostream &out) const
+{
+    out << "Dataset {\n" ;
+    var.print_decl(out, "    ", true, false, true);
+    out << "} function_value;\n" ;
+    out << "Data:\n" ;
+
+    out << flush ;
+
+    // Grab a stream that encodes using XDR.
+    XDRStreamMarshaller m( out ) ;
+
+    try {
+        // In the following call to serialize, suppress CE evaluation.
+        var.serialize(eval, dds, m, false);
+    }
+    catch (Error &e) {
+        throw;
+    }
+}
+
+#if FILE_METHODS
+void
+DODSFilter::dataset_constraint(DDS & dds, ConstraintEvaluator & eval,
+                               FILE * out, bool ce_eval) const
+{
+    // send constrained DDS
+    dds.print_constrained(out);
+    fprintf(out, "Data:\n");
+    fflush(out);
+
+    // Grab a stream that encodes using XDR.
+    XDRFileMarshaller m( out ) ;
+
+    try {
+        // Send all variables in the current projection (send_p())
+        for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
+            if ((*i)->send_p()) {
+                DBG(cerr << "Sending " << (*i)->name() << endl);
+                (*i)->serialize(eval, dds, m, ce_eval);
+            }
+    }
+    catch (Error & e) {
+        throw;
+    }
+}
+#endif
+
+void
+DODSFilter::dataset_constraint(DDS & dds, ConstraintEvaluator & eval,
+                               ostream &out, bool ce_eval) const
+{
+    // send constrained DDS
+    dds.print_constrained(out);
+    out << "Data:\n" ;
+    out << flush ;
+
+    // Grab a stream that encodes using XDR.
+    XDRStreamMarshaller m( out ) ;
+
+    try {
+        // Send all variables in the current projection (send_p())
+        for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
+            if ((*i)->send_p()) {
+                DBG(cerr << "Sending " << (*i)->name() << endl);
+                (*i)->serialize(eval, dds, m, ce_eval);
+            }
+    }
+    catch (Error & e) {
+        throw;
+    }
+}
+
+void
+DODSFilter::dataset_constraint_ddx(DDS & dds, ConstraintEvaluator & eval,
+                               ostream &out, const string &boundary,
+                               const string &start, bool ce_eval) const
+{
+    // Write the MPM headers for the DDX (text/xml) part of the response
+    set_mime_ddx_boundary(out, boundary, start, dap4_ddx);
+
+    // Make cid
+    uuid_t uu;
+    uuid_generate(uu);
+    char uuid[37];
+    uuid_unparse(uu, &uuid[0]);
+    char domain[256];
+    if (getdomainname(domain, 255) != 0 || strlen(domain) == 0)
+	strncpy(domain, "opendap.org", 255);
+
+    string cid = string(&uuid[0]) + "@" + string(&domain[0]);
+
+    // Send constrained DDX with a data blob reference
+    dds.print_xml(out, true, cid);
+
+    // Write the MPM headers for the data part of the response.
+    set_mime_data_boundary(out, boundary, cid, dap4_data, binary);
+
+    // Grab a stream that encodes using XDR.
+    XDRStreamMarshaller m( out ) ;
+
+    try {
+        // Send all variables in the current projection (send_p())
+        for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
+            if ((*i)->send_p()) {
+                DBG(cerr << "Sending " << (*i)->name() << endl);
+                (*i)->serialize(eval, dds, m, ce_eval);
+            }
+    }
+    catch (Error & e) {
+        throw;
+    }
+}
+
+#if FILE_METHODS
+/** Send the data in the DDS object back to the client program. The data is
+    encoded using a Marshaller, and enclosed in a MIME document which is all sent
+    to \c data_stream. If this is being called from a CGI, \c data_stream is
+    probably \c stdout and writing to it has the effect of sending the
+    response back to the client.
+
+    @brief Transmit data.
+    @param dds A DDS object containing the data to be sent.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param data_stream Write the response to this FILE.
+    @param anc_location A directory to search for ancillary files (in
+    addition to the CWD).  This is used in a call to
+    get_data_last_modified_time().
+    @param with_mime_headers If true, include the MIME headers in the response.
+    Defaults to true.
+    @return void */
+void
+DODSFilter::send_data(DDS & dds, ConstraintEvaluator & eval,
+                      FILE * data_stream, const string & anc_location,
+                      bool with_mime_headers) const
+{
+    // If this is a conditional request and the server should send a 304
+    // response, do that and exit. Otherwise, continue on and send the full
+    // response.
+    time_t data_lmt = get_data_last_modified_time(anc_location);
+    if (is_conditional()
+        && data_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(data_stream);
+        return;
+    }
+    // Set up the alarm.
+    establish_timeout(data_stream);
+    dds.set_timeout(d_timeout);
+
+    eval.parse_constraint(d_ce, dds);   // Throws Error if the ce doesn't
+					// parse.
+
+    dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+    // Start sending the response...
+
+    // Handle *functional* constraint expressions specially
+#if 0
+    if (eval.functional_expression()) {
+        // Get the result and then start sending the headers. This provides a
+        // way to send errors back to the client w/o colliding with the
+        // normal response headers. There's some duplication of code with this
+        // and the else-clause.
+        BaseType *var = eval.eval_function(dds, d_dataset);
+        if (!var)
+            throw Error(unknown_error, "Error calling the CE function.");
+
+#if COMPRESSION_FOR_SERVER3
+        if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver,
+                            (compress) ? deflate : x_plain, data_lmt);
+        fflush(data_stream);
+
+        int childpid;
+        if (compress)
+            data_stream = compressor(data_stream, childpid);
+#endif
+        if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
+
+        fflush(data_stream);
+
+        functional_constraint(*var, dds, eval, data_stream);
+        delete var;
+        var = 0;
+    }
+#endif
+    if (eval.function_clauses()) {
+	DDS *fdds = eval.eval_function_clauses(dds);
+
+        if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
+
+        dataset_constraint(*fdds, eval, data_stream, false);
+	delete fdds;
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
+
+        dataset_constraint(dds, eval, data_stream);
+    }
+
+    fflush(data_stream);
+}
+#endif
+
+/** Send the data in the DDS object back to the client program. The data is
+    encoded using a Marshaller, and enclosed in a MIME document which is all sent
+    to \c data_stream. If this is being called from a CGI, \c data_stream is
+    probably \c stdout and writing to it has the effect of sending the
+    response back to the client.
+
+    @brief Transmit data.
+    @param dds A DDS object containing the data to be sent.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param data_stream Write the response to this stream.
+    @param anc_location A directory to search for ancillary files (in
+    addition to the CWD).  This is used in a call to
+    get_data_last_modified_time().
+    @param with_mime_headers If true, include the MIME headers in the response.
+    Defaults to true.
+    @return void */
+void
+DODSFilter::send_data(DDS & dds, ConstraintEvaluator & eval,
+                      ostream & data_stream, const string & anc_location,
+                      bool with_mime_headers) const
+{
+    // If this is a conditional request and the server should send a 304
+    // response, do that and exit. Otherwise, continue on and send the full
+    // response.
+    time_t data_lmt = get_data_last_modified_time(anc_location);
+    if (is_conditional()
+        && data_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(data_stream);
+        return;
+    }
+    // Set up the alarm.
+    establish_timeout(data_stream);
+    dds.set_timeout(d_timeout);
+
+    eval.parse_constraint(d_ce, dds);   // Throws Error if the ce doesn't
+					// parse.
+
+    dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+    // Start sending the response...
+
+    // Handle *functional* constraint expressions specially
+#if 0
+    if (eval.functional_expression()) {
+        // Get the result and then start sending the headers. This provides a
+        // way to send errors back to the client w/o colliding with the
+        // normal response headers. There's some duplication of code with this
+        // and the else-clause.
+        BaseType *var = eval.eval_function(dds, d_dataset);
+        if (!var)
+            throw Error(unknown_error, "Error calling the CE function.");
+
+       if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
+
+	data_stream << flush ;
+
+        functional_constraint(*var, dds, eval, data_stream);
+        delete var;
+        var = 0;
+    }
+#endif
+    if (eval.function_clauses()) {
+	DDS *fdds = eval.eval_function_clauses(dds);
+        if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
+
+        dataset_constraint(*fdds, eval, data_stream, false);
+	delete fdds;
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_binary(data_stream, dods_data, d_cgi_ver, x_plain, data_lmt);
+
+        dataset_constraint(dds, eval, data_stream);
+    }
+
+    data_stream << flush ;
+}
+
+#if FILE_METHODS
+/** Send the DDX response. The DDX never contains data, instead it holds a
+    reference to a Blob response which is used to get the data values. The
+    DDS and DAS objects are built using code that already exists in the
+    servers.
+
+    @param dds The dataset's DDS \e with attributes in the variables.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param out Destination
+    @param with_mime_headers If true, include the MIME headers in the response.
+    Defaults to true. */
+void
+DODSFilter::send_ddx(DDS &dds, ConstraintEvaluator &eval, FILE *out,
+                     bool with_mime_headers) const
+{
+    // If constrained, parse the constraint. Throws Error or InternalErr.
+    if (!d_ce.empty())
+        eval.parse_constraint(d_ce, dds);
+
+    if (eval.functional_expression())
+        throw Error("Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
+
+    time_t dds_lmt = get_dds_last_modified_time(d_anc_dir);
+
+    // If this is a conditional request and the server should send a 304
+    // response, do that and exit. Otherwise, continue on and send the full
+    // response.
+    if (is_conditional() && dds_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(out);
+        return;
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_text(out, dap4_ddx, d_cgi_ver, x_plain, dds_lmt);
+        dds.print_xml(out, !d_ce.empty(), "");
+    }
+}
+#endif
+
+/** Send the DDX response. The DDX never contains data, instead it holds a
+    reference to a Blob response which is used to get the data values. The
+    DDS and DAS objects are built using code that already exists in the
+    servers.
+
+    @param dds The dataset's DDS \e with attributes in the variables.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param out Destination
+    @param with_mime_headers If true, include the MIME headers in the response.
+    Defaults to true. */
+void
+DODSFilter::send_ddx(DDS &dds, ConstraintEvaluator &eval, ostream &out,
+                     bool with_mime_headers) const
+{
+    // If constrained, parse the constraint. Throws Error or InternalErr.
+    if (!d_ce.empty())
+        eval.parse_constraint(d_ce, dds);
+
+    if (eval.functional_expression())
+        throw Error("Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
+
+    time_t dds_lmt = get_dds_last_modified_time(d_anc_dir);
+
+    // If this is a conditional request and the server should send a 304
+    // response, do that and exit. Otherwise, continue on and send the full
+    // response.
+    if (is_conditional() && dds_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(out);
+        return;
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_text(out, dap4_ddx, d_cgi_ver, x_plain, dds_lmt);
+        dds.print_xml(out, !d_ce.empty(), "");
+    }
+}
+
+/** Send the data in the DDS object back to the client program. The data is
+    encoded using a Marshaller, and enclosed in a MIME document which is all sent
+    to \c data_stream. If this is being called from a CGI, \c data_stream is
+    probably \c stdout and writing to it has the effect of sending the
+    response back to the client.
+
+    @brief Transmit data.
+
+    @param dds A DDS object containing the data to be sent.
+    @param eval A reference to the ConstraintEvaluator to use.
+    @param data_stream Write the response to this stream.
+    @param start
+    @param boundary
+    @param anc_location A directory to search for ancillary files (in
+    addition to the CWD).  This is used in a call to
+    get_data_last_modified_time().
+    @param with_mime_headers If true, include the MIME headers in the response.
+    Defaults to true.
+
+    @return void */
+void
+DODSFilter::send_data_ddx(DDS & dds, ConstraintEvaluator & eval,
+                      ostream & data_stream, const string &start,
+                      const string &boundary, const string & anc_location,
+                      bool with_mime_headers) const
+{
+    // If this is a conditional request and the server should send a 304
+    // response, do that and exit. Otherwise, continue on and send the full
+    // response.
+    time_t data_lmt = get_data_last_modified_time(anc_location);
+    if (is_conditional()
+        && data_lmt <= get_request_if_modified_since()
+        && with_mime_headers) {
+        set_mime_not_modified(data_stream);
+        return;
+    }
+    // Set up the alarm.
+    establish_timeout(data_stream);
+    dds.set_timeout(d_timeout);
+
+    eval.parse_constraint(d_ce, dds);   // Throws Error if the ce doesn't
+					// parse.
+
+    dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+    // Start sending the response...
+
+    // Handle *functional* constraint expressions specially
+#if 0
+    if (eval.functional_expression()) {
+        BaseType *var = eval.eval_function(dds, d_dataset);
+        if (!var)
+            throw Error(unknown_error, "Error calling the CE function.");
+
+        if (with_mime_headers)
+            set_mime_multipart(data_stream, boundary, start, dap4_data_ddx,
+		d_cgi_ver, x_plain, data_lmt);
+	data_stream << flush ;
+	BaseTypeFactory btf;
+	DDS var_dds(&btf, var->name());
+	var->set_send_p(true);
+	var_dds.add_var(var);
+        dataset_constraint_ddx(var_dds, eval, data_stream, boundary, start);
+
+        // functional_constraint_ddx(*var, dds, eval, data_stream, boundary);
+        delete var;
+        var = 0;
+    }
+#endif
+    if (eval.function_clauses()) {
+    	DDS *fdds = eval.eval_function_clauses(dds);
+        if (with_mime_headers)
+            set_mime_multipart(data_stream, boundary, start, dap4_data_ddx,
+        	    d_cgi_ver, x_plain, data_lmt);
+        data_stream << flush ;
+        dataset_constraint(*fdds, eval, data_stream, false);
+    	delete fdds;
+    }
+    else {
+        if (with_mime_headers)
+            set_mime_multipart(data_stream, boundary, start, dap4_data_ddx,
+        	    d_cgi_ver, x_plain, data_lmt);
+        data_stream << flush ;
+        dataset_constraint_ddx(dds, eval, data_stream, boundary, start);
+    }
+
+    data_stream << flush ;
+
+    if (with_mime_headers)
+	data_stream << CRLF << "--" << boundary << "--" << CRLF;
+}
+
+} // namespace libdap
+
diff --git a/DODSFilter.h b/DODSFilter.h
new file mode 100644
index 0000000..294828c
--- /dev/null
+++ b/DODSFilter.h
@@ -0,0 +1,242 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997-1999
+// Please first read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+// jhrg,jimg James Gallagher <jgallagher at gso.uri.edu>
+
+#ifndef _dodsfilter_h
+#define _dodsfilter_h
+
+#include <string>
+
+#ifndef _das_h
+#include "DAS.h"
+#endif
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** When a DODS server receives a request from a DODS client, the
+    server CGI script dispatches the request to one of several
+    ``filter'' programs.  Each filter is responsible for returning a
+    different aspect of the dataset information: one is for data, one
+    is for the dataset DDS, one is for the dataset DAS, and a fourth
+    is for a usage message describing the server itself.  Some
+    installations may have additional optional filters.
+
+    The filter program receives a data request from the dispatch
+    script. It receives its operating parameters from the command
+    line, like any UNIX command, and it returns its output to standard
+    output, which the httpd server packages up into a reply to the
+    client.
+
+    This class contains some common functions for the filter programs
+    used to make up the DODS data servers. The filter programs do not
+    <i>have</i> to be called by a CGI program, but that is the normal
+    mechanism by which they are invoked.
+
+    @todo Add a test to make sure that the required arguments are given.
+    @todo We need to rethink the ancillary file/directory stuff. I don't
+    think it's ever been used...
+
+    @brief Common functions for DODS server filter programs.
+    @author jhrg 8/26/97 */
+
+class DODSFilter
+{
+public:
+    /** Types of responses DODSFilter know about. */
+    enum Response {
+        Unknown_Response,
+        DAS_Response,
+        DDS_Response,
+        DataDDS_Response,
+        DDX_Response,
+        DataDDX_Response,
+        BLOB_Response,
+        Version_Response
+    };
+
+protected:
+    bool d_comp;  // True if the output should be compressed.
+    bool d_bad_options;  // True if the options (argc,argv) are bad.
+    bool d_conditional_request;
+
+    string d_program_name; // Name of the filter program
+    string d_dataset;  // Name of the dataset/database
+    string d_ce;  // Constraint expression
+    string d_cgi_ver;  // Version of CGI script (caller)
+    string d_anc_dir;  // Look here for ancillary files
+    string d_anc_file;  // Use this for ancillary file name
+    string d_cache_dir;  // Use this for cache files
+    string d_url;  // URL minus CE.
+
+    Response d_response; // enum name of the response to generate
+    string d_action;  // string name of the response to generate
+
+    int d_timeout;  // Server timeout after N seconds
+
+    time_t d_anc_das_lmt; // Last modified time of the anc. DAS.
+    time_t d_anc_dds_lmt; // Last modified time of the anc. DDS.
+    time_t d_if_modified_since; // Time from a conditional request.
+
+    void initialize();
+    void initialize(int argc, char *argv[]);
+
+    virtual int process_options(int argc, char *argv[]);
+
+public:
+    /** Make an empty instance. Use the set_*() methods to load with needed
+        values. You must call at least set_dataset_name() or be requesting
+        version information.
+
+        @todo Add methods to provide a way to set all of the parameters
+        this class contains. They can currently only be set using the
+        argc/argv command line parameters. */
+    DODSFilter()
+    {
+        initialize();
+    }
+    DODSFilter(int argc, char *argv[]) throw(Error);
+
+    virtual ~DODSFilter();
+
+    virtual bool is_conditional() const;
+
+    virtual string get_cgi_version() const;
+    virtual void set_cgi_version(string version);
+
+    virtual string get_ce() const;
+    virtual void set_ce(string _ce);
+
+    virtual string get_dataset_name() const;
+    virtual void set_dataset_name(const string _dataset);
+
+    virtual string get_URL() const;
+    virtual void set_URL(const string &url);
+
+    virtual string get_dataset_version() const;
+
+    virtual Response get_response() const;
+    virtual string get_action() const;
+    virtual void set_response(const string &r);
+
+    virtual time_t get_dataset_last_modified_time() const;
+
+    virtual time_t get_das_last_modified_time(const string &anc_location = "") const;
+
+    virtual time_t get_dds_last_modified_time(const string &anc_location = "") const;
+
+    virtual time_t get_data_last_modified_time(const string &anc_location = "") const;
+
+    virtual time_t get_request_if_modified_since() const;
+
+    virtual string get_cache_dir() const;
+
+    void set_timeout(int timeout = 0);
+
+    int get_timeout() const;
+
+    virtual void establish_timeout(ostream &stream) const;
+
+    virtual void print_usage() const;
+
+    virtual void send_version_info() const;
+
+    virtual void send_das(DAS &das, const string &anc_location = "",
+                          bool with_mime_headers = true) const;
+    virtual void send_das(ostream &out, DAS &das, const string &anc_location = "",
+                          bool with_mime_headers = true) const;
+
+    virtual void send_dds(DDS &dds, ConstraintEvaluator &eval,
+                          bool constrained = false,
+                          const string &anc_location = "",
+                          bool with_mime_headers = true) const;
+    virtual void send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval,
+                          bool constrained = false,
+                          const string &anc_location = "",
+                          bool with_mime_headers = true) const;
+    // deprecated
+    virtual void functional_constraint(BaseType &var, DDS &dds,
+                                       ConstraintEvaluator &eval, ostream &out) const;
+
+    virtual void dataset_constraint(DDS &dds, ConstraintEvaluator &eval,
+                                    ostream &out, bool ce_eval = true) const;
+    virtual void dataset_constraint_ddx(DDS & dds, ConstraintEvaluator & eval,
+                                   ostream &out, const string &boundary,
+                                   const string &start,
+                                   bool ce_eval = true) const;
+
+    virtual void send_data(DDS &dds, ConstraintEvaluator &eval,
+                           ostream &data_stream,
+                           const string &anc_location = "",
+                           bool with_mime_headers = true) const;
+    virtual void send_ddx(DDS &dds, ConstraintEvaluator &eval, ostream &out,
+                          bool with_mime_headers = true) const;
+    virtual void send_data_ddx(DDS &dds, ConstraintEvaluator &eval,
+                           ostream &data_stream, const string &start,
+                           const string &boundary,
+                           const string &anc_location = "",
+                           bool with_mime_headers = true) const;
+
+#if FILE_METHODS
+    virtual void establish_timeout(FILE *stream) const;
+    virtual void send_das(FILE *out, DAS &das, const string &anc_location = "",
+                          bool with_mime_headers = true) const;
+    virtual void send_dds(FILE *out, DDS &dds, ConstraintEvaluator &eval,
+                          bool constrained = false,
+                          const string &anc_location = "",
+                          bool with_mime_headers = true) const;
+    // deprecated
+    virtual void functional_constraint(BaseType &var, DDS &dds,
+                                       ConstraintEvaluator &eval, FILE *out) const;
+
+    virtual void dataset_constraint(DDS &dds, ConstraintEvaluator &eval,
+                                    FILE *out, bool ce_eval = true) const;
+    virtual void send_data(DDS &dds, ConstraintEvaluator &eval,
+                           FILE *data_stream,
+                           const string &anc_location = "",
+                           bool with_mime_headers = true) const;
+    virtual void send_ddx(DDS &dds, ConstraintEvaluator &eval, FILE *out,
+                          bool with_mime_headers = true) const;
+#endif
+};
+
+} // namespace libdap
+
+#endif // _dodsfilter_h
diff --git a/DapIndent.cc b/DapIndent.cc
new file mode 100644
index 0000000..6055888
--- /dev/null
+++ b/DapIndent.cc
@@ -0,0 +1,85 @@
+// DapIndent.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+// Methods for the class DapIndent - an indentation class to support
+// debugging and the dump methods.
+
+#include "DapIndent.h"
+
+namespace libdap {
+
+string DapIndent::_indent ;
+
+void
+DapIndent::Indent()
+{
+    _indent += "    " ;
+}
+
+void
+DapIndent::UnIndent()
+{
+    if (_indent.length() == 0)
+        return ;
+    if (_indent.length() == 4)
+        _indent = "" ;
+    else
+        _indent = _indent.substr(0, _indent.length() - 4) ;
+}
+
+void
+DapIndent::Reset()
+{
+    _indent = "" ;
+}
+
+const string &
+DapIndent::GetIndent()
+{
+    return _indent ;
+}
+
+void
+DapIndent::SetIndent(const string &indent)
+{
+    _indent = indent ;
+}
+
+ostream &
+DapIndent::LMarg(ostream &strm)
+{
+    strm << _indent ;
+    return strm ;
+}
+
+} // namespace libdap
+
diff --git a/DapIndent.h b/DapIndent.h
new file mode 100644
index 0000000..b19c7e8
--- /dev/null
+++ b/DapIndent.h
@@ -0,0 +1,67 @@
+// DapIndent.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+/** @brief indentation to help with dump methods and debugging
+ */
+
+#ifndef I_DapIndent_h
+#define I_DapIndent_h 1
+
+#include <string>
+#include <iostream>
+
+using std::string ;
+using std::ostream ;
+
+namespace libdap
+{
+
+/** @brief class with static methods to help with indentation of debug
+ * information.
+ */
+class DapIndent
+{
+private:
+    static string  _indent ;
+public:
+    static void   Indent() ;
+    static void   UnIndent() ;
+    static void   Reset() ;
+    static const string & GetIndent() ;
+    static void   SetIndent(const string &indent) ;
+    static ostream &  LMarg(ostream &strm) ;
+} ;
+
+} // namespace libdap
+
+#endif // I_DapIndent_h
+
diff --git a/DapObj.h b/DapObj.h
new file mode 100644
index 0000000..91178a7
--- /dev/null
+++ b/DapObj.h
@@ -0,0 +1,110 @@
+// DapObj.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+/** @brief top level DAP object to house generic methods
+ */
+
+#ifndef A_DapObj_h
+#define A_DapObj_h 1
+
+#include <iostream>
+
+using std::ostream ;
+using std::endl ;
+
+#include "DapIndent.h"
+
+namespace libdap
+{
+
+/** @brief libdap base object for common functionality of libdap objects
+ *
+ * A base object for any libdap objects to use. Provides simple
+ * methods for dumping the contents of the object.
+ */
+
+class DapObj
+{
+public:
+    virtual  ~DapObj()
+    {}
+
+    /** @brief dump the contents of this object to the specified ostream
+     *
+     * This method is implemented by all derived classes to dump their
+     * contents, in other words, any state they might have, private variables,
+     * etc...
+     *
+     * The inline function below can be used to dump the contents of an
+     * OPeNDAOObj object. For example, the object Animal is derived from
+     * DapObj. A user could do the following:
+     *
+     * Animal *a = new dog( "Sparky" ) ;
+     * cout << a << endl ;
+     *
+     * And the dump method for dog could display the name passed into the
+     * constructor, the (this) pointer of the object, etc...
+     *
+     * @param strm C++ i/o stream to dump the object to
+     */
+    virtual void dump(ostream &strm) const = 0 ;
+} ;
+
+} // namespace libdap
+
+/** @brief dump the contents of the specified object to the specified ostream
+ *
+ * This inline method uses the dump method of the DapObj instance passed
+ * to it. This allows a user to dump the contents of an object instead of just
+ * getting the pointer value of the object.
+ *
+ * For example, the object Animal is derived from DapObj. A user could
+ * do the following:
+ *
+ * Animal *a = new dog( "Sparky" ) ;
+ * cout << a << endl ;
+ *
+ * And the dump method for dog could display the name passed into the
+ * constructor, the (this) pointer of the object, etc...
+ *
+ * @param strm C++ i/o stream to dump the object to
+ * @param obj The DapObj to dump
+ */
+inline ostream &
+operator<<(ostream &strm, const libdap::DapObj &obj)
+{
+    obj.dump(strm) ;
+    return strm ;
+}
+
+#endif // A_DapObj_h
+
diff --git a/DataDDS.cc b/DataDDS.cc
new file mode 100644
index 0000000..c113632
--- /dev/null
+++ b/DataDDS.cc
@@ -0,0 +1,172 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+//
+// jhrg 9/19/97
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: DataDDS.cc 17856 2008-02-02 21:25:59Z pwest $"
+    };
+
+
+#include <iostream>
+#include <iomanip>
+#include <sstream>
+#include <string>
+
+#include "DataDDS.h"
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+// private
+
+/** Parse the version string. A string that does not parse causes the
+    version to default to 0.0. This is better than throwing an Error since
+    this method is called from a constructor. */
+void
+DataDDS::m_version_string_to_numbers()
+{
+    string num = d_server_version.substr(d_server_version.find('/') + 1);
+
+    if (!num.empty() && num.find('.') != string::npos) {
+        istringstream iss(num);
+        char c;
+
+        iss >> d_server_version_major;
+        iss >> c;               // This reads the `.' in the version string
+        iss >> d_server_version_minor;
+
+        // Did it parse?
+        if (!(c == '.' && d_server_version_major > 0
+              && d_server_version_minor > 0)) {
+
+            d_server_version_major = 0;
+            d_server_version_minor = 0;
+        }
+    }
+    else {
+        d_server_version_major = 0;
+        d_server_version_minor = 0;
+    }
+
+    DBG(cerr << "Server version: " << d_server_version_major << "." \
+        << d_server_version_minor << endl);
+}
+
+/** Parse the protocol string. A string that does not parse causes the
+    version to default to 2.0. This is better than throwing an Error since
+    this method is called from a constructor. */
+void
+DataDDS::m_protocol_string_to_numbers()
+{
+
+    if (!d_protocol_version.empty() && d_protocol_version.find('.')
+        != string::npos) {
+        istringstream iss(d_protocol_version);
+        char c;
+
+        iss >> d_server_protocol_major;
+        iss >> c;               // This reads the `.' in the version string
+        iss >> d_server_protocol_minor;
+
+        // Did it parse?
+        if (!(c == '.' && d_server_protocol_major > 0)) {
+            d_server_protocol_major = 2;
+            d_server_protocol_minor = 0;
+        }
+    }
+    else {
+        d_server_protocol_major = 2;
+        d_server_protocol_minor = 0;
+    }
+
+    DBG(cerr << "Server version: " << d_server_version_major << "." \
+        << d_server_version_minor << endl);
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and then calls parent dump
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+DataDDS::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "DataDDS::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    DDS::dump(strm) ;
+    strm << DapIndent::LMarg << "server version: " << d_server_version
+         << endl ;
+    strm << DapIndent::LMarg << "version major: " << d_server_version_major
+         << endl ;
+    strm << DapIndent::LMarg << "version minor: " << d_server_version_minor
+         << endl ;
+    strm << DapIndent::LMarg << "protocol version: " << d_protocol_version
+         << endl ;
+    strm << DapIndent::LMarg << "protocol major: " << d_server_protocol_major
+         << endl ;
+    strm << DapIndent::LMarg << "protocol minor: " << d_server_protocol_minor
+         << endl ;
+    DapIndent::UnIndent() ;
+}
+
+// public
+
+/** @brief Make an instance of DataDDS
+    A DataDDS instance is a DDS with aditional information about the version
+    of the server from which the data came.
+    @param factory Use this BaseTypeFactory to instantiate the variables.
+    Caller must free; can also be set using the set_factory() method. Never
+    delete until just before deleting the DDS istelf unless you intend to
+    replace the factory with a new instance.
+    @param n The name of the dataset. Can also be set using the
+    set_dataset_name() method.
+    @param v The server version.
+    @param p The protocol version. */
+
+DataDDS::DataDDS(BaseTypeFactory *factory, const string &n, const string &v,
+                 const string &p)
+        : DDS(factory, n), d_server_version(v), d_protocol_version(p)
+{
+    m_version_string_to_numbers();
+    m_protocol_string_to_numbers();
+}
+
+} // namespace libdap
+
diff --git a/DataDDS.h b/DataDDS.h
new file mode 100644
index 0000000..01062ad
--- /dev/null
+++ b/DataDDS.h
@@ -0,0 +1,147 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Specialize DDS for returned data. This currently means adding version
+// information about the source of the data. Was it from a version 1, 2 or
+// later server?
+//
+// jhrg 9/19/97
+
+#ifndef _datadds_h
+#define _datadds_h 1
+
+#include <iostream>
+#include <string>
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+namespace libdap
+{
+
+/** This class adds some useful state information to the DDS
+    structure.  It is for use on the client side of the connection.
+
+    @note Make sure to pass a valid pointer to the DDS constructor or use
+    the set_factory() method before actually using the DDS. Also make sure
+    that the Factory's lifetime thereafter is the same as the DDS's. Never
+    delete the factory until you're done using the DDS.
+
+    @note Update: I removed the DEFAULT_BASETYPE_FACTORY switch because it
+    caused more confusion than it avoided. See Trac #130.
+
+    @note The compile-time symbol DEFAULT_BASETYPE_FACTORY controls whether
+    the old (3.4 and earlier) DDS and DataDDS constructors are supported.
+    These constructors now use a default factory class (BaseTypeFactory,
+    implemented by this library) to instantiate Byte, ..., Grid variables. To
+    use the default ctor in your code you must also define this symbol. If
+    you \e do choose to define this and fail to provide a specialization of
+    BaseTypeFactory when your software needs one, you code may not link or
+    may fail at run time. In addition to the older ctors for DDS and DataDDS,
+    defining the symbol also makes some of the older methods in Connect
+    available (because those methods require the older DDS and DataDDS ctors.
+
+    @brief Holds a DAP2 DDS.
+    @see Connect
+    */
+
+class DataDDS : public DDS
+{
+private:
+    string d_server_version;
+    int d_server_version_major;
+    int d_server_version_minor;
+
+    string d_protocol_version;
+    int d_server_protocol_major;
+    int d_server_protocol_minor;
+
+    void m_version_string_to_numbers();
+    void m_protocol_string_to_numbers();
+
+public:
+    DataDDS(BaseTypeFactory *factory, const string &n = "",
+            const string &v = "", const string &p = "");
+    // #ifdef DEFAULT_BASETYPE_FACTORY
+    // DataDDS(const string &n = "", const string &v = "");
+    // #endif
+    virtual ~DataDDS()
+    {}
+
+    /** Sets the version string.  This typically looks something like:
+    <tt>DODS/2.15</tt>, where ``2'' is the major version number, and ``15''
+    the minor number. */
+    void set_version(const string &v)
+    {
+        d_server_version = v;
+        m_version_string_to_numbers();
+    }
+    /** @brief Get the server version string, unparsed. */
+    string get_version() const
+    {
+        return d_server_version;
+    }
+    /** @brief Returns the major version number. */
+    int get_version_major() const
+    {
+        return d_server_version_major;
+    }
+    /** @brief Returns the minor version number. */
+    int get_version_minor() const
+    {
+        return d_server_version_minor;
+    }
+
+    void set_protocol(const string &p)
+    {
+        d_protocol_version = p;
+        m_protocol_string_to_numbers();
+    }
+    string get_protocol() const
+    {
+        return d_protocol_version;
+    }
+    int get_protocol_major() const
+    {
+        return d_server_protocol_major;
+    }
+    int get_protocol_minor() const
+    {
+        return d_server_protocol_minor;
+    }
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _datadds_h
diff --git a/EncodingType.h b/EncodingType.h
new file mode 100644
index 0000000..362a3f6
--- /dev/null
+++ b/EncodingType.h
@@ -0,0 +1,58 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _encodingtype_h
+#define _encodingtype_h
+
+namespace libdap
+{
+
+/** libdap understands two types of encoding: x-plain and deflate, which
+    correspond to plain uncompressed data and data compressed with zlib's LZW
+    algorithm respectively.
+
+    <code>
+     enum EncodingType {
+       unknown_enc,
+       deflate,
+       x_plain,
+       gzip,
+       binary
+     };
+    </code>
+
+    @brief The type of encoding used on the current stream. */
+
+enum EncodingType {
+    unknown_enc,
+    deflate,
+    x_plain,
+    gzip,
+    binary
+};
+
+} // namespace libdap
+
+#endif
diff --git a/Error.cc b/Error.cc
new file mode 100644
index 0000000..6179ee0
--- /dev/null
+++ b/Error.cc
@@ -0,0 +1,293 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the Error class.
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: Error.cc 18940 2008-06-25 19:22:37Z jimg $"
+    };
+
+#include <cstdio>
+#include <cassert>
+
+#include "Error.h"
+#include "parser.h"
+#include "InternalErr.h"
+#include "debug.h"
+
+using namespace std;
+
+// Glue routines declared in Error.lex
+extern void Error_switch_to_buffer(void *new_buffer);
+extern void Error_delete_buffer(void * buffer);
+extern void *Error_buffer(FILE *fp);
+
+extern void Errorrestart(FILE *yyin); // defined in Error.tab.c
+extern int Errorparse(void *arg);
+
+namespace libdap {
+
+// There are two entries for 'cannot read file' because of an error made 
+// when the message was first added to this class. 
+static const char *err_messages[] = {
+    "Undefined error",
+    "Unknown error",
+    "Internal error",
+    "No such file",
+    "No such variable",
+    "Malformed expression",
+    "No authorization",
+    "Cannot read file",
+    "Cannot read file"
+};
+
+/** Specializations of Error should use this to set the error code and
+    message. */
+Error::Error() : _error_code(undefined_error), _error_message("")
+{}
+
+/** Create an instance with a specific code and message string. This ctor
+    provides a way to to use any code and string you'd like. The code can be
+    one of the standard codes or it may be specific to your server. Thus a
+    client which can tell it's dealing with a specific type of server can use
+    the code accordingly. In general, clients simply show the error message
+    to users or write it to a log file.
+
+    @param ec The error code
+    @param msg The error message string. */
+Error::Error(ErrorCode ec, string msg)
+        : _error_code(ec), _error_message(msg)
+{}
+
+/** Create an instance with a specific message. The error code is set to \c
+    unknown_error.
+
+    @param msg The error message.
+    @see ErrorCode */
+Error::Error(string msg)
+        : _error_code(unknown_error), _error_message(msg)
+{}
+
+Error::Error(const Error &copy_from)
+        : _error_code(copy_from._error_code),
+        _error_message(copy_from._error_message)
+{
+}
+
+Error::~Error()
+{
+}
+
+Error &
+Error::operator=(const Error &rhs)
+{
+    assert(OK());
+
+    if (&rhs == this)  // are they identical?
+        return *this;
+    else {
+        _error_code = rhs._error_code;
+        _error_message = rhs._error_message;
+
+        assert(this->OK());
+
+        return *this;
+    }
+}
+
+/** Use this function to determine whether an Error object is
+    valid.  To be a valid, an Error object must either be: 1)
+    empty or contain a message and a code.
+
+    @brief Is the Error object valid?
+    @return TRUE if the object is valid, FALSE otherwise. */
+bool
+Error::OK() const
+{
+    // The object is empty - users cannot make these, but this class can!
+    bool empty = ((_error_code == undefined_error)
+                  && (_error_message.empty()));
+
+    // Just a message - the program part is null.
+    bool message = ((_error_code != undefined_error)
+                    && (!_error_message.empty()));
+
+    DBG(cerr << "empty: " << empty << ", message: " << message << endl);
+    return empty || message;
+}
+
+/** Given an input stream (FILE *) <tt>fp</tt>, parse an Error object from
+    stream. Values for fields of the Error object are parsed and \c this is
+    set accordingly. This is how a client program receives an error object
+    from a server.
+
+    @brief Parse an Error object.
+    @param fp A valid file pointer to an input stream.
+    @return TRUE if no error was detected, FALSE otherwise.  */
+bool
+Error::parse(FILE *fp)
+{
+    if (!fp)
+        throw InternalErr(__FILE__, __LINE__, "Null input stream");
+
+    void *buffer = Error_buffer(fp);
+    Error_switch_to_buffer(buffer);
+
+    parser_arg arg(this);
+
+    bool status;
+    try {
+        status = Errorparse((void *) & arg) == 0;
+        Error_delete_buffer(buffer);
+    }
+    catch (Error &e) {
+        Error_delete_buffer(buffer);
+        throw InternalErr(__FILE__, __LINE__, e.get_error_message());
+    }
+
+    // STATUS is the result of the parser function; if a recoverable error
+    // was found it will be true but arg.status() will be false.
+    // I'm throwing an InternalErr here since Error objects are generated by
+    // the core; they should always parse! 9/21/2000 jhrg
+    if (!status || !arg.status())
+        throw InternalErr(__FILE__, __LINE__, "Error parsing error object!");
+    else
+        return OK();  // Check object consistency
+}
+
+
+/** Creates a printable representation of the Error object. It is suitable
+    for framing, and also for printing and sending over a network.
+
+    The printed representation produced by this function can be parsed by the
+    parse() member function. Thus parse and print form a symmetrical pair
+    that can be used to send and receive an Error object over the network in
+    a MIME document.
+
+    @param out A pointer to the output stream on which the Error object is to
+    be rendered. */
+void
+Error::print(FILE *out) const
+{
+    assert(OK());
+
+    fprintf(out, "Error {\n") ;
+
+    fprintf(out, "    code = %d;\n", static_cast<int>(_error_code)) ;
+
+    // If the error message is wrapped in double quotes, print it, else, add
+    // wrapping double quotes.
+    if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
+        fprintf(out, "    message = %s;\n", _error_message.c_str()) ;
+    else
+        fprintf(out, "    message = \"%s\";\n", _error_message.c_str()) ;
+
+    fprintf(out, "};\n") ;
+}
+
+/** Creates a printable representation of the Error object. It is suitable
+    for framing, and also for printing and sending over a network.
+
+    The printed representation produced by this function can be parsed by the
+    parse() member function. Thus parse and print form a symmetrical pair
+    that can be used to send and receive an Error object over the network in
+    a MIME document.
+
+    @param strm A reference to the output stream on which the Error object is to
+    be rendered. */
+void
+Error::print(ostream &strm) const
+{
+    assert(OK());
+
+    strm << "Error {\n" ;
+
+    strm << "    code = " << static_cast<int>(_error_code) << ";\n" ;
+
+    // If the error message is wrapped in double quotes, print it, else, add
+    // wrapping double quotes.
+    if (*_error_message.begin() == '"' && *(_error_message.end() - 1) == '"')
+        strm << "    message = " << _error_message.c_str() << ";\n" ;
+    else
+        strm << "    message = \"" << _error_message.c_str() << "\";\n"  ;
+
+    strm << "};\n" ;
+}
+
+/** Get the ErrorCode for this instance. */
+ErrorCode
+Error::get_error_code() const
+{
+    assert(OK());
+    return _error_code;
+}
+
+/** Set the ErrorCode. If the current error message has not been set, use \e
+    ec to set the error message. The resulting error message string is the
+    same as the ErrorCode name. If \e ec is not within the range of values
+    for an OPeNDAP ErrorCode, the error message is left unchanged.
+
+    @param ec The new ErrorCode value. */
+void
+Error::set_error_code(ErrorCode ec)
+{
+    _error_code = ec;
+    // Added check to make sure that err_messages is not accessed beyond its
+    // bounds. 02/02/04 jhrg
+    if (_error_message.empty()
+        && ec > undefined_error && ec <= cannot_read_file) {
+        _error_message = err_messages[ec - undefined_error];
+    }
+    else {
+        _error_message = err_messages[0];
+    }
+}
+
+/** Return the current error message. */
+string
+Error::get_error_message() const
+{
+    assert(OK());
+
+    return string(_error_message);
+}
+
+/** Set the error message. */
+void
+Error::set_error_message(string msg)
+{
+    _error_message = msg;
+}
+
+} // namespace libdap
diff --git a/Error.h b/Error.h
new file mode 100644
index 0000000..d231aab
--- /dev/null
+++ b/Error.h
@@ -0,0 +1,119 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999,2000
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the Error class
+//
+// jhrg 4/23/96
+
+#ifndef _error_h
+#define _error_h
+
+#include <cstdio>  // For FILE *
+#include <iostream>
+#include <string>
+
+using std::cout;
+using std::string;
+using std::ostream;
+
+namespace libdap
+{
+
+/** The most common errors within DAP2 have special codes so that they
+    can be spotted easily by the client software. Any error
+    without a matching code gets the <tt>unknown_error</tt> code.
+
+    @brief An enumerated type for common errors.  */
+typedef int ErrorCode; //using standard errno+netCDF error codes from server
+
+/** @name Internal DAP errors */
+//@{
+#define    undefined_error   1000 ///< Undefined error code
+#define    unknown_error     1001 ///< Unknown error
+#define    internal_error    1002 ///< Internal server error
+#define    no_such_file      1003
+#define    no_such_variable  1004
+#define    malformed_expr    1005
+#define    no_authorization  1006
+#define    cannot_read_file  1007
+#define    dummy_message     1008 // Dumplicate of 1007; see Error.cc
+
+//@}
+
+/** The Error class is used to transport error information from the server to
+    the client within libdap. This class is also the base class for all the
+    errors thrown by methods in the DAP, so catching Error will catch all DAP
+    throws. Errors consist of an error code and a string. The code can be
+    used to quickly distinguish between certain common errors while the
+    string is used to convey information about the error to the user. The
+    error code should never be displayed to the user.
+
+    This class is used on both clients and servers. The \e print() and \e
+    parse() methods are used to send the object back and forth.
+
+    @note A past version of this class supported the notion of an error
+    correcting program (Tcl, Java, ...) that could be sent from the server to
+    the client to help users correct the error and resubmit the request. This
+    never worked well in practice and that feature of the class is deprecated.
+
+    @brief A class for error processing.
+    @author jhrg */
+
+class Error
+{
+protected:
+    ErrorCode _error_code;
+    string _error_message;
+
+public:
+    Error(ErrorCode ec, string msg);
+    Error(string msg);
+    Error();
+
+    Error(const Error &copy_from);
+
+    virtual ~Error();
+
+    Error &operator=(const Error &rhs);
+
+    bool OK() const;
+    bool parse(FILE *fp);
+    void print(FILE *out) const;
+    void print(ostream &out) const;
+    ErrorCode get_error_code() const;
+    string get_error_message() const;
+    void set_error_code(ErrorCode ec = undefined_error);
+    void set_error_message(string msg = "");
+};
+
+} // namespace libdap
+
+#endif // _error_h
diff --git a/Error.lex b/Error.lex
new file mode 100644
index 0000000..fc660f7
--- /dev/null
+++ b/Error.lex
@@ -0,0 +1,165 @@
+
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-1996,1998,1999
+*/ 
+
+/*
+  Scanner for the Error object. It recognizes the five keywords in the
+  persistent representation of the Error object plus some syntactic sugar
+  (`=', `{', ...). The object's persistent representation uses a keyword =
+  value notation, where the values are quoted strings or integers.
+
+  The scanner is not reentrant, but can share name spaces with other
+  scanners. It must be processed by GNU's flex scanner generator.
+*/
+
+%{
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: Error.lex 18315 2008-03-03 20:14:44Z jimg $"};
+
+#include <cstdlib>
+#include <cassert>
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_NO_UNPUT
+#define YY_DECL int Errorlex YY_PROTO(( void ))
+
+#include "Error.tab.hh"
+
+int error_line_num = 1;
+static int start_line;		/* used in quote and comment error handlers */
+
+void store_integer();
+void store_string();
+
+%}
+    
+%option noyywrap
+%option prefix="Error"
+%option outfile="lex.Error.cc"
+%x quote
+%x comment
+
+SCAN_INT		[0-9]+
+
+SCAN_ERROR		error|Error|ERROR
+SCAN_CODE		code|Code|CODE
+SCAN_MSG		message|Message|MESSAGE
+SCAN_PTYPE		program_type|ProgramType|PROGRAM_TYPE|Program_Type
+SCAN_PROGRAM	program|Program|PROGRAM
+
+NEVER   [^a-zA-Z0-9_/.+\-{}:;,]
+
+%%
+
+
+{SCAN_ERROR}	store_string(); return SCAN_ERROR;
+
+{SCAN_CODE}	store_string(); return SCAN_CODE;
+{SCAN_MSG}	store_string(); return SCAN_MSG;
+
+{SCAN_INT}	store_integer(); return SCAN_INT;
+
+"{" 	    	return (int)*yytext;
+"}" 	    	return (int)*yytext;
+";" 	    	return (int)*yytext;
+"="		return (int)*yytext;
+
+[ \t]+
+\n	    	    	++error_line_num;
+<INITIAL><<EOF>>    	yy_init = 1; error_line_num = 1; yyterminate();
+
+"#"	    	    	BEGIN(comment);
+<comment>[^\n]*
+<comment>\n		++error_line_num; BEGIN(INITIAL);
+<comment><<EOF>>        yy_init = 1; error_line_num = 1; yyterminate();
+
+\"			BEGIN(quote); start_line = error_line_num; yymore();
+<quote>[^"\n\\]*	yymore();
+<quote>[^"\n\\]*\n	yymore(); ++error_line_num;
+<quote>\\.		yymore();
+<quote>\"		{ 
+    			  BEGIN(INITIAL); 
+			  store_string();
+			  return SCAN_STR;
+                        }
+<quote><<EOF>>		{
+                          char msg[256];
+			  sprintf(msg,
+				  "Unterminated quote (starts on line %d)\n",
+				  start_line);
+			  YY_FATAL_ERROR(msg);
+                        }
+
+{NEVER}                 {
+                          if (yytext) {	/* suppress msgs about `' chars */
+                            fprintf(stderr, "Character `%c' is not", *yytext);
+                            fprintf(stderr, " allowed (except within");
+			    fprintf(stderr, " quotes) and has been ignored\n");
+			  }
+			}
+%%
+
+// These three glue routines enable DDS to reclaim the memory used to parse a
+// DDS off the wire. They are here because this file can see the YY_*
+// symbols; the file DDS.cc cannot.
+
+void *
+Error_buffer(FILE *fp)
+{
+    return (void *)Error_create_buffer(fp, YY_BUF_SIZE);
+}
+
+void
+Error_switch_to_buffer(void *buf)
+{
+    Error_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+Error_delete_buffer(void *buf)
+{
+    Error_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+store_integer()
+{
+    Errorlval.integer = atoi(yytext);
+}
+
+void
+store_string()
+{
+    Errorlval.string = yytext;
+}
+
diff --git a/Error.tab.cc b/Error.tab.cc
new file mode 100644
index 0000000..f2201c7
--- /dev/null
+++ b/Error.tab.cc
@@ -0,0 +1,1633 @@
+/* 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 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse Errorparse
+#define yylex   Errorlex
+#define yyerror Errorerror
+#define yylval  Errorlval
+#define yychar  Errorchar
+#define yydebug Errordebug
+#define yynerrs Errornerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_INT = 258,
+     SCAN_STR = 259,
+     SCAN_ERROR = 260,
+     SCAN_CODE = 261,
+     SCAN_MSG = 262
+   };
+#endif
+/* Tokens.  */
+#define SCAN_INT 258
+#define SCAN_STR 259
+#define SCAN_ERROR 260
+#define SCAN_CODE 261
+#define SCAN_MSG 262
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 32 "Error.y"
+
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: Error.y 18315 2008-03-03 20:14:44Z jimg $"};
+
+#include <iostream>
+
+#include "Error.h"
+
+#include "parser.h"
+#include "debug.h"
+#include "util.h"
+
+using namespace std;
+using namespace libdap;
+
+// These macros are used to access the `arguments' passed to the parser. A
+// pointer to an error object and a pointer to an integer status variable are
+// passed in to the parser within a structure (which itself is passed as a
+// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *. 
+
+#define ERROR_OBJ(arg) ((Error *)((parser_arg *)(arg))->_object)
+#define STATUS(arg) ((parser_arg *)(arg))->_status
+
+#define YYPARSE_PARAM arg
+
+extern int error_line_num;	// defined in Error.lex
+
+int Errorlex();			// the scanner
+void Errorerror(char *s);	// gotta love automatically generated names...
+
+
+
+/* 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
+#line 66 "Error.y"
+{
+#ifdef __SUNPRO_CC
+    int boolean;
+#else
+    bool boolean;
+#endif
+    int integer;
+    char *string;
+}
+/* Line 187 of yacc.c.  */
+#line 162 "Error.tab.cc"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 175 "Error.tab.cc"
+
+#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__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# 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 YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* 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)) \
+      + 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  4
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   16
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  12
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  7
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  8
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  20
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   262
+
+#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,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    10,
+       2,    11,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     8,     2,     9,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     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
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     9,    11,    14,    16,    21,    22
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      13,     0,    -1,     5,     8,    14,     9,    10,    -1,    15,
+      -1,    16,    17,    -1,    16,    -1,     6,    11,     3,    10,
+      -1,    -1,     7,    11,     4,    18,    10,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint8 yyrline[] =
+{
+       0,    94,    94,    97,   100,   101,   104,   112,   111
+};
+#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", "SCAN_INT", "SCAN_STR", "SCAN_ERROR",
+  "SCAN_CODE", "SCAN_MSG", "'{'", "'}'", "';'", "'='", "$accept",
+  "error_object", "contents", "description", "code", "message", "@1", 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,   123,   125,
+      59,    61
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    12,    13,    14,    15,    15,    16,    18,    17
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     5,     1,     2,     1,     4,     0,     5
+};
+
+/* 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[] =
+{
+       0,     0,     0,     0,     1,     0,     0,     3,     5,     0,
+       0,     0,     4,     0,     2,     0,     6,     7,     0,     8
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     2,     6,     7,     8,    12,    18
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -8
+static const yytype_int8 yypact[] =
+{
+      -5,    -7,     2,    -3,    -8,    -6,    -2,    -8,    -1,     1,
+       0,     3,    -8,     5,    -8,     4,    -8,    -8,     6,    -8
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+      -8,    -8,    -8,    -8,    -8,    -8,    -8
+};
+
+/* 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[] =
+{
+       1,     3,     4,     5,    13,     9,    11,    10,    17,     0,
+      14,     0,     0,     0,    15,    16,    19
+};
+
+static const yytype_int8 yycheck[] =
+{
+       5,     8,     0,     6,     3,    11,     7,     9,     4,    -1,
+      10,    -1,    -1,    -1,    11,    10,    10
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     5,    13,     8,     0,     6,    14,    15,    16,    11,
+       9,     7,    17,     3,    10,    11,    10,     4,    18,    10
+};
+
+#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 (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 (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#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); \
+      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)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# 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)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  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, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#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)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} 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)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  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 (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| 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 (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  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;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* 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;
+
+  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;
+
+
+	/* 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),
+
+		    &yystacksize);
+
+	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);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + 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;
+
+  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];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 94 "Error.y"
+    { (yyval.boolean) = (yyvsp[(3) - (5)].boolean); STATUS(arg) = (yyvsp[(3) - (5)].boolean); ;}
+    break;
+
+  case 3:
+#line 97 "Error.y"
+    { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;}
+    break;
+
+  case 4:
+#line 100 "Error.y"
+    { (yyval.boolean) = (yyvsp[(1) - (2)].boolean) && (yyvsp[(2) - (2)].boolean); ;}
+    break;
+
+  case 5:
+#line 101 "Error.y"
+    { (yyval.boolean) = (yyvsp[(1) - (1)].boolean); ;}
+    break;
+
+  case 6:
+#line 105 "Error.y"
+    { 
+		    ERROR_OBJ(arg)->set_error_code((ErrorCode)(yyvsp[(3) - (4)].integer));
+		    (yyval.boolean) = true; 
+		;}
+    break;
+
+  case 7:
+#line 112 "Error.y"
+    { 
+		    ERROR_OBJ(arg)->set_error_message((yyvsp[(3) - (3)].string));
+		;}
+    break;
+
+  case 8:
+#line 116 "Error.y"
+    {
+		    (yyval.boolean) = true;
+		;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1406 "Error.tab.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* 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 (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 (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  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);
+	  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;
+
+  /* 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;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* 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 (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* 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);
+      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);
+}
+
+
+#line 121 "Error.y"
+
+
+void
+Errorerror(char *s)
+{
+  string msg = s;
+  msg += " line: ";
+  append_long_to_string(error_line_num, 10, msg);
+  msg += "\n";
+
+  throw Error(unknown_error, msg);
+}
+
+
diff --git a/Error.tab.hh b/Error.tab.hh
new file mode 100644
index 0000000..5bd0731
--- /dev/null
+++ b/Error.tab.hh
@@ -0,0 +1,80 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface 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.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_INT = 258,
+     SCAN_STR = 259,
+     SCAN_ERROR = 260,
+     SCAN_CODE = 261,
+     SCAN_MSG = 262
+   };
+#endif
+/* Tokens.  */
+#define SCAN_INT 258
+#define SCAN_STR 259
+#define SCAN_ERROR 260
+#define SCAN_CODE 261
+#define SCAN_MSG 262
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 66 "Error.y"
+{
+#ifdef __SUNPRO_CC
+    int boolean;
+#else
+    bool boolean;
+#endif
+    int integer;
+    char *string;
+}
+/* Line 1489 of yacc.c.  */
+#line 73 "Error.tab.hh"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE Errorlval;
+
diff --git a/Error.y b/Error.y
new file mode 100644
index 0000000..2e381a1
--- /dev/null
+++ b/Error.y
@@ -0,0 +1,133 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+%{
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: Error.y 18315 2008-03-03 20:14:44Z jimg $"};
+
+#include <iostream>
+
+#include "Error.h"
+
+#include "parser.h"
+#include "debug.h"
+#include "util.h"
+
+using namespace std;
+using namespace libdap;
+
+// These macros are used to access the `arguments' passed to the parser. A
+// pointer to an error object and a pointer to an integer status variable are
+// passed in to the parser within a structure (which itself is passed as a
+// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *. 
+
+#define ERROR_OBJ(arg) ((Error *)((parser_arg *)(arg))->_object)
+#define STATUS(arg) ((parser_arg *)(arg))->_status
+
+#define YYPARSE_PARAM arg
+
+extern int error_line_num;	// defined in Error.lex
+
+int Errorlex();			// the scanner
+void Errorerror(char *s);	// gotta love automatically generated names...
+
+%}
+
+%union {
+#ifdef __SUNPRO_CC
+    int boolean;
+#else
+    bool boolean;
+#endif
+    int integer;
+    char *string;
+}
+
+%token <integer>	SCAN_INT
+%token <string>		SCAN_STR
+
+%token <integer>	SCAN_ERROR
+%token <integer>	SCAN_CODE
+%token <string>		SCAN_MSG
+
+%type <boolean> error_object contents description code message
+
+%%
+
+// The parser is called through a function named ERRORPARSE which takes a
+// pointer to a structure and returns a boolean. The structure contains a
+// pointer to an Error object which is empty and an integer which contains
+// status information. In addition the parser_arg structure contains a
+// pointer to an error object. However, the `error' member of parser_arg is
+// not yet used here.
+
+error_object:	SCAN_ERROR '{' contents '}' ';' { $$ = $3; STATUS(arg) = $3; }
+;
+
+contents:	description { $$ = $1; }
+;
+
+description:	code message { $$ = $1 && $2; }
+                | code { $$ = $1; }
+;
+
+code:		SCAN_CODE '=' SCAN_INT ';' 
+		{ 
+		    ERROR_OBJ(arg)->set_error_code((ErrorCode)$3);
+		    $$ = true; 
+		}
+;
+
+message:	SCAN_MSG '=' SCAN_STR 
+		{ 
+		    ERROR_OBJ(arg)->set_error_message($3);
+		} 
+		';' 
+                {
+		    $$ = true;
+		}
+;
+
+%%
+
+void
+Errorerror(char *s)
+{
+  string msg = s;
+  msg += " line: ";
+  append_long_to_string(error_line_num, 10, msg);
+  msg += "\n";
+
+  throw Error(unknown_error, msg);
+}
+
diff --git a/EventHandler.h b/EventHandler.h
new file mode 100644
index 0000000..ff40428
--- /dev/null
+++ b/EventHandler.h
@@ -0,0 +1,74 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef event_handler_h
+#define event_handler_h
+
+#include <iostream>
+
+namespace libdap
+{
+
+/** An abstract class which provides a hook method used by SignalHandler.
+
+    Based on "Applying Design Patterns to Simplify Signal Handling", Douglas
+    C. Schmidt, 1998, http://www.cs.wustl.edu/~schmidt/signal-patterns.html.
+
+    @see SignalHandler
+    @see AlarmHandler
+    @author James Gallagher <jgallagher at opendap.org> */
+class EventHandler
+{
+public:
+    /** Hook method for SignalHandler. If a concrete instance of this class
+    is registered with SignalHandler, this method will be called when \c
+    signum is received. */
+    virtual void handle_signal(int signum) = 0;
+
+    /** We don't need a destructor, but including one might stave off an
+    error later on... */
+    virtual ~EventHandler()
+    {}
+};
+
+/** Test Handler. This is used with the SignalHandlerTest unit tests. */
+class TestHandler : public EventHandler
+{
+public:
+    int flag;
+
+    TestHandler() : flag(0)
+    {}
+
+    virtual void handle_signal(int signum)
+    {
+        std::cerr << "Got signal: " << signum << std::endl;
+        flag = 1;
+    }
+};
+
+} // namespace libdap
+
+#endif // event_handler_h
diff --git a/Float32.cc b/Float32.cc
new file mode 100644
index 0000000..1cc6756
--- /dev/null
+++ b/Float32.cc
@@ -0,0 +1,300 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Float32.
+//
+// 3/22/99 jhrg
+
+
+#include <iomanip>
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: Float32.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "dods-limits.h"
+#include "InternalErr.h"
+
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The Float32 constructor accepts only the name of the variable. The
+    name may be omitted, which will create a nameless variable. This
+    may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+*/
+Float32::Float32(const string &n)
+        : BaseType(n, dods_float32_c)
+{}
+
+/** The Float32 server-side constructor accepts the name of the variable and
+    the dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+Float32::Float32(const string &n, const string &d)
+        : BaseType(n, d, dods_float32_c)
+{}
+
+Float32::Float32(const Float32 &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+Float32::ptr_duplicate()
+{
+    return new Float32(*this);
+}
+
+Float32 &
+Float32::operator=(const Float32 &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+Float32::width()
+{
+    return sizeof(dods_float32);
+}
+
+bool
+Float32::serialize(ConstraintEvaluator &eval, DDS &dds,
+                   Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_float32( _buf ) ;
+
+    return true;
+}
+
+bool
+Float32::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_float32( _buf ) ;
+
+    return false;
+}
+
+unsigned int
+Float32::val2buf(void *val, bool)
+{
+    // Jose Garcia This method is public I believe it has been
+    // designed to be used by read which must be implemented in a
+    // subclass, thus if the pointer val is NULL, is an Internal
+    // Error.
+    // Changed to InternalErr. jhrg
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    _buf = *(dods_float32 *)val;
+
+    return width();
+}
+
+unsigned int
+Float32::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    if (!*val)
+        *val = new dods_float32;
+
+    *(dods_float32 *)*val = _buf;
+
+    return width();
+}
+
+bool
+Float32::set_value(dods_float32 f)
+{
+    _buf = f;
+    set_read_p(true);
+
+    return true;
+}
+
+/** Return the value of the Float32 held by this instance. This is more
+    convenient than the general interface provided by buf2val, but its use
+    requires a cast from BaseType to Float32.
+
+    @return The dods_float32 value. */
+dods_float32
+Float32::value() const
+{
+    return _buf;
+}
+
+#if FILE_METHODS
+void
+Float32::print_val(FILE *out, string space, bool print_decl_p)
+{
+    // FIX: need to set precision in the printing somehow.
+    // os.precision(DODS_FLT_DIG);
+
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %.6g;\n", _buf) ;
+    }
+    else
+        fprintf(out, "%.6g", _buf) ;
+}
+#endif
+
+void
+Float32::print_val(ostream &out, string space, bool print_decl_p)
+{
+    // FIX: need to set precision in the printing somehow.
+    // os.precision(DODS_FLT_DIG);
+
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << std::setprecision( 6 ) << _buf << ";\n" ;
+    }
+    else
+	out << std::setprecision( 6 ) << _buf ;
+}
+
+bool
+Float32::ops(BaseType *b, int op)
+{
+    // Get this instance's value
+    if (!read_p() && !read()) {
+        // Jose Garcia Since the read method is virtual and
+        // implemented outside libdap++ if we cannot read the data
+        // that is the problem of whomever wrote the implementation of
+        // read and therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b || !(b->read_p() || b->read())) {
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops<dods_float32, dods_byte, Cmp<dods_float32, dods_byte> >
+               (_buf, dynamic_cast<Byte *>(b)->_buf, op);
+    case dods_int16_c:
+        return rops<dods_float32, dods_int16, Cmp<dods_float32, dods_int16> >
+               (_buf, dynamic_cast<Int16 *>(b)->_buf, op);
+    case dods_uint16_c:
+        return rops<dods_float32, dods_uint16, Cmp<dods_float32, dods_uint16> >
+               (_buf, dynamic_cast<UInt16 *>(b)->_buf, op);
+    case dods_int32_c:
+        return rops<dods_float32, dods_int32, Cmp<dods_float32, dods_int32> >
+               (_buf, dynamic_cast<Int32 *>(b)->_buf, op);
+    case dods_uint32_c:
+        return rops<dods_float32, dods_uint32, Cmp<dods_float32, dods_uint32> >
+               (_buf, dynamic_cast<UInt32 *>(b)->_buf, op);
+    case dods_float32_c:
+        return rops<dods_float32, dods_float32, Cmp<dods_float32, dods_float32> >
+               (_buf, dynamic_cast<Float32 *>(b)->_buf, op);
+    case dods_float64_c:
+        return rops<dods_float32, dods_float64, Cmp<dods_float32, dods_float64> >
+               (_buf, dynamic_cast<Float64 *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+
+   Displays the pointer value of this instance and information about this
+   instance.
+
+   @param strm C++ i/o stream to dump the information to
+   @return void
+ */
+void
+Float32::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Float32::dump - (" << (void *)this << ")"
+	 << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Float32.h b/Float32.h
new file mode 100644
index 0000000..737a099
--- /dev/null
+++ b/Float32.h
@@ -0,0 +1,115 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Float32 type.
+//
+// 3/22/99 jhrg
+
+#ifndef _float32_h
+#define _float32_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** @brief Holds a 32-bit floating point value.
+
+    @see BaseType
+    */
+class Float32: public BaseType
+{
+    /** This class allows Byte, ..., Float64 access to <tt>_buf</tt>
+	to simplify and speed up the relational operators. */
+
+    friend class Byte;
+    friend class Int16;
+    friend class UInt16;
+    friend class Int32;
+    friend class UInt32;
+    friend class Float64;
+
+protected:
+    dods_float32 _buf;
+
+public:
+    Float32(const string &n);
+    Float32(const string &n, const string &d);
+
+    Float32(const Float32 &copy_from);
+
+    Float32 &operator=(const Float32 &rhs);
+
+    virtual ~Float32()
+    {}
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual unsigned int width();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual dods_float32 value() const;
+    virtual bool set_value(dods_float32 f);
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _float32_h
+
diff --git a/Float64.cc b/Float64.cc
new file mode 100644
index 0000000..72820be
--- /dev/null
+++ b/Float64.cc
@@ -0,0 +1,307 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Float64.
+//
+// jhrg 9/7/94
+
+#include <iomanip>
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: Float64.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include <iomanip>
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "dods-limits.h"
+#include "InternalErr.h"
+
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The Float64 constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+
+*/
+Float64::Float64(const string &n)
+        : BaseType(n, dods_float64_c)
+{}
+
+/** The Float64 server-side constructor accepts the name of the variable and
+    the dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+Float64::Float64(const string &n, const string &d)
+        : BaseType(n, d, dods_float64_c)
+{}
+
+Float64::Float64(const Float64 &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+Float64::ptr_duplicate()
+{
+    return new Float64(*this);
+}
+
+Float64 &
+Float64::operator=(const Float64 &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+Float64::width()
+{
+    return sizeof(dods_float64);
+}
+
+bool
+Float64::serialize(ConstraintEvaluator &eval, DDS &dds,
+                   Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_float64( _buf ) ;
+
+    return true;
+}
+
+bool
+Float64::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_float64( _buf ) ;
+
+    return false;
+}
+
+unsigned int
+Float64::val2buf(void *val, bool)
+{
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogated library,
+    // thus if the pointer val is NULL, is an Internal Error.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    _buf = *(dods_float64 *)val;
+
+    return width();
+}
+
+unsigned int
+Float64::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    if (!*val)
+        *val = new dods_float64;
+
+    *(dods_float64 *)*val = _buf;
+
+    return width();
+}
+
+/** Return the value of the Float64 held by this instance. This is more
+    convenient than the general interface provided by buf2val, but its use
+    requires a downcase from BaseType to Float64.
+
+    @return The dods_float32 value. */
+dods_float64
+Float64::value() const
+{
+    return _buf;
+}
+
+bool
+Float64::set_value(dods_float64 val)
+{
+    _buf = val;
+    set_read_p(true);
+
+    return true;
+}
+
+#if FILE_METHODS
+void
+Float64::print_val(FILE *out, string space, bool print_decl_p)
+{
+    // FIX: need to set precision in the printing somehow.
+    // os.precision(DODS_DBL_DIG);
+
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %.15g;\n", _buf) ;
+    }
+    else
+        fprintf(out, "%.15g", _buf) ;
+}
+#endif
+
+void
+Float64::print_val(ostream &out, string space, bool print_decl_p)
+{
+    // FIX: need to set precision in the printing somehow.
+    // os.precision(DODS_DBL_DIG);
+
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << std::setprecision( 15 ) << _buf << ";\n" ;
+    }
+    else
+	out << std::setprecision( 15 ) << _buf ;
+}
+
+bool
+Float64::ops(BaseType *b, int op)
+{
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b->read_p() && !b->read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops<dods_float64, dods_byte, Cmp<dods_float64, dods_byte> >
+               (_buf, dynamic_cast<Byte *>(b)->_buf, op);
+    case dods_int16_c:
+        return rops<dods_float64, dods_int16, Cmp<dods_float64, dods_int16> >
+               (_buf, dynamic_cast<Int16 *>(b)->_buf, op);
+    case dods_uint16_c:
+        return rops<dods_float64, dods_uint16, Cmp<dods_float64, dods_uint16> >
+               (_buf, dynamic_cast<UInt16 *>(b)->_buf, op);
+    case dods_int32_c:
+        return rops<dods_float64, dods_int32, Cmp<dods_float64, dods_int32> >
+               (_buf, dynamic_cast<Int32 *>(b)->_buf, op);
+    case dods_uint32_c:
+        return rops<dods_float64, dods_uint32, Cmp<dods_float64, dods_uint32> >
+               (_buf, dynamic_cast<UInt32 *>(b)->_buf, op);
+    case dods_float32_c:
+        return rops<dods_float64, dods_float32, Cmp<dods_float64, dods_float32> >
+               (_buf, dynamic_cast<Float32 *>(b)->_buf, op);
+    case dods_float64_c:
+        return rops<dods_float64, dods_float64, Cmp<dods_float64, dods_float64> >
+               (_buf, dynamic_cast<Float64 *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Float64::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Float64::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Float64.h b/Float64.h
new file mode 100644
index 0000000..1f34d69
--- /dev/null
+++ b/Float64.h
@@ -0,0 +1,117 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Float64 type.
+//
+// jhrg 9/7/94
+
+#ifndef _float64_h
+#define _float64_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** @brief Holds a 64-bit (double precision) floating point value.
+
+ at see BaseType
+*/
+
+class Float64: public BaseType
+{
+    /** This class allows Byte, ..., Float32 access to <tt>_buf</tt> to
+    simplify and speed up the relational operators.
+
+    NB: According to Stroustrup it does not matter where (public, private
+    or protected) friend classes are declared. */
+    friend class Byte;
+    friend class Int16;
+    friend class UInt16;
+    friend class Int32;
+    friend class UInt32;
+    friend class Float32;
+
+protected:
+    dods_float64 _buf;
+
+public:
+    Float64(const string &n);
+    Float64(const string &n, const string &d);
+    virtual ~Float64()
+    {}
+
+    Float64(const Float64 &copy_from);
+
+    Float64 &operator=(const Float64 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual unsigned int width();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual dods_float64 value() const;
+    virtual bool set_value(dods_float64 val);
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _float64_h
+
diff --git a/GNU/GNURegex.cc b/GNU/GNURegex.cc
new file mode 100644
index 0000000..b216d5c
--- /dev/null
+++ b/GNU/GNURegex.cc
@@ -0,0 +1,167 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <config.h>
+
+#ifndef WIN32
+#include <alloca.h>
+#endif
+#include <stdlib.h>
+ 
+#include <sys/types.h>
+#include <regex.h>
+
+#include <new>
+#include <string>
+#include <vector>
+#include <stdexcept>
+
+#include "GNURegex.h"
+#include "Error.h"
+#include "util.h"
+
+using namespace std;
+
+namespace libdap {
+
+void
+Regex::init(const char *t)
+{
+    d_preg = static_cast<void*>(new regex_t);
+    int result = regcomp(static_cast<regex_t*>(d_preg), t, REG_EXTENDED);
+
+    if  (result != 0) {
+        size_t msg_len = regerror(result, static_cast<regex_t*>(d_preg),
+                                  static_cast<char*>(NULL),
+                                  static_cast<size_t>(0));
+        vector<char> msg(msg_len+1);
+        //char *msg = new char[msg_len+1];
+        regerror(result, static_cast<regex_t*>(d_preg), &msg[0], msg_len);
+        throw Error(string("Regex error: ") + string(&msg[0]));
+        //delete[] msg;
+        //throw e;
+    }
+}
+
+Regex::~Regex()
+{
+    regfree(static_cast<regex_t*>(d_preg));
+    delete static_cast<regex_t*>(d_preg); d_preg = 0;
+
+}
+
+/** Initialize a POSIX regular expression (using the 'extended' features).
+
+    @param t The regular expression pattern. */
+Regex::Regex(const char* t)
+{
+    init(t);
+}
+
+/** Compatability ctor.
+    @see Regex::Regex(const char* t) */
+Regex::Regex(const char* t, int)
+{
+    init(t);
+}
+
+/** Does the regular expression match the string? 
+
+    @param s The string
+    @param len The length of string to consider
+    @param pos Start looking at this position in the string
+    @return The number of characters that match, -1 if there's no match. */
+int 
+Regex::match(const char* s, int len, int pos)
+{
+   if (len > 32766)	// Integer overflow protection
+    	return -1;
+    	
+    regmatch_t *pmatch = new regmatch_t[len+1];
+    string ss = s;
+
+    int result = regexec(static_cast<regex_t*>(d_preg), 
+                         ss.substr(pos, len-pos).c_str(), len, pmatch, 0);
+	int matchnum;
+    if (result == REG_NOMATCH)
+        matchnum = -1;
+	else
+		matchnum = pmatch[0].rm_eo - pmatch[0].rm_so;
+		
+	delete[] pmatch; pmatch = 0;
+
+    return matchnum;
+}
+
+/** Does the regular expression match the string? 
+
+    @param s The string
+    @param len The length of string to consider
+    @param matchlen Return the length of the matched portion in this 
+    value-result parameter.
+    @param pos Start looking at this position in the string
+    @return The start position of the first match. This is different from 
+    POSIX regular expressions, whcih return the start position of the 
+    longest match. */
+int 
+Regex::search(const char* s, int len, int& matchlen, int pos)
+{
+	// sanitize allocation
+    if (!size_ok(sizeof(regmatch_t), len+1))
+    	return -1;
+    	
+    // alloc space for len matches, which is theoretical max.
+    // Problem: If somehow 'len' is very large - say the size of a 32-bit int,
+    // then len+1 is a an integer overflow and this might be exploited by
+    // an attacker. It's not likely there will be more than a handful of
+    // matches, so I am going to limit this value to 32766. jhrg 3/4/09
+    if (len > 32766)
+    	return -1;
+
+    regmatch_t *pmatch = new regmatch_t[len+1];
+    string ss = s;
+     
+    int result = regexec(static_cast<regex_t*>(d_preg),
+                         ss.substr(pos, len-pos).c_str(), len, pmatch, 0);
+    if (result == REG_NOMATCH) {
+        delete[] pmatch; pmatch = 0;
+        return -1;
+    }
+
+    // Match found, find the first one (pmatch lists the longest first)
+    int m = 0;
+    for (int i = 1; i < len; ++i)
+        if (pmatch[i].rm_so != -1 && pmatch[i].rm_so < pmatch[m].rm_so)
+            m = i;
+            
+    matchlen = pmatch[m].rm_eo - pmatch[m].rm_so;
+    int matchpos = pmatch[m].rm_so;
+    
+    delete[] pmatch; pmatch = 0;
+    return matchpos;
+}
+
+} // namespace libdap
+
diff --git a/GNU/GNURegex.h b/GNU/GNURegex.h
new file mode 100644
index 0000000..cd3cad8
--- /dev/null
+++ b/GNU/GNURegex.h
@@ -0,0 +1,60 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _Regex_h
+#define _Regex_h 1
+
+namespace libdap
+{
+
+/** a C++ interface to POSIX regular expression functions.
+
+    @author James Gallagher <jgallagher at opendap.org> */
+class Regex
+{
+private:
+    // d_preg was a regex_t* but I needed to include both regex.h and config.h
+    // to make the gnulib code work. Because this header is installed (and is
+    // used by other libraries) it cannot include config.h, so I moved the 
+    // regex.h and config.h (among other) includes to the implementation. It
+    // would be cleaner to use a special class, but for one field that seems
+    // like overkill.
+    void *d_preg;
+    void init(const char *t);
+    
+public:
+    Regex(const char *t);
+    Regex(const char *t, int dummy);
+    ~Regex();
+
+    /// Does the pattern match.
+    int match(const char* s, int len, int pos = 0);
+    /// How much of the string does the pattern matche.
+    int search(const char* s, int len, int& matchlen, int pos = 0);
+};
+
+} // namespace libdap
+
+#endif
diff --git a/GNU/GetOpt.cc b/GNU/GetOpt.cc
new file mode 100644
index 0000000..24a7ad4
--- /dev/null
+++ b/GNU/GetOpt.cc
@@ -0,0 +1,274 @@
+/*
+Getopt for GNU. 
+Copyright (C) 1987, 1989 Free Software Foundation, Inc.
+
+(Modified by Douglas C. Schmidt for use with GNU G++.)
+This file is part of the GNU C++ Library.  This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library 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 Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+/* AIX requires the alloca decl to be the first thing in the file. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#elif defined(sparc)
+#include <alloca.h>
+#elif defined(_AIX)
+#pragma alloca
+#elif defined(WIN32)
+#include <malloc.h>
+#else
+char *alloca ();
+#endif
+
+#include <vector>
+
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#include <string.h>		// Added these. 10/20/98 jhrg
+#include "GetOpt.h"
+#include <stdlib.h>
+#include <string.h>
+
+char* GetOpt::nextchar = 0;
+int GetOpt::first_nonopt = 0;
+int GetOpt::last_nonopt = 0;
+
+GetOpt::GetOpt (int argc, char **argv, const char *optstring)
+ :opterr (1), nargc (argc), nargv (argv), noptstring (optstring)
+{
+  /* Initialize the internal data when the first call is made.
+     Start processing options with ARGV-element 1 (since ARGV-element 0
+     is the program name); the sequence of previously skipped
+     non-option ARGV-elements is empty.  */
+
+  first_nonopt = last_nonopt = optind = 1;
+  optarg = nextchar = 0;
+
+  /* Determine how to handle the ordering of options and nonoptions.  */
+
+  if (optstring[0] == '-')
+    ordering = RETURN_IN_ORDER;
+  else if (getenv ("_POSIX_OPTION_ORDER") != 0)
+    ordering = REQUIRE_ORDER;
+  else
+    ordering = PERMUTE;
+}
+
+void
+GetOpt::exchange (char **argv)
+{
+  int nonopts_size = (last_nonopt - first_nonopt) * sizeof(char *);
+  /* char **temp = (char **) alloca (nonopts_size); */
+  /* char **temp = (char **)malloc(nonopts_size); */
+  std::vector<char> temp(nonopts_size);
+  
+  /* Interchange the two blocks of data in argv.  */
+
+  memcpy (&temp[0], &argv[first_nonopt], nonopts_size);
+
+  /* valgrind complains about this because in some cases the memory areas
+     overlap. I switched to memmove. See the memcpy & memmove man pages.
+     02/12/04 jhrg */
+#if 0
+  memcpy (&argv[first_nonopt], &argv[last_nonopt],
+         (optind - last_nonopt) * sizeof (char *));
+#endif
+  memmove (&argv[first_nonopt], &argv[last_nonopt],
+         (optind - last_nonopt) * sizeof (char *));
+
+  memcpy (&argv[first_nonopt + optind - last_nonopt], &temp[0],
+         nonopts_size);
+
+  /* Update records for the slots the non-options now occupy.  */
+
+  first_nonopt += (optind - last_nonopt);
+  last_nonopt = optind;
+  
+  //free(temp);
+}
+

+/* Scan elements of ARGV (whose length is ARGC) for option characters
+   given in OPTSTRING.
+
+   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+   then it is an option element.  The characters of this element
+   (aside from the initial '-') are option characters.  If `getopt'
+   is called repeatedly, it returns successively each of theoption characters
+   from each of the option elements.
+
+   If `getopt' finds another option character, it returns that character,
+   updating `optind' and `nextchar' so that the next call to `getopt' can
+   resume the scan with the following option character or ARGV-element.
+
+   If there are no more option characters, `getopt' returns `EOF'.
+   Then `optind' is the index in ARGV of the first ARGV-element
+   that is not an option.  (The ARGV-elements have been permuted
+   so that those that are not options now come last.)
+
+   OPTSTRING is a string containing the legitimate option characters.
+   A colon in OPTSTRING means that the previous character is an option
+   that wants an argument.  The argument is taken from the rest of the
+   current ARGV-element, or from the following ARGV-element,
+   and returned in `optarg'.
+
+   If an option character is seen that is not listed in OPTSTRING,
+   return '?' after printing an error message.  If you set `opterr' to
+   zero, the error message is suppressed but we still return '?'.
+
+   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+   so the following text in the same ARGV-element, or the text of the following
+   ARGV-element, is returned in `optarg.  Two colons mean an option that
+   wants an optional arg; if there is text in the current ARGV-element,
+   it is returned in `optarg'.
+
+   If OPTSTRING starts with `-', it requests a different method of handling the
+   non-option ARGV-elements.  See the comments about RETURN_IN_ORDER, above.  */
+
+int
+GetOpt::operator () (void)
+{
+  if (nextchar == 0 || *nextchar == 0)
+    {
+      if (ordering == PERMUTE)
+        {
+          /* If we have just processed some options following some non-options,
+             exchange them so that the options come first.  */
+
+          if (first_nonopt != last_nonopt && last_nonopt != optind)
+            exchange (nargv);
+          else if (last_nonopt != optind)
+            first_nonopt = optind;
+
+          /* Now skip any additional non-options
+             and extend the range of non-options previously skipped.  */
+
+          while (optind < nargc
+                 && (nargv[optind][0] != '-'
+                     || nargv[optind][1] == 0))
+            optind++;
+          last_nonopt = optind;
+        }
+
+      /* Special ARGV-element `--' means premature end of options.
+         Skip it like a null option,
+         then exchange with previous non-options as if it were an option,
+         then skip everything else like a non-option.  */
+
+      if (optind != nargc && !strcmp (nargv[optind], "--"))
+        {
+          optind++;
+
+          if (first_nonopt != last_nonopt && last_nonopt != optind)
+            exchange (nargv);
+          else if (first_nonopt == last_nonopt)
+            first_nonopt = optind;
+          last_nonopt = nargc;
+
+          optind = nargc;
+        }
+
+      /* If we have done all the ARGV-elements, stop the scan
+         and back over any non-options that we skipped and permuted.  */
+
+      if (optind == nargc)
+        {
+          /* Set the next-arg-index to point at the non-options
+             that we previously skipped, so the caller will digest them.  */
+          if (first_nonopt != last_nonopt)
+            optind = first_nonopt;
+          return EOF;
+        }
+	 
+      /* If we have come to a non-option and did not permute it,
+         either stop the scan or describe it to the caller and pass it by.  */
+
+      if (nargv[optind][0] != '-' || nargv[optind][1] == 0)
+        {
+          if (ordering == REQUIRE_ORDER)
+            return EOF;
+          optarg = nargv[optind++];
+          return 0;
+        }
+
+      /* We have found another option-ARGV-element.
+         Start decoding its characters.  */
+
+      nextchar = nargv[optind] + 1;
+    }
+
+  /* Look at and handle the next option-character.  */
+
+  {
+    char c = *nextchar++;
+    char *temp = (char *) strchr (noptstring, c);
+
+    /* Increment `optind' when we start to process its last character.  */
+    if (*nextchar == 0)
+      optind++;
+
+    if (temp == 0 || c == ':')
+      {
+        if (opterr != 0)
+          {
+            if (c < 040 || c >= 0177)
+              fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
+                       nargv[0], c);
+            else
+              fprintf (stderr, "%s: unrecognized option `-%c'\n",
+                       nargv[0], c);
+          }
+        return '?';
+      }
+    if (temp[1] == ':')
+      {
+        if (temp[2] == ':')
+          {
+            /* This is an option that accepts an argument optionally.  */
+            if (*nextchar != 0)
+              {
+                optarg = nextchar;
+                optind++;
+              }
+            else
+              optarg = 0;
+            nextchar = 0;
+          }
+        else
+          {
+            /* This is an option that requires an argument.  */
+            if (*nextchar != 0)
+              {
+                optarg = nextchar;
+                /* If we end this ARGV-element by taking the rest as an arg,
+                   we must advance to the next element now.  */
+                optind++;
+              }
+            else if (optind == nargc)
+              {
+                if (opterr != 0)
+                  fprintf (stderr, "%s: no argument for `-%c' option\n",
+                           nargv[0], c);
+                c = '?';
+              }
+            else
+              /* We already incremented `optind' once;
+                 increment it again when taking next ARGV-elt as argument.  */
+              optarg = nargv[optind++];
+            nextchar = 0;
+          }
+      }
+    return c;
+  }
+}
diff --git a/GNU/GetOpt.h b/GNU/GetOpt.h
new file mode 100644
index 0000000..394b01a
--- /dev/null
+++ b/GNU/GetOpt.h
@@ -0,0 +1,125 @@
+/* Getopt for GNU. 
+   Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
+   (Modified by Douglas C. Schmidt for use with GNU G++.)
+
+This file is part of the GNU C++ Library.  This library is free
+software; you can redistribute it and/or modify it under the terms of
+the GNU Library 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 Library General Public License for more details.
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+

+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+   but it behaves differently for the user, since it allows the user
+   to intersperse the options with the other arguments.
+
+   As `getopt' works, it permutes the elements of `argv' so that,
+   when it is done, all the options precede everything else.  Thus
+   all application programs are extended to handle flexible argument order.
+
+   Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
+   Then the behavior is completely standard.
+
+   GNU application programs can use a third alternative mode in which
+   they can distinguish the relative order of options and other arguments.  */
+
+#ifndef GetOpt_h
+#define GetOpt_h 1
+
+#include <stdio.h>
+
+class GetOpt
+{
+private:
+  /* The next char to be scanned in the option-element
+     in which the last option character we returned was found.
+     This allows us to pick up the scan where we left off.
+        
+     If this is zero, or a null string, it means resume the scan
+     by advancing to the next ARGV-element.  */
+  
+  static char *nextchar;
+  
+  
+  /* Describe how to deal with options that follow non-option ARGV-elements.
+    
+    UNSPECIFIED means the caller did not specify anything;
+    the default is then REQUIRE_ORDER if the environment variable
+    _OPTIONS_FIRST is defined, PERMUTE otherwise.
+      
+    REQUIRE_ORDER means don't recognize them as options.
+    Stop option processing when the first non-option is seen.
+    This is what Unix does.
+            
+    PERMUTE is the default.  We permute the contents of `argv' as we scan,
+    so that eventually all the options are at the end.  This allows options
+    to be given in any order, even with programs that were not written to
+    expect this.
+        
+    RETURN_IN_ORDER is an option available to programs that were written
+    to expect options and other ARGV-elements in any order and that care about
+    the ordering of the two.  We describe each non-option ARGV-element
+    as if it were the argument of an option with character code zero.
+    Using `-' as the first character of the list of option characters
+    requests this mode of operation.
+                    
+    The special argument `--' forces an end of option-scanning regardless
+    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+    `--' can cause `getopt' to return EOF with `optind' != ARGC.  */
+  
+   enum OrderingEnum { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER };
+   OrderingEnum ordering;
+
+  /* Handle permutation of arguments.  */
+  
+  /* Describe the part of ARGV that contains non-options that have
+     been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+     `last_nonopt' is the index after the last of them.  */
+  
+  static int first_nonopt;
+  static int last_nonopt;
+  
+  void exchange (char **argv);
+public:
+  /* For communication from `getopt' to the caller.
+     When `getopt' finds an option that takes an argument,
+     the argument value is returned here.
+     Also, when `ordering' is RETURN_IN_ORDER,
+     each non-option ARGV-element is returned here.  */
+  
+  char *optarg;
+  
+  /* Index in ARGV of the next element to be scanned.
+     This is used for communication to and from the caller
+     and for communication between successive calls to `getopt'.
+     On entry to `getopt', zero means this is the first call; initialize.
+          
+     When `getopt' returns EOF, this is the index of the first of the
+     non-option elements that the caller should itself scan.
+              
+     Otherwise, `optind' communicates from one call to the next
+     how much of ARGV has been scanned so far.  */
+  
+  int optind;
+
+  /* Callers store zero here to inhibit the error message
+     for unrecognized options.  */
+  
+  int opterr;
+  
+  int    nargc;
+  char **nargv;
+  const char  *noptstring;
+  
+  GetOpt (int argc, char **argv, const char *optstring);
+  int operator () (void);
+};
+
+#endif
diff --git a/GNU/README b/GNU/README
new file mode 100644
index 0000000..3b300bb
--- /dev/null
+++ b/GNU/README
@@ -0,0 +1,8 @@
+
+	$Id: README 24057 2011-02-02 23:54:21Z jimg $
+
+The files GetOpt.{cc,h} are from the GNU libg++ software package. If you'd
+like the complete library it may be obtained from ftp.gnu.org.
+
+The files GNURegex.{cc,h} were originally from teh GNU libg++ package, but 
+I rewrote them to use the Unix regex library some time ago. 
diff --git a/GSEClause.cc b/GSEClause.cc
new file mode 100644
index 0000000..25d93f9
--- /dev/null
+++ b/GSEClause.cc
@@ -0,0 +1,351 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// The Grid Selection Expression Clause class.
+
+
+#include "config.h"
+
+static char id[] not_used =
+    {"$Id: GSEClause.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include <iostream>
+#include <sstream>
+
+#include "dods-datatypes.h"
+#include "Error.h"
+#include "InternalErr.h"
+
+#include "debug.h"
+#include "GSEClause.h"
+#include "parser.h"
+#include "gse.tab.hh"
+
+using namespace std;
+
+int gse_parse(void *arg);
+void gse_restart(FILE *in);
+
+// Glue routines declared in gse.lex
+void gse_switch_to_buffer(void *new_buffer);
+void gse_delete_buffer(void * buffer);
+void *gse_string(const char *yy_str);
+
+namespace libdap {
+
+// Private methods
+
+GSEClause::GSEClause()
+{
+    throw InternalErr(__FILE__, __LINE__, "default ctor called for GSEClause");
+}
+
+GSEClause::GSEClause(const GSEClause &)
+{
+    throw InternalErr(__FILE__, __LINE__, "copy ctor called for GSEClause");
+}
+
+GSEClause &GSEClause::operator=(GSEClause &)
+{
+    throw InternalErr(__FILE__, __LINE__, "assigment called for GSEClause");
+}
+
+// For the comparisions here, we should use an epsilon to catch issues
+// with floating point values. jhrg 01/12/06
+template<class T>
+static bool
+compare(T elem, relop op, double value)
+{
+    switch (op) {
+    case dods_greater_op:
+        return elem > value;
+    case dods_greater_equal_op:
+        return elem >= value;
+    case dods_less_op:
+        return elem < value;
+    case dods_less_equal_op:
+        return elem <= value;
+    case dods_equal_op:
+        return elem == value;
+    case dods_not_equal_op:
+        return elem != value;
+    case dods_nop_op:
+        throw Error(malformed_expr, "Attempt to use NOP in Grid selection.");
+    default:
+        throw Error(malformed_expr, "Unknown relational operator in Grid selection.");
+    }
+}
+
+// These values are used in error messages, hence the strings.
+template<class T>
+void
+GSEClause::set_map_min_max_value(T min, T max)
+{
+    DBG(cerr << "Inside set map min max value " << min << ", " << max << endl);
+    std::ostringstream oss1;
+    oss1 << min;
+    d_map_min_value = oss1.str();
+
+    std::ostringstream oss2;
+    oss2 << max;
+    d_map_max_value = oss2.str();
+}
+
+// Read the map array, scan, set start and stop.
+template<class T>
+void
+GSEClause::set_start_stop()
+{
+    T *vals = new T[d_map->length()];
+    d_map->value(vals);
+
+    // Set the map's max and min values for use in error messages (it's a lot
+    // easier to do here, now, than later... 9/20/2001 jhrg)
+    set_map_min_max_value<T>(vals[d_start], vals[d_stop]);
+
+    // Starting at the current start point in the map (initially index position
+    // zero), scan forward until the comparison is true. Set the new value
+    // of d_start to that location. Note that each clause applies to exactly
+    // one map. The 'i <= end' test keeps us from setting start _past_ the
+    // end ;-)
+    int i = d_start;
+    int end = d_stop;
+    while (i <= end && !compare<T>(vals[i], d_op1, d_value1))
+        i++;
+
+    d_start = i;
+
+    // Now scan backward from the end. We scan all the way to the actual start
+    // although it would probably work to stop at 'i >= d_start'.
+    i = end;
+    while (i >= 0 && !compare<T>(vals[i], d_op1, d_value1))
+        i--;
+    d_stop = i;
+
+    // Every clause must have one operator but the second is optional since
+    // the more complex form of a clause is optional. That is, the above two
+    // loops took care of constraints like 'x < 7' but we need the following
+    // for ones like '3 < x < 7'.
+    if (d_op2 != dods_nop_op) {
+        int i = d_start;
+        int end = d_stop;
+        while (i <= end && !compare<T>(vals[i], d_op2, d_value2))
+            i++;
+
+        d_start = i;
+
+        i = end;
+        while (i >= 0 && !compare<T>(vals[i], d_op2, d_value2))
+            i--;
+
+        d_stop = i;
+    }
+    
+    delete[] vals;
+}
+
+void
+GSEClause::compute_indices()
+{
+    switch (d_map->var()->type()) {
+    case dods_byte_c:
+        set_start_stop<dods_byte>();
+        break;
+    case dods_int16_c:
+        set_start_stop<dods_int16>();
+        break;
+    case dods_uint16_c:
+        set_start_stop<dods_uint16>();
+        break;
+    case dods_int32_c:
+        set_start_stop<dods_int32>();
+        break;
+    case dods_uint32_c:
+        set_start_stop<dods_uint32>();
+        break;
+    case dods_float32_c:
+        set_start_stop<dods_float32>();
+        break;
+    case dods_float64_c:
+        set_start_stop<dods_float64>();
+        break;
+    default:
+        throw Error(malformed_expr,
+                    "Grid selection using non-numeric map vectors is not supported");
+    }
+
+}
+
+// Public methods
+
+/** @brief Create an instance using discrete parameters. */
+GSEClause::GSEClause(Grid *grid, const string &map, const double value,
+                     const relop op)
+        : d_map(0),
+        d_value1(value), d_value2(0), d_op1(op), d_op2(dods_nop_op),
+        d_map_min_value(""), d_map_max_value("")
+{
+    d_map = dynamic_cast<Array *>(grid->var(map));
+    if (!d_map)
+        throw Error(string("The map variable '") + map
+                    + string("' does not exist in the grid '")
+                    + grid->name() + string("'."));
+
+    DBG(cerr << d_map->toString());
+
+    // Initialize the start and stop indices.
+    Array::Dim_iter iter = d_map->dim_begin();
+    d_start = d_map->dimension_start(iter);
+    d_stop = d_map->dimension_stop(iter);
+
+    compute_indices();
+}
+
+/** @brief Create an instance using discrete parameters. */
+GSEClause::GSEClause(Grid *grid, const string &map, const double value1,
+                     const relop op1, const double value2, const relop op2)
+        : d_map(0),
+        d_value1(value1), d_value2(value2), d_op1(op1), d_op2(op2),
+        d_map_min_value(""), d_map_max_value("")
+{
+    d_map = dynamic_cast<Array *>(grid->var(map));
+    if (!d_map)
+        throw Error(string("The map variable '") + map
+                    + string("' does not exist in the grid '")
+                    + grid->name() + string("'."));
+
+    DBG(cerr << d_map->toString());
+
+    // Initialize the start and stop indices.
+    Array::Dim_iter iter = d_map->dim_begin();
+    d_start = d_map->dimension_start(iter);
+    d_stop = d_map->dimension_stop(iter);
+
+    compute_indices();
+}
+
+/** Class invariant.
+    @return True if the object is valid, otherwise False. */
+bool
+GSEClause::OK() const
+{
+    if (!d_map)
+        return false;
+
+    // More ...
+
+    return true;
+}
+
+/** @brief Get a pointer to the map variable constrained by this clause.
+    @return The Array object. */
+Array *
+GSEClause::get_map() const
+{
+    return d_map;
+}
+
+/** @brief Set the pointer to the map vector contrained by this clause.
+
+    Note that this method also sets the name of the map vector.
+    @return void */
+void
+GSEClause::set_map(Array *map)
+{
+    d_map = map;
+}
+
+/** @brief Get the name of the map variable constrained by this clause.
+    @return The Array object's name. */
+string
+GSEClause::get_map_name() const
+{
+    return d_map->name();
+}
+
+/** @brief Get the starting index of the clause's map variable as
+    constrained by this clause.
+    @return The start index. */
+int
+GSEClause::get_start() const
+{
+    return d_start;
+}
+
+/** @brief Set the starting index.
+    @return void */
+void
+GSEClause::set_start(int start)
+{
+    d_start = start;
+}
+
+/** @brief Get the stopping index of the clause's map variable as
+    constrained by this clause.
+    @return The stop index. */
+int
+GSEClause::get_stop() const
+{
+    DBG(cerr << "Returning stop index value of: " << d_stop << endl);
+    return d_stop;
+}
+
+/** @brief Set the stopping index.
+    @return void */
+void
+GSEClause::set_stop(int stop)
+{
+    d_stop = stop;
+}
+
+/** @brief Get the minimum map vector value.
+
+    Useful in messages back to users.
+    @return The minimum map vetor value. */
+string
+GSEClause::get_map_min_value() const
+{
+    return d_map_min_value;
+}
+
+/** @brief Get the maximum map vector value.
+
+    Useful in messages back to users.
+    @return The maximum map vetor value. */
+string
+GSEClause::get_map_max_value() const
+{
+    return d_map_max_value;
+}
+
+} // namespace libdap
+
diff --git a/GSEClause.h b/GSEClause.h
new file mode 100644
index 0000000..7f5400e
--- /dev/null
+++ b/GSEClause.h
@@ -0,0 +1,143 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// The Grid Selection Expression Clause class.
+
+#ifndef _gseclause_h
+#define _gseclause_h 1
+
+
+#include <string>
+#include <sstream>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _array_h
+#include "Array.h"
+#endif
+
+#ifndef _grid_h
+#include "Grid.h"
+#endif
+
+namespace libdap
+{
+
+enum relop {
+    dods_nop_op,
+    dods_greater_op,
+    dods_greater_equal_op,
+    dods_less_op,
+    dods_less_equal_op,
+    dods_equal_op,
+    dods_not_equal_op
+};
+
+/** Holds the results of parsing one of the Grid Selection Expression
+    clauses. The Grid selection function takes a set of clauses as arguments
+    and must create one instance of this class for each of those clauses. The
+    GridSelectionExpr class holds N instances of this class.
+
+    @author James Gallagher
+    @see GridSelectionExpr */
+
+class GSEClause
+{
+private:
+    Array *d_map;
+    // _value1, 2 and _op1, 2 hold the first and second operators and
+    // operands. For a clause like `var op value' only _op1 and _value1 have
+    // valid information. For a clause like `value op var op value' the
+    // second operator and operand are on _op2 and _value2. 1/19/99 jhrg
+    double d_value1, d_value2;
+    relop d_op1, d_op2;
+    int d_start;
+    int d_stop;
+
+    string d_map_min_value, d_map_max_value;
+
+    GSEClause();  // Hidden default constructor.
+
+    GSEClause(const GSEClause &param); // Hide
+    GSEClause &operator=(GSEClause &rhs); // Hide
+
+    template<class T> void set_start_stop();
+    template<class T> void set_map_min_max_value(T min, T max);
+
+    void compute_indices();
+
+public:
+    /** @name Constructors */
+    //@{
+    GSEClause(Grid *grid, const string &map, const double value,
+              const relop op);
+
+    GSEClause(Grid *grid, const string &map, const double value1,
+              const relop op1, const double value2, const relop op2);
+    //@}
+
+    virtual ~GSEClause() {
+    	delete d_map; d_map = 0;
+    }
+    
+    bool OK() const;
+
+    /** @name Accessors */
+    //@{
+    Array *get_map() const;
+
+    string get_map_name() const;
+
+    int get_start() const;
+
+    int get_stop() const;
+
+    string get_map_min_value() const;
+
+    string get_map_max_value() const;
+    //@}
+
+    /** @name Mutators */
+    //@{
+    void set_map(Array *map);
+
+    void set_start(int start);
+
+    void set_stop(int stop);
+    //@}
+};
+
+} // namespace libdap
+
+#endif // _gseclause_h
+
diff --git a/GeoConstraint.cc b/GeoConstraint.cc
new file mode 100644
index 0000000..1e1958f
--- /dev/null
+++ b/GeoConstraint.cc
@@ -0,0 +1,659 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// The Grid Selection Expression Clause class.
+
+
+#include "config.h"
+
+static char id[] not_used =
+    { "$Id: GeoConstraint.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include <cstring>
+#include <cmath>
+#include <iostream>
+#include <sstream>
+#include <algorithm>  //  for find_if
+
+//#define DODS_DEBUG
+//#define DODS_DEBUG2
+
+#include "debug.h"
+#include "dods-datatypes.h"
+#include "GeoConstraint.h"
+#include "Float64.h"
+
+#include "Error.h"
+#include "InternalErr.h"
+#include "ce_functions.h"
+#include "util.h"
+
+using namespace std;
+
+namespace libdap {
+
+/** This is used with find_if(). The GeoConstraint class holds a set of strings
+    which are prefixes for variable names. Using the regular find() locates
+    only the exact matches, using find_if() with this functor makes is easy
+    to treat those set<string> objects as collections of prefixes. */
+class is_prefix
+{
+private:
+    string s;
+public:
+    is_prefix(const string & in): s(in)
+    {}
+
+    bool operator()(const string & prefix)
+    {
+        return s.find(prefix) == 0;
+    }
+};
+
+/** Look in the containers which hold the units attributes and variable name
+    prefixes which are considered as identifying a vector as being a latitude
+    or longitude vector.
+
+    @param units A container with a bunch of units attribute values.
+    @param names A container with a bunch of variable name prefixes.
+    @param var_units The value of the 'units' attribute for this variable.
+    @param var_name The name of the variable.
+    @return True if the units_value matches any of the accepted attributes
+    exactly or if the name_value starts with any of the accepted prefixes */
+bool
+unit_or_name_match(set < string > units, set < string > names,
+                       const string & var_units, const string & var_name)
+{
+    return (units.find(var_units) != units.end()
+            || find_if(names.begin(), names.end(),
+                       is_prefix(var_name)) != names.end());
+}
+
+/** A private method that determines if the longitude part of the bounding
+    box uses 0/359 or -180/179 notation. This class only supports latitude
+    constraints which use 90/-90 notation, so there's no need to figure out
+    what sort of notation they use.
+
+    @note This function assumes that if one of the two values is
+    negative, then the notation is or the -180/179 form, otherwise not.
+    If the user asks for 30 degrees to 50 degrees (or 50 to 30,
+    for that matter), there's no real way to tell which notation they are
+    using.
+
+    @param left The left side of the bounding box, in degrees
+    @param right The right side of the bounding box
+    @return The notation (pos or neg_pos) */
+GeoConstraint::Notation
+GeoConstraint::categorize_notation(const double left,
+                                   const double right) const
+{
+    return (left < 0 || right < 0) ? neg_pos : pos;
+}
+
+/* A private method to translate the longitude constraint from -180/179
+   notation to 0/359 notation.
+
+   About the two notations:
+   0                          180                       360
+   |---------------------------|-------------------------|
+   0                        180,-180                     0
+
+   so in the neg-pos notation (using the name I give it in this class) both
+   180 and -180 are the same longitude. And in the pos notation 0 and 360 are
+   the same.
+
+   @param left Value-result parameter; the left side of the bounding box
+   @parm right Value-result parameter; the right side of the bounding box */
+void
+GeoConstraint::transform_constraint_to_pos_notation(double &left,
+        double &right) const
+{
+    if (left < 0)
+	left += 360 ;
+
+    if (right < 0)
+	right += 360;
+}
+
+/** Given that the Grid has a longitude map that uses the 'neg_pos' notation,
+    transform it to the 'pos' notation. This method modifies the d_lon array.
+
+    @note: About the two notations:
+   0                          180                       360
+   |---------------------------|-------------------------|
+   0                        180,-180                     0
+*/
+void GeoConstraint::transform_longitude_to_pos_notation()
+{
+    // Assume earlier logic is correct (since the test is expensive)
+    // for each value, add 180
+    // Longitude could be represented using any of the numeric types
+    for (int i = 0; i < d_lon_length; ++i)
+	if (d_lon[i] < 0)
+	    d_lon[i] += 360;
+}
+
+/** Given that the Grid has a longitude map that uses the 'pos' notation,
+    transform it to the 'neg_pos' notation. This method modifies the
+    d_lon array.
+
+    @note: About the two notations:
+   0                          180                       360
+   |---------------------------|-------------------------|
+   0                        180,-180                     0
+*/
+void GeoConstraint::transform_longitude_to_neg_pos_notation()
+{
+    for (int i = 0; i < d_lon_length; ++i)
+	if (d_lon[i] > 180)
+	    d_lon[i] -= 360;
+}
+
+bool GeoConstraint::is_bounding_box_valid(const double left, const double top,
+        const double right, const double bottom) const
+{
+    if ((left < d_lon[0] && right < d_lon[0])
+        || (left > d_lon[d_lon_length-1] && right > d_lon[d_lon_length-1]))
+        return false;
+
+    if (d_latitude_sense == normal) {
+        // When sense is normal, the largest values are at the origin.
+        if ((top > d_lat[0] && bottom > d_lat[0])
+            || (top < d_lat[d_lat_length-1] && bottom < d_lat[d_lat_length-1]))
+            return false;
+    }
+    else {
+        if ((top < d_lat[0] && bottom < d_lat[0])
+            || (top > d_lat[d_lat_length-1] && bottom > d_lat[d_lat_length-1]))
+            return false;
+    }
+
+    return true;
+}
+
+/** Scan from the left to the right, and the right to the left, looking
+    for the left and right bounding box edges, respectively.
+
+    @param left The left edge of the bounding box
+    @param right The right edge
+    @param longitude_index_left Value-result parameter that holds the index
+    in the grid's longitude map of the left bounding box edge. Uses a closed
+    interval for the test.
+    @param  longitude_index_right Value-result parameter for the right edge
+    index. */
+void GeoConstraint::find_longitude_indeces(double left, double right,
+        int &longitude_index_left, int &longitude_index_right) const
+{
+    // Use all values 'modulo 360' to take into account the cases where the
+    // constraint and/or the longitude vector are given using values greater
+    // than 360 (i.e., when 380 is used to mean 20).
+    double t_left = fmod(left, 360.0);
+    double t_right = fmod(right, 360.0);
+
+    // Find the place where 'longitude starts.' That is, what value of the
+    // index 'i' corresponds to the smallest value of d_lon. Why we do this:
+    // Some data sources use offset longitude axes so that the 'seam' is
+    // shifted to a place other than the date line.
+    int i = 0;
+    int lon_origin_index = 0;
+    double smallest_lon = fmod(d_lon[0], 360.0);
+    while (i < d_lon_length) {
+	double curent_lon_value = fmod(d_lon[i], 360.0);
+        if (smallest_lon > curent_lon_value) {
+            smallest_lon = curent_lon_value;
+            lon_origin_index = i;
+        }
+        ++i;
+    }
+
+    DBG2(cerr << "lon_origin_index: " << lon_origin_index << endl);
+
+    // Scan from the index of the smallest value looking for the place where
+    // the value is greater than or equal to the left most point of the bounding
+    // box.
+    i = lon_origin_index;
+    while (fmod(d_lon[i], 360.0) < t_left) {
+        ++i;
+        i = i % d_lon_length;
+
+        // If we cycle completely through all the values/indices, throw
+        if (i == lon_origin_index)
+            throw Error("geogrid: Could not find an index for the longitude value '" + double_to_string(left) + "'");
+    }
+
+    if (fmod(d_lon[i], 360.0) == t_left)
+        longitude_index_left = i;
+    else
+        longitude_index_left = (i - 1) > 0 ? i - 1 : 0;
+
+    DBG2(cerr << "longitude_index_left: " << longitude_index_left << endl);
+
+    // Assume the vector is circular --> the largest value is next to the
+    // smallest.
+    int largest_lon_index = (lon_origin_index - 1 + d_lon_length) % d_lon_length;
+    i = largest_lon_index;
+    while (fmod(d_lon[i], 360.0) > t_right) {
+        // This is like modulus but for 'counting down'
+        i = (i == 0) ? d_lon_length - 1 : i - 1;
+        if (i == largest_lon_index)
+            throw Error("geogrid: Could not find an index for the longitude value '" + double_to_string(right) + "'");
+    }
+
+    if (fmod(d_lon[i], 360.0) == t_right)
+        longitude_index_right = i;
+    else
+        longitude_index_right = (i + 1) < d_lon_length - 1 ? i + 1 : d_lon_length - 1;
+
+    DBG2(cerr << "longitude_index_right: " << longitude_index_right << endl);
+}
+
+/** Scan from the top to the bottom, and the bottom to the top, looking
+    for the top and bottom bounding box edges, respectively.
+
+    @param top The top edge of the bounding box
+    @param bottom The bottom edge
+    @param sense Does the array/grid store data with larger latitudes at
+    the starting indices or are the latitude 'upside down?'
+    @param latitude_index_top Value-result parameter that holds the index
+    in the grid's latitude map of the top bounding box edge. Uses a closed
+    interval for the test.
+    @param  latitude_index_bottom Value-result parameter for the bottom edge
+    index. */
+void GeoConstraint::find_latitude_indeces(double top, double bottom,
+        LatitudeSense sense,
+        int &latitude_index_top,
+        int &latitude_index_bottom) const
+{
+    int i, j;
+
+    if (sense == normal) {
+	i = 0;
+        while (i < d_lat_length - 1 && top < d_lat[i])
+            ++i;
+
+        j = d_lat_length - 1;
+        while (j > 0 && bottom > d_lat[j])
+            --j;
+
+        if (d_lat[i] == top)
+            latitude_index_top = i;
+        else
+            latitude_index_top = (i - 1) > 0 ? i - 1 : 0;
+
+        if (d_lat[j] == bottom)
+            latitude_index_bottom = j;
+        else
+            latitude_index_bottom =
+                (j + 1) < d_lat_length - 1 ? j + 1 : d_lat_length - 1;
+    }
+    else {
+        i = d_lat_length - 1;
+        while (i > 0 && d_lat[i] > top)
+            --i;
+
+        j = 0;
+        while (j < d_lat_length - 1 && d_lat[j] < bottom)
+            ++j;
+
+        if (d_lat[i] == top)
+            latitude_index_top = i;
+        else
+            latitude_index_top = (i + 1) < d_lat_length - 1 ? i + 1 : d_lat_length - 1;
+
+        if (d_lat[j] == bottom)
+            latitude_index_bottom = j;
+        else
+            latitude_index_bottom = (j - 1) > 0 ? j - 1 : 0;
+    }
+}
+
+/** Take a look at the latitude vector values and record whether the world is
+    normal or upside down.
+    @return normal or inverted. */
+GeoConstraint::LatitudeSense GeoConstraint::categorize_latitude() const
+{
+    return d_lat[0] >= d_lat[d_lat_length - 1] ? normal : inverted;
+}
+
+// Use 'index' as the pivot point. Move the points behind index to the front of
+// the vector and those points in front of and at index to the rear.
+static void
+swap_vector_ends(char *dest, char *src, int len, int index, int elem_sz)
+{
+    memcpy(dest, src + index * elem_sz, (len - index) * elem_sz);
+
+    memcpy(dest + (len - index) * elem_sz, src, index * elem_sz);
+}
+
+template<class T>
+static void transpose(std::vector<std::vector<T> > a,
+	std::vector<std::vector<T> > b, int width, int height)
+{
+    for (int i = 0; i < width; i++) {
+	for (int j = 0; j < height; j++) {
+	    b[j][i] = a[i][j];
+	}
+    }
+}
+
+/** Given a vector of doubles, transpose the elements. Use this to flip the
+ * latitude vector for a Grid that stores the southern latitudes at the top
+ * instead of the bottom.
+ *
+ * @param src A pointer to the vector
+ * @param length The number of elements in the vector
+ */
+void GeoConstraint::transpose_vector(double *src, const int length)
+{
+    double *tmp = new double[length];
+
+    int i = 0, j = length-1;
+    while (i < length)
+	tmp[j--] = src[i++];
+
+    memcpy(src, tmp,length * sizeof(double));
+
+    delete[] tmp;
+}
+
+static int
+count_size_except_latitude_and_longitude(Array &a)
+{
+    if (a.dim_end() - a.dim_begin() <= 2)	// < 2 is really an error...
+	return 1;
+
+    int size = 1;
+    for (Array::Dim_iter i = a.dim_begin(); (i + 2) != a.dim_end(); ++i)
+        size *= a.dimension_size(i, true);
+
+    return size;
+}
+
+void GeoConstraint::flip_latitude_within_array(Array &a, int lat_length,
+	int lon_length)
+{
+    if (!d_array_data) {
+	a.read();
+	d_array_data = static_cast<char*>(a.value());
+	d_array_data_size = a.width();	// Bytes not elements
+    }
+
+    int size = count_size_except_latitude_and_longitude(a);
+    // char *tmp_data = new char[d_array_data_size];
+    vector<char> tmp_data(d_array_data_size);
+    int array_elem_size = a.var()->width();
+    int lat_lon_size = (d_array_data_size / size);
+
+    DBG(cerr << "lat, lon_length: " << lat_length << ", " << lon_length << endl);
+    DBG(cerr << "size: " << size << endl);
+    DBG(cerr << "d_array_data_size: " << d_array_data_size << endl);
+    DBG(cerr << "array_elem_size: " << array_elem_size<< endl);
+    DBG(cerr << "lat_lon_size: " << lat_lon_size<< endl);
+
+    for (int i = 0; i < size; ++i) {
+	int lat = 0;
+	int s_lat = lat_length - 1;
+	// lon_length is the element size; memcpy() needs the number of bytes
+	int lon_size = array_elem_size * lon_length;
+	int offset = i * lat_lon_size;
+	while (s_lat > -1)
+	    memcpy(&tmp_data[0] + offset + (lat++ * lon_size),
+		    d_array_data + offset + (s_lat-- * lon_size),
+		    lon_size);
+    }
+
+    memcpy(d_array_data, &tmp_data[0], d_array_data_size);
+    // delete [] tmp_data;
+}
+
+/** Reorder the elements in the longitude map so that the longitude constraint no
+    longer crosses the edge of the map's storage. The d_lon field is
+    modified.
+
+    @note The d_lon vector always has double values regardless of the type
+    of d_longitude.
+
+    @param longitude_index_left The left edge of the bounding box. */
+void GeoConstraint::reorder_longitude_map(int longitude_index_left)
+{
+    double *tmp_lon = new double[d_lon_length];
+
+    swap_vector_ends((char *) tmp_lon, (char *) d_lon, d_lon_length,
+                     longitude_index_left, sizeof(double));
+
+    memcpy(d_lon, tmp_lon, d_lon_length * sizeof(double));
+
+    delete[]tmp_lon;
+}
+
+static int
+count_dimensions_except_longitude(Array &a)
+{
+    int size = 1;
+    for (Array::Dim_iter i = a.dim_begin(); (i + 1) != a.dim_end(); ++i)
+        size *= a.dimension_size(i, true);
+
+    return size;
+}
+
+/** Reorder the data values relative to the longitude axis so that the
+    reordered longitude map (see GeoConstraint::reorder_longitude_map())
+    and the data values match.
+
+    @note This should be called with the Array that contains the d_lon_dim
+    Array::Dim_iter.
+
+    @note This method must set the d_array_data and d_array_data_size
+    fields. If those are set, apply_constraint_to_data() will use those
+    values.
+
+    @note First set all the other constraints, including the latitude and
+    then make this call. Other constraints, besides latitude, will be simple
+    range constraints. Latitude might require that values be flipped, but
+    that can be done _after_ the longitude reordering takes place.
+
+    @todo Fix this code so that it works with latitude as the rightmost map */
+void GeoConstraint::reorder_data_longitude_axis(Array &a, Array::Dim_iter lon_dim)
+{
+
+    if (!is_longitude_rightmost())
+        throw Error("This grid does not have Longitude as its rightmost dimension, the geogrid()\ndoes not support constraints that wrap around the edges of this type of grid.");
+
+    DBG(cerr << "Constraint for the left half: " << get_longitude_index_left()
+        << ", " << get_lon_length() - 1 << endl);
+
+    // Build a constraint for the left part and get those values
+    a.add_constraint(lon_dim, get_longitude_index_left(), 1,
+                     get_lon_length() - 1);
+    a.set_read_p(false);
+    a.read();
+    DBG2(a.print_val(stderr));
+
+    // Save the left-hand data to local storage
+    int left_size = a.width();		// width() == length() * element size
+    char *left_data = (char*)a.value();	// value() allocates and copies
+
+    // Build a constraint for the 'right' part, which goes from the left edge
+    // of the array to the right index and read those data.
+    // (Don't call a.clear_constraint() since that will clear the constraint on
+    // all the dimensions while add_constraint() will replace a constraint on
+    // the given dimension).
+
+    DBG(cerr << "Constraint for the right half: " << 0
+        << ", " << get_longitude_index_right() << endl);
+
+    a.add_constraint(lon_dim, 0, 1, get_longitude_index_right());
+    a.set_read_p(false);
+    a.read();
+    DBG2(a.print_val(stderr));
+
+    char *right_data = (char*)a.value();
+    int right_size = a.width();
+
+    // Make one big lump O'data
+    d_array_data_size = left_size + right_size;
+    d_array_data = new char[d_array_data_size];
+
+    // Assume COARDS conventions are being followed: lon varies fastest.
+    // These *_elements variables are actually elements * bytes/element since
+    // memcpy() uses bytes.
+    int elem_size = a.var()->width();
+    int left_row_size = (get_lon_length() - get_longitude_index_left()) * elem_size;
+    int right_row_size = (get_longitude_index_right() + 1) * elem_size;
+    int total_bytes_per_row = left_row_size + right_row_size;
+
+    DBG2(cerr << "elem_size: " << elem_size << "; left & right size: "
+	    << left_row_size << ", " << right_row_size << endl);
+
+    // This will work for any number of dimension so long as longitude is the
+    // right-most array dimension.
+    int rows_to_copy = count_dimensions_except_longitude(a);
+    for (int i = 0; i < rows_to_copy; ++i) {
+	DBG(cerr << "Copying " << i << "th row" << endl);
+	DBG(cerr << "left memcpy: " << *(float *)(left_data + (left_row_size * i)) << endl);
+
+        memcpy(d_array_data + (total_bytes_per_row * i),
+               left_data + (left_row_size * i),
+               left_row_size);
+
+        DBG(cerr << "right memcpy: " << *(float *)(right_data + (right_row_size * i)) << endl);
+
+        memcpy(d_array_data + (total_bytes_per_row * i) + left_row_size,
+               right_data + (right_row_size * i),
+               right_row_size);
+    }
+
+    delete[]left_data;
+    delete[]right_data;
+}
+
+/** @brief Initialize GeoConstraint.
+ */
+GeoConstraint::GeoConstraint()
+        : d_array_data(0), d_array_data_size(0),
+        d_lat(0), d_lon(0),
+        d_bounding_box_set(false),
+        d_longitude_rightmost(false),
+        d_longitude_notation(unknown_notation),
+        d_latitude_sense(unknown_sense)
+{
+    // Build sets of attribute values for easy searching. Maybe overkill???
+    d_coards_lat_units.insert("degrees_north");
+    d_coards_lat_units.insert("degree_north");
+    d_coards_lat_units.insert("degree_N");
+    d_coards_lat_units.insert("degrees_N");
+
+    d_coards_lon_units.insert("degrees_east");
+    d_coards_lon_units.insert("degree_east");
+    d_coards_lon_units.insert("degrees_E");
+    d_coards_lon_units.insert("degree_E");
+
+    d_lat_names.insert("COADSY");
+    d_lat_names.insert("lat");
+    d_lat_names.insert("Lat");
+    d_lat_names.insert("LAT");
+
+    d_lon_names.insert("COADSX");
+    d_lon_names.insert("lon");
+    d_lon_names.insert("Lon");
+    d_lon_names.insert("LON");
+}
+
+/** Set the bounding box for this constraint. After calling this method the
+    object has values for the indexes for the latitude and longitude extent
+    as well as the sense of the latitude (south pole at the top or bottom of
+    the Array or Grid). These are used by the apply_constraint_to_data()
+    method to actually constrain the data.
+
+    @param left The left side of the bounding box.
+    @param right The right side
+    @param top The top
+    @param bottom The bottom */
+void GeoConstraint::set_bounding_box(double top, double left,
+                                     double bottom, double right)
+{
+    // Ensure this method is called only once. What about pthreads?
+    // The method Array::reset_constraint() might make this so it could be
+    // called more than once. jhrg 8/30/06
+    if (d_bounding_box_set)
+        throw Error("It is not possible to register more than one geographical constraint on a variable.");
+
+    // Record the 'sense' of the latitude for use here and later on.
+    d_latitude_sense = categorize_latitude();
+#if 0
+    if (d_latitude_sense == inverted)
+	throw Error("geogrid() does not currently work with inverted data (data where the north pole is at a negative latitude value).");
+#endif
+
+    // Categorize the notation used by the bounding box (0/359 or -180/179).
+    d_longitude_notation = categorize_notation(left, right);
+
+    // If the notation uses -180/179, transform the request to 0/359 notation.
+    if (d_longitude_notation == neg_pos)
+        transform_constraint_to_pos_notation(left, right);
+
+    // If the grid uses -180/179, transform it to 0/359 as well. This will make
+    // subsequent logic easier and adds only a few extra operations, even with
+    // large maps.
+    Notation longitude_notation =
+        categorize_notation(d_lon[0], d_lon[d_lon_length - 1]);
+
+    if (longitude_notation == neg_pos)
+        transform_longitude_to_pos_notation();
+
+    if (!is_bounding_box_valid(left, top, right, bottom))
+        throw Error("The bounding box does not intersect any data within this Grid or Array. The\ngeographical extent of these data are from latitude "
+		    + double_to_string(d_lat[0]) + " to "
+		    + double_to_string(d_lat[d_lat_length-1])
+		    + "\nand longitude " + double_to_string(d_lon[0])
+		    + " to " + double_to_string(d_lon[d_lon_length-1])
+		    + " while the bounding box provided was latitude "
+		    + double_to_string(top) + " to "
+		    + double_to_string(bottom) + "\nand longitude "
+		    + double_to_string(left) + " to "
+		    + double_to_string(right));
+
+    // This is simpler than the longitude case because there's no need to
+    // test for several notations, no need to accommodate them in the return,
+    // no modulo arithmetic for the axis and no need to account for a
+    // constraint with two disconnected parts to be joined.
+    find_latitude_indeces(top, bottom, d_latitude_sense,
+                          d_latitude_index_top, d_latitude_index_bottom);
+
+
+    // Find the longitude map indexes that correspond to the bounding box.
+    find_longitude_indeces(left, right, d_longitude_index_left,
+                           d_longitude_index_right);
+
+    DBG(cerr << "Bounding box (tlbr): " << d_latitude_index_top << ", "
+        << d_longitude_index_left << ", "
+        << d_latitude_index_bottom << ", "
+        << d_longitude_index_right << endl);
+
+    d_bounding_box_set = true;
+}
+
+} // namespace libdap
diff --git a/GeoConstraint.h b/GeoConstraint.h
new file mode 100644
index 0000000..2e80b9a
--- /dev/null
+++ b/GeoConstraint.h
@@ -0,0 +1,376 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _geo_constraint_h
+#define _geo_constraint_h 1
+
+#include <string>
+#include <sstream>
+#include <set>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _array_h
+#include "Array.h"
+#endif
+
+#ifndef _grid_h
+#include "Grid.h"
+#endif
+
+namespace libdap
+{
+
+/** Encapsulate the logic needed to handle geographical constraints
+    when they are applied to DAP Grid (and some Array) variables.
+
+    This class will apply a longitude/latitude bounding box to a Grid
+    that is a 'geo-referenced' Grid. That is, it follows the COARDS/CF
+    conventions. This may be relaxed...
+
+    If the longitude range of the constraint crosses the boundary of
+    the data array so that the constraint creates two separate
+    rectangles, this class will arrange to return the result as a
+    single Grid. It will do this by rearranging the data before
+    control is passed onto the constraint evaluator and serialization
+    logic. Here's a diagram of how it works:
+
+    Suppose a constraint for the longitude BB starts at the left edge
+    of L and goes to the right edge of R:
+
+    <pre>
+       0.0       180.0       360.0 (longitude, in degrees)
+        +----------------------+
+        |xxxxxyyyyyyyyyyyyzzzzz|
+        -----+            +-----
+        |    |            |    |
+        | R  |            | L  |
+        |    |            |    |
+        -----+            +-----
+        |                      |
+        +----------------------+
+    </pre>
+
+    For example, suppose the client provides a bounding box that
+    starts at 200 degrees and ends at 80. This class will first copy
+    the Left part to new storage and then copy the right part, thus
+    'stitching together' the two halves of the constraint. The result
+    looks like:
+
+    <pre>
+     80.0  360.0/0.0  180.0  ~200.0 (longitude, in degrees)
+        +----------------------+
+        |zzzzzxxxxxxyyyyyyyyyyy|
+        -----++-----           |
+        |    ||    |           |
+        | L  || R  |           |
+        |    ||    |           |
+        -----++-----           |
+        |                      |
+        +----------------------+
+    </pre>
+
+    The changes are made in the Grid variable itself, so once this is
+    done the Grid should not be re-read by the CE or serialization
+    code.
+
+    @author James Gallagher */
+
+class GeoConstraint
+{
+public:
+    /** The longitude extents of the constraint bounding box can be expressed
+        two ways: using a 0/359 notation and using a -180/179 notation. I call
+        the 0/359 notation 'pos' and the -180/179 notation 'neg_pos'. */
+    enum Notation {
+        unknown_notation,
+        pos,
+        neg_pos
+    };
+
+    /** Most of the time, latitude starts at the top of an array with
+        positive values and ends up at the bottom with negative ones.
+        But sometimes... the world is upside down. */
+    enum LatitudeSense {
+        unknown_sense,
+        normal,
+        inverted
+    };
+
+private:
+    char *d_array_data;    	//< Holds the Grid's data values
+    int d_array_data_size;	//< Total size (bytes) of the array data
+
+    double *d_lat;              //< Holds the latitude values
+    double *d_lon;              //< Holds the longitude values
+    int d_lat_length;           //< Elements (not bytes) in the latitude vector
+    int d_lon_length;           //< ... longitude vector
+
+    // These four are indexes of the constraint
+    int d_latitude_index_top;
+    int d_latitude_index_bottom;
+    int d_longitude_index_left;
+    int d_longitude_index_right;
+
+    bool d_bounding_box_set;    //< Has the bounding box been set?
+    bool d_longitude_rightmost; //< Is longitude the rightmost dimension?
+
+    Notation d_longitude_notation;
+    LatitudeSense d_latitude_sense;
+
+    Array::Dim_iter d_lon_dim;  //< References the longitude dimension
+    Array::Dim_iter d_lat_dim;  //< References the latitude dimension
+
+    // Sets of string values used to find stuff in attributes
+    set<string> d_coards_lat_units;
+    set<string> d_coards_lon_units;
+
+    set<string> d_lat_names;
+    set<string> d_lon_names;
+
+    // Hide these three automatically provided methods
+    GeoConstraint(const GeoConstraint &param);
+    GeoConstraint &operator=(GeoConstraint &rhs);
+
+protected:
+    /** A protected method that searches for latitude and longitude
+        map vectors and sets six key internal fields. This method
+        returns false if either map cannot be found.
+
+        The d_lon, d_lon_length and d_lon_dim (and matching lat)
+        fields <em>must be set</em> by this method.
+
+        @return True if the maps are found, otherwise False */
+    virtual bool build_lat_lon_maps() = 0;
+
+    /** Are the latitude and longitude dimensions ordered so that this
+	class can properly constrain the data? This method throws
+	Error if lat and lon are not to two 'fastest-varying' (or
+	'rightmost) dimensions. It sets the internal property \e
+	longitude_rightmost if that's true.
+
+	@note Called by the constructor once build_lat_lon_maps() has returned.
+
+	@return True if the lat/lon maps are the two rightmost maps,
+	false otherwise*/
+    virtual bool lat_lon_dimensions_ok() = 0;
+
+    Notation categorize_notation(const double left, const double right) const;
+    void transform_constraint_to_pos_notation(double &left, double &right) const;
+    virtual void transform_longitude_to_pos_notation();
+    virtual void transform_longitude_to_neg_pos_notation();
+    virtual bool is_bounding_box_valid(const double left, const double top,
+					const double right, const double bottom) const;
+    void find_longitude_indeces(double left, double right,
+                                int &longitude_index_left,
+                                int &longitude_index_right) const;
+
+    virtual void transpose_vector(double *src, const int length);
+    virtual void reorder_longitude_map(int longitude_index_left);
+
+    virtual LatitudeSense categorize_latitude() const;
+    void find_latitude_indeces(double top, double bottom, LatitudeSense sense,
+                               int &latitude_index_top,
+                               int &latitude_index_bottom) const;
+
+    virtual void reorder_data_longitude_axis(Array &a, Array::Dim_iter lon_dim);
+    virtual void flip_latitude_within_array(Array &a, int lat_length,
+					    int lon_length);
+
+    friend class GridGeoConstraintTest; // Unit tests
+
+public:
+    /** @name Constructors */
+    //@{
+    GeoConstraint();
+    //@}
+
+    virtual ~GeoConstraint()
+    {
+        delete [] d_lat; d_lat = 0;
+        delete [] d_lon; d_lon = 0;
+        delete [] d_array_data; d_array_data = 0;
+    }
+
+    /** @name Accessors/Mutators */
+    //@{
+    // These are set in reorder_data_longitude_axis()
+    char *get_array_data() const
+    {
+        return d_array_data;
+    }
+    int get_array_data_size() const
+    {
+        return d_array_data_size;
+    }
+
+    double *get_lat() const
+    {
+        return d_lat;
+    }
+    double *get_lon() const
+    {
+        return d_lon;
+    }
+    void set_lat(double *lat)
+    {
+        d_lat = lat;
+    }
+    void set_lon(double *lon)
+    {
+        d_lon = lon;
+    }
+
+    int get_lat_length() const
+    {
+        return d_lat_length;
+    }
+    int get_lon_length() const
+    {
+        return d_lon_length;
+    }
+    void set_lat_length(int len)
+    {
+        d_lat_length = len;
+    }
+    void set_lon_length(int len)
+    {
+        d_lon_length = len;
+    }
+
+    Array::Dim_iter get_lon_dim() const
+    {
+        return d_lon_dim;
+    }
+    Array::Dim_iter get_lat_dim() const
+    {
+        return d_lat_dim;
+    }
+    void set_lon_dim(Array::Dim_iter lon)
+    {
+        d_lon_dim = lon;
+    }
+    void set_lat_dim(Array::Dim_iter lat)
+    {
+        d_lat_dim = lat;
+    }
+
+    // These four are indexes of the constraint
+    int get_latitude_index_top() const
+    {
+        return d_latitude_index_top;
+    }
+    int get_latitude_index_bottom() const
+    {
+        return d_latitude_index_bottom;
+    }
+    void set_latitude_index_top(int top)
+    {
+        d_latitude_index_top = top;
+    }
+    void set_latitude_index_bottom(int bottom)
+    {
+        d_latitude_index_bottom = bottom;
+    }
+
+    int get_longitude_index_left() const
+    {
+        return d_longitude_index_left;
+    }
+    int get_longitude_index_right() const
+    {
+        return d_longitude_index_right;
+    }
+    void set_longitude_index_left(int left)
+    {
+        d_longitude_index_left = left;
+    }
+    void set_longitude_index_right(int right)
+    {
+        d_longitude_index_right = right;
+    }
+
+    bool is_bounding_box_set() const
+    {
+        return d_bounding_box_set;
+    }
+    bool is_longitude_rightmost() const
+    {
+        return d_longitude_rightmost;
+    }
+    void set_longitude_rightmost(bool state)
+    {
+        d_longitude_rightmost = state;
+    }
+
+    Notation get_longitude_notation() const
+    {
+        return d_longitude_notation;
+    }
+    LatitudeSense get_latitude_sense() const
+    {
+        return d_latitude_sense;
+    }
+    void set_longitude_notation(Notation n)
+    {
+        d_longitude_notation = n;
+    }
+    void set_latitude_sense(LatitudeSense l)
+    {
+        d_latitude_sense = l;
+    }
+
+    set<string> get_coards_lat_units() const
+        {
+            return d_coards_lat_units;
+        }
+    set<string> get_coards_lon_units() const
+        {
+            return d_coards_lon_units;
+        }
+
+    set<string> get_lat_names() const
+        {
+            return d_lat_names;
+        }
+    set<string> get_lon_names() const
+        {
+            return d_lon_names;
+        }
+    //@}
+
+    void set_bounding_box(double top, double left, double bottom, double right);
+
+    /** @brief Once the bounding box is set use this method to apply
+        the constraint. */
+    virtual void apply_constraint_to_data() = 0;
+};
+
+} // namespace libdap
+
+#endif // _geo_constraint_h
+
diff --git a/Grid.cc b/Grid.cc
new file mode 100644
index 0000000..9dfd841
--- /dev/null
+++ b/Grid.cc
@@ -0,0 +1,1146 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// implementation for Grid.
+//
+// jhrg 9/15/94
+
+#include "config.h"
+
+// #define DODS_DEBUG
+
+#include <functional>
+#include <algorithm>
+
+#include "Grid.h"
+#include "DDS.h"
+#include "Array.h"  // for downcasts
+#include "util.h"
+#include "InternalErr.h"
+#include "escaping.h"
+
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+void
+Grid::_duplicate(const Grid &s)
+{
+    // Clear out any spurious vars in Constructor::_vars
+    _vars.clear(); // [mjohnson 10 Sep 2009]
+
+    _array_var = s._array_var->ptr_duplicate();
+    _array_var->set_parent(this);
+    _vars.push_back(_array_var); // so the Constructor::Vars_Iter sees it [mjohnson 10 Sep 2009]
+
+    Grid &cs = const_cast<Grid &>(s);
+
+    for (Map_iter i = cs._map_vars.begin(); i != cs._map_vars.end(); i++) {
+        BaseType *btp = (*i)->ptr_duplicate();
+        btp->set_parent(this);
+        _map_vars.push_back(btp);
+        _vars.push_back(btp); // push all map vectors as weak refs into super::_vars which won't delete them [mjohnson 10 Sep 2009]
+    }
+
+}
+
+/** The Grid constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+
+    @brief The Grid constructor.
+*/
+Grid::Grid(const string &n) : Constructor(n, dods_grid_c), _array_var(0)
+{}
+
+/** The Grid server-side constructor requires the name of the variable
+    to be created and the dataset name from which this variable is created.
+    Used when creating variables on the server side.
+
+    @param n A string containing the name of the variable to be
+    created.
+    @param d A string containing the name of the dataset from which this
+    variable is being created.
+
+    @brief The Grid constructor.
+*/
+Grid::Grid(const string &n, const string &d)
+    : Constructor(n, d, dods_grid_c), _array_var(0)
+{}
+
+/** @brief The Grid copy constructor. */
+Grid::Grid(const Grid &rhs) : Constructor(rhs)
+{
+    _duplicate(rhs);
+}
+
+Grid::~Grid()
+{
+    delete _array_var; _array_var = 0;
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        BaseType *btp = *i ;
+        delete btp ; btp = 0;
+    }
+}
+
+BaseType *
+Grid::ptr_duplicate()
+{
+    return new Grid(*this);
+}
+
+Grid &
+Grid::operator=(const Grid &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    delete _array_var; _array_var = 0;
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        BaseType *btp = *i ;
+        delete btp ;
+    }
+
+    // this doesn't copy Constructor::_vars so...
+    dynamic_cast<Constructor &>(*this) = rhs;
+
+    // we do it in here...
+    _duplicate(rhs);
+
+    return *this;
+}
+
+int
+Grid::element_count(bool leaves)
+{
+    if (!leaves)
+        return _map_vars.size() + 1;
+    else {
+        int i = 0;
+        for (Map_iter j = _map_vars.begin(); j != _map_vars.end(); j++) {
+            j += (*j)->element_count(leaves);
+        }
+
+		if (!get_array())
+			throw InternalErr(__FILE__, __LINE__, "No Grid arry!");
+
+        i += get_array()->element_count(leaves);
+        return i;
+    }
+}
+
+void
+Grid::set_send_p(bool state)
+{
+    _array_var->set_send_p(state);
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        (*i)->set_send_p(state);
+    }
+
+    BaseType::set_send_p(state);
+}
+
+void
+Grid::set_read_p(bool state)
+{
+    _array_var->set_read_p(state);
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        (*i)->set_read_p(state);
+    }
+
+    BaseType::set_read_p(state);
+}
+
+void
+Grid::set_in_selection(bool state)
+{
+    _array_var->set_in_selection(state);
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        (*i)->set_in_selection(state);
+    }
+
+    BaseType::set_in_selection(state);
+}
+
+unsigned int
+Grid::width()
+{
+    unsigned int sz = _array_var->width();
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        sz += (*i)->width();
+    }
+
+    return sz;
+}
+
+void
+Grid::intern_data(ConstraintEvaluator &eval, DDS &dds)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+    dds.timeout_off();
+
+    if (_array_var->send_p())
+        _array_var->intern_data(eval, dds);
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        if ((*i)->send_p()) {
+            (*i)->intern_data(eval, dds);
+        }
+    }
+}
+
+bool
+Grid::serialize(ConstraintEvaluator &eval, DDS &dds,
+                Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    // Re ticket 560: Get an object from eval that describes how to sample
+    // and rearrange the data, then perform those actions. Alternative:
+    // implement this as a selection function.
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    if (_array_var->send_p())
+        _array_var->serialize(eval, dds, m, false);
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        if ((*i)->send_p()) {
+            (*i)->serialize(eval, dds, m, false);
+        }
+    }
+
+    return true;
+}
+
+bool
+Grid::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
+{
+    _array_var->deserialize(um, dds, reuse);
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        (*i)->deserialize(um, dds, reuse);
+    }
+
+    return false;
+}
+
+/** @brief Returns the size of the Grid type.
+
+    Use the <tt>val2buf()</tt>
+    functions of the member elements to insert values into the Grid
+    buffer.
+
+    @return The size (in bytes) of the value's representation.  */
+unsigned int
+Grid::val2buf(void *, bool)
+{
+    return sizeof(Grid);
+}
+
+/** Returns the size of the Grid type.  Use the <tt>buf2val()</tt>
+    functions of the member elements to read values from the Grid
+    buffer. */
+unsigned int
+Grid::buf2val(void **)
+{
+    return sizeof(Grid);
+}
+
+BaseType *
+Grid::var(const string &n, btp_stack &s)
+{
+    return var(n, true, &s);
+}
+
+/** Note the parameter <i>exact_match</i> is not used by this
+    member function.
+
+    @see BaseType */
+BaseType *
+Grid::var(const string &n, bool, btp_stack *s)
+{
+    string name = www2id(n);
+
+    if (_array_var->name() == name) {
+        if (s)
+            s->push(static_cast<BaseType *>(this));
+        return _array_var;
+    }
+
+    for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+        if ((*i)->name() == name) {
+            if (s)
+                s->push(static_cast<BaseType *>(this));
+            return *i;
+        }
+    }
+
+    return 0;
+}
+
+/** Add an array or map to the Grid.
+
+    The original version of this method required that the \c part parameter
+    be present. However, this complicates using the class from a parser
+    (e.g., the schema-based XML parser). I have modified the method so that
+    if \c part is nil (the default), then the first variable added is the
+    array and subsequent variables are maps. This matches the behavior in the
+    Java DAP implementation.
+
+    @param bt Array or Map variable
+    @param part is this an array or a map. If not present, first \c bt is the
+    array and subsequent <tt>bt</tt>s are maps. */
+void
+Grid::add_var(BaseType *bt, Part part)
+{
+    if (!bt) {
+        throw InternalErr(__FILE__, __LINE__,
+                          "Passing NULL pointer as variable to be added.");
+    }
+
+    if (part == array && _array_var) {
+      // Avoid leaking memory...  Function is add, not set, so it is an error to call again for the array part.
+      throw InternalErr(__FILE__, __LINE__, "Error: Grid::add_var called with part==Array, but the array was already set!");
+    }
+
+    // Set to the clone of bt if we get that far.
+    BaseType* bt_clone = 0;
+
+    switch (part) {
+
+    case array: {
+        // Refactored to use new set_array ([mjohnson 11 nov 2009])
+        Array* p_arr = dynamic_cast<Array*>(bt);
+        // avoid obvious broken semantics
+        if (!p_arr) {
+          throw InternalErr(__FILE__, __LINE__,
+              "Grid::add_var(): with Part==array: object is not an Array!");
+        }
+        // Add it as a copy to preserve old semantics.  This sets parent too.
+        bt_clone = p_arr->ptr_duplicate();
+        set_array(static_cast<Array*>(bt_clone));
+    }
+    break;
+
+    case maps: {
+            bt_clone = bt->ptr_duplicate();
+            bt_clone->set_parent(this);
+            _map_vars.push_back(bt_clone);
+        }
+    break;
+
+    default: {
+        if (!_array_var) {
+            // Refactored to use new set_array ([mjohnson 11 nov 2009])
+            Array* p_arr = dynamic_cast<Array*>(bt);
+            // avoid obvious broken semantics
+            if (!p_arr) {
+              throw InternalErr(__FILE__, __LINE__,
+                  "Grid::add_var(): with Part==array: object is not an Array!");
+            }
+            // Add it as a copy to preserve old semantics.  This sets parent too.
+            bt_clone = p_arr->ptr_duplicate();
+            set_array(static_cast<Array*>(bt_clone));
+        }
+        else {
+            bt_clone = bt->ptr_duplicate();
+            bt_clone->set_parent(this);
+            _map_vars.push_back(bt_clone);
+        }
+    }
+    break;
+  }// switch
+
+  // if we get ehre without exception, add the cloned object to the superclass variable iterator
+  // mjohnson 10 Sep 2009
+  // Add it to the superclass _vars list so we can iterate on superclass vars
+  if (bt_clone) {
+    _vars.push_back(bt_clone);
+  }
+}
+
+/**
+ * Set the Array part of the Grid to point to the memory
+ * p_new_arr.  Grid takes control of the memory (no copy
+ * is made).
+ * If there already exists an array portion, the old
+ * one will be deleted to avoid leaks.
+ * @param p_new_arr  the object to store as the array
+ *                   part of the grid.
+ */
+void
+Grid::set_array(Array* p_new_arr)
+{
+  if (!p_new_arr) {
+    throw InternalErr(__FILE__, __LINE__,
+        "Grid::set_array(): Cannot set to null!");
+  }
+  // Make sure not same memory, this would be evil.
+  if (p_new_arr == _array_var) {
+      return;
+   }
+  // clean out any old array
+  delete _array_var; _array_var = 0;
+  // Set the new, with parent
+  _array_var = p_new_arr;
+  _array_var->set_parent(this);
+}
+
+/**
+ * Add the given array p_new_map as a new map
+ * vector for the Grid.
+ *
+ * If add_as_copy, p_new_map will be cloned
+ * and the copy added, leaving p_new_map
+ * in the control of the caller.
+ *
+ * If !add_as_copy, p_new_map will be explicitly
+ * added as the new map vector.
+ *
+ * The actual Array* in the Grid will be returned,
+ * either the address of the COPY if add_as_copy,
+ * else p_new_map itself if !add_as_copy.
+ *
+ * It is an exception for p_new_map to be null.
+ *
+ * @param p_new_map  the map we want to add
+ * @param add_as_copy whether to add p_new_map
+ *             explicitly and take onwership of memory
+ *             or to add a clone of it and leave control
+ *             to caller.
+ * @return the actual object stored in the Grid, whether
+ *         p_new_map, or the address of the copy.
+ *
+ */
+Array*
+Grid::add_map(Array* p_new_map, bool add_as_copy)
+{
+  if (!p_new_map) {
+    throw InternalErr(__FILE__, __LINE__,
+        "Grid::add_map(): cannot have p_new_map null!");
+  }
+
+  if (add_as_copy) {
+    p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
+  }
+
+  p_new_map->set_parent(this);
+  _map_vars.push_back(p_new_map);
+  _vars.push_back(p_new_map); // allow superclass iter to work as well.
+
+  // return the one that got put into the Grid.
+  return p_new_map;
+}
+
+/**
+ * Add pMap (or a clone if addAsCopy) to the
+ * FRONT of the maps list.  This is needed if
+ * we are preserving Grid semantics but want to
+ * add a new OUTER dimension, whereas add_map
+ * appends to the end making a new INNER dimension.
+ * @param p_new_map the map to add or copy and add
+ * @param add_copy if true, copy pMap and add the copy.
+ * @return The actual memory stored in the Grid,
+ *      either pMap (if !add_copy) or the ptr to
+ *      the clone (if add_copy).
+ */
+Array*
+Grid::prepend_map(Array* p_new_map, bool add_copy)
+{
+  if (add_copy)
+    {
+      p_new_map = static_cast<Array*>(p_new_map->ptr_duplicate());
+    }
+
+  p_new_map->set_parent(this);
+  _map_vars.insert(_map_vars.begin(), p_new_map);
+  _vars.insert(_vars.begin(), p_new_map); // allow superclass iter to work as well.
+
+   // return the one that got put into the Grid.
+   return p_new_map;
+}
+
+/** @brief Returns the Grid Array.
+    @deprecated
+    @see get_array() */
+BaseType *
+Grid::array_var()
+{
+    return _array_var;
+}
+
+/** @brief Returns the Grid Array.
+    This method returns the array using an Array*, so no cast is required.
+    @return A pointer to the Grid's (dependent) data array */
+Array *
+Grid::get_array()
+{
+    Array *a = dynamic_cast<Array*>(_array_var);
+    if (a)
+        return a;
+    else
+        throw InternalErr(__FILE__, __LINE__, "bad Cast");
+}
+
+/** @brief Returns an iterator referencing the first Map vector. */
+Grid::Map_iter
+Grid::map_begin()
+{
+    return _map_vars.begin() ;
+}
+
+/** Returns an iterator referencing the end of the list of Map vectors.
+    It does not reference the last Map vector */
+Grid::Map_iter
+Grid::map_end()
+{
+    return _map_vars.end() ;
+}
+
+/** @brief Returns an iterator referencing the first Map vector. */
+Grid::Map_riter
+Grid::map_rbegin()
+{
+    return _map_vars.rbegin() ;
+}
+
+/** Returns an iterator referencing the end of the list of Map vectors.
+    It does not reference the last Map vector */
+Grid::Map_riter
+Grid::map_rend()
+{
+    return _map_vars.rend() ;
+}
+
+/** Return the iterator for the \e ith map.
+    @param i the index
+    @return The corresponding  Vars_iter */
+Grid::Map_iter
+Grid::get_map_iter(int i)
+{
+    return _map_vars.begin() + i;
+}
+
+/** Returns the number of components in the Grid object.  This is
+    equal to one plus the number of Map vectors.  If there is a
+    constraint expression in effect, the number of dimensions needed
+    may be smaller than the actual number in the stored data.  (Or
+    the Array might not even be requested.) In this case, a user can
+    request the smaller number with the <i>constrained</i> flag.
+
+    @brief Returns the number of components in the Grid object.
+    @return The number of components in the Grid object.
+    @param constrained If TRUE, the function returns the number of
+    components contained in the constrained Grid.  Since a
+    constraint expression might well eliminate one or more of the
+    Grid dimensions, this number can be lower than the actual number
+    of components.  If this parameter is FALSE (the default), the
+    actual number of components will be returned.  */
+int
+Grid::components(bool constrained)
+{
+    int comp;
+
+    if (constrained) {
+        comp = _array_var->send_p() ? 1 : 0;
+
+        for (Map_iter i = _map_vars.begin(); i != _map_vars.end(); i++) {
+            if ((*i)->send_p()) {
+                comp++;
+            }
+        }
+    }
+    else {
+        comp = 1 + _map_vars.size();
+    }
+
+    return comp;
+}
+
+void Grid::transfer_attributes(AttrTable *at_container)
+{
+    AttrTable *at = at_container->get_attr_table(name());
+
+    if (at) {
+	at->set_is_global_attribute(false);
+
+	array_var()->transfer_attributes(at);
+
+	Map_iter map = map_begin();
+	while (map != map_end()) {
+	    (*map)->transfer_attributes(at);
+	    map++;
+	}
+
+	// Trick: If an attribute that's within the container 'at' still has its
+	// is_global_attribute property set, then it's not really a global attr
+	// but instead an attribute that belongs to this Grid.
+	AttrTable::Attr_iter at_p = at->attr_begin();
+	while (at_p != at->attr_end()) {
+	    if (at->is_global_attribute(at_p)) {
+		if (at->get_attr_type(at_p) == Attr_container)
+		    get_attr_table().append_container(new AttrTable(
+			    *at->get_attr_table(at_p)), at->get_name(at_p));
+		else
+		    get_attr_table().append_attr(at->get_name(at_p),
+			    at->get_type(at_p), at->get_attr_vector(at_p));
+	    }
+
+	    at_p++;
+	}
+    }
+}
+
+// When projected (using whatever the current constraint provides in the way
+// of a projection), is the object still a Grid?
+
+/** Returns TRUE if the current projection will yield a Grid that
+    will pass the <tt>check_semantics()</tt> function. A Grid that, when
+    projected, will not pass the <tt>check_semantics()</tt> function must
+    be sent as either a Structure of Arrays or a single Array
+    depending on the projection.
+
+    The function first checks to see whether the Array is present.
+    Then, for each dimension in the Array part, the function checks
+    the corresponding Map vector to make sure it is present in the
+    projected Grid. If for each projected dimension in the Array
+    component, there is a matching Map vector, then the Grid is
+    valid.
+
+    @return TRUE if the projected grid is still a Grid.  FALSE
+    otherwise.
+*/
+bool
+Grid::projection_yields_grid()
+{
+    // For each dimension in the Array part, check the corresponding Map
+    // vector to make sure it is present in the projected Grid. If for each
+    // projected dimension in the Array component, there is a matching Map
+    // vector, then the Grid is valid.
+    bool valid = true;
+    Array *a = (Array *)_array_var;
+
+    // Don't bother checking if the Array component is not included.
+    if (!a->send_p())
+        return false;
+
+    // If only one part is being sent, it's clearly not a grid (it must be
+    // the array part of the Grid that's being sent (given that the above
+    // test passed and the array is being sent).
+    if (components(true) == 1)
+	return false;
+
+    Array::Dim_iter d = a->dim_begin() ;
+    Map_iter m = map_begin() ;
+
+    while (valid && d != a->dim_end() && m != map_end()) {
+	Array &map = dynamic_cast<Array&>(**m);
+        if (a->dimension_size(d, true) && map.send_p()) {
+            // Check the matching Map vector; the Map projection must equal
+            // the Array dimension projection
+            Array::Dim_iter fd = map.dim_begin(); // Maps have only one dim!
+            valid = map.dimension_start(fd, true) == a->dimension_start(d, true)
+                    && map.dimension_stop(fd, true) == a->dimension_stop(d, true)
+                    && map.dimension_stride(fd, true) == a->dimension_stride(d, true);
+        }
+        else {
+           valid = false;
+        }
+
+	d++, m++;
+    }
+
+    return valid;
+}
+
+/** For each of the Array and Maps in this Grid, call clear_constraint(). */
+void
+Grid::clear_constraint()
+{
+    dynamic_cast<Array&>(*_array_var).clear_constraint();
+    for (Map_iter m = map_begin(); m != map_end(); ++m)
+        dynamic_cast<Array&>(*(*m)).clear_constraint();
+}
+
+#if FILE_METHODS
+void
+Grid::print_decl(FILE *out, string space, bool print_semi,
+                 bool constraint_info, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    // The problem with the above is that if two Grids are projected and each
+    // contain one variable, say a map, and it happens to have the same name
+    // in each Grid, then without the enclosing Structures, the returned dataset
+    // has two variables with the same name at the same lexical level. So I'm
+    // removing the code above.
+    if (constrained && !projection_yields_grid()) {
+        fprintf(out, "%sStructure {\n", space.c_str()) ;
+
+        _array_var->print_decl(out, space + "    ", true, constraint_info,
+                               constrained);
+
+        for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
+            (*i)->print_decl(out, space + "    ", true,
+                             constraint_info, constrained);
+        }
+
+        fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
+    }
+    else {
+        // The number of elements in the (projected) Grid must be such that
+        // we have a valid Grid object; send it as such.
+        fprintf(out, "%s%s {\n", space.c_str(), type_name().c_str()) ;
+
+        fprintf(out, "%s  Array:\n", space.c_str()) ;
+        _array_var->print_decl(out, space + "    ", true, constraint_info,
+                               constrained);
+
+        fprintf(out, "%s  Maps:\n", space.c_str()) ;
+        for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
+            (*i)->print_decl(out, space + "    ", true,
+                             constraint_info, constrained);
+        }
+
+        fprintf(out, "%s} %s", space.c_str(), id2www(name()).c_str()) ;
+    }
+
+    if (constraint_info) {
+        if (send_p())
+            fprintf( out, ": Send True");
+        else
+            fprintf( out, ": Send False");
+    }
+
+    if (print_semi)
+        fprintf(out, ";\n") ;
+
+    return;
+}
+#endif
+
+void
+Grid::print_decl(ostream &out, string space, bool print_semi,
+                 bool constraint_info, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    // See comment for the FILE* version of this method.
+    if (constrained && !projection_yields_grid()) {
+	out << space << "Structure {\n" ;
+
+        _array_var->print_decl(out, space + "    ", true, constraint_info,
+                               constrained);
+
+        for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
+            (*i)->print_decl(out, space + "    ", true,
+                             constraint_info, constrained);
+        }
+
+	out << space << "} " << id2www(name()) ;
+    }
+    else {
+        // The number of elements in the (projected) Grid must be such that
+        // we have a valid Grid object; send it as such.
+	out << space << type_name() << " {\n" ;
+
+	out << space << "  Array:\n" ;
+        _array_var->print_decl(out, space + "    ", true, constraint_info,
+                               constrained);
+
+	out << space << "  Maps:\n" ;
+        for (Map_citer i = _map_vars.begin(); i != _map_vars.end(); i++) {
+            (*i)->print_decl(out, space + "    ", true,
+                             constraint_info, constrained);
+        }
+
+	out << space << "} " << id2www(name()) ;
+    }
+
+    if (constraint_info) {
+        if (send_p())
+            out << ": Send True";
+        else
+            out << ": Send False";
+    }
+
+    if (print_semi)
+	out << ";\n" ;
+
+    return;
+}
+
+#if FILE_METHODS
+class PrintMapField : public unary_function<BaseType *, void>
+{
+    FILE *d_out;
+    string d_space;
+    bool d_constrained;
+    string d_tag;
+public:
+    PrintMapField(FILE *o, string s, bool c, const string &t = "Map")
+            : d_out(o), d_space(s), d_constrained(c), d_tag(t)
+    {}
+
+    void operator()(BaseType *btp)
+    {
+        Array *a = dynamic_cast<Array*>(btp);
+        if (!a)
+            throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
+        a->print_xml_core(d_out, d_space, d_constrained, d_tag);
+    }
+};
+
+void
+Grid::print_xml(FILE *out, string space, bool constrained)
+{
+    if (constrained && !send_p())
+         return;
+
+     if (constrained && !projection_yields_grid()) {
+         fprintf(out, "%s<Structure", space.c_str());
+         if (!name().empty())
+             fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
+
+         fprintf(out, ">\n");
+
+         get_attr_table().print_xml(out, space + "    ", constrained);
+
+         get_array()->print_xml(out, space + "    ", constrained);
+
+         for_each(map_begin(), map_end(),
+                  PrintMapField(out, space + "    ", constrained, "Array"));
+
+         fprintf(out, "%s</Structure>\n", space.c_str());
+     }
+     else {
+         // The number of elements in the (projected) Grid must be such that
+         // we have a valid Grid object; send it as such.
+         fprintf(out, "%s<Grid", space.c_str());
+         if (!name().empty())
+             fprintf(out, " name=\"%s\"", id2xml(name()).c_str());
+
+         fprintf(out, ">\n");
+
+         get_attr_table().print_xml(out, space + "    ", constrained);
+
+         get_array()->print_xml(out, space + "    ", constrained);
+
+         for_each(map_begin(), map_end(),
+                  PrintMapField(out, space + "    ", constrained));
+
+         fprintf(out, "%s</Grid>\n", space.c_str());
+     }
+}
+#endif
+
+class PrintMapFieldStrm : public unary_function<BaseType *, void>
+{
+    ostream &d_out;
+    string d_space;
+    bool d_constrained;
+    string d_tag;
+public:
+    PrintMapFieldStrm(ostream &o, string s, bool c, const string &t = "Map")
+            : d_out(o), d_space(s), d_constrained(c), d_tag(t)
+    {}
+
+    void operator()(BaseType *btp)
+    {
+        Array *a = dynamic_cast<Array*>(btp);
+        if (!a)
+            throw InternalErr(__FILE__, __LINE__, "Expected an Array.");
+        a->print_xml_core(d_out, d_space, d_constrained, d_tag);
+    }
+};
+
+void
+Grid::print_xml(ostream &out, string space, bool constrained)
+{
+    if (constrained && !send_p())
+        return;
+
+    if (constrained && !projection_yields_grid()) {
+        out << space << "<Structure" ;
+        if (!name().empty())
+            out << " name=\"" << id2xml(name()) << "\"" ;
+
+        out << ">\n" ;
+
+        get_attr_table().print_xml(out, space + "    ", constrained);
+
+        get_array()->print_xml(out, space + "    ", constrained);
+
+        for_each(map_begin(), map_end(),
+                 PrintMapFieldStrm(out, space + "    ", constrained, "Array"));
+
+        out << space << "</Structure>\n" ;
+    }
+    else {
+        // The number of elements in the (projected) Grid must be such that
+        // we have a valid Grid object; send it as such.
+        out << space << "<Grid" ;
+        if (!name().empty())
+            out << " name=\"" << id2xml(name()) << "\"" ;
+
+        out << ">\n" ;
+
+        get_attr_table().print_xml(out, space + "    ", constrained);
+
+        get_array()->print_xml(out, space + "    ", constrained);
+
+        for_each(map_begin(), map_end(),
+                 PrintMapFieldStrm(out, space + "    ", constrained));
+
+        out << space << "</Grid>\n" ;
+    }
+}
+
+#if FILE_METHODS
+void
+Grid::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = ") ;
+    }
+
+    // If we are printing a value on the client-side, projection_yields_grid
+    // should not be called since we don't *have* a projection without a
+    // contraint. I think that if we are here and send_p() is not true, then
+    // the value of this function should be ignored. 4/6/2000 jhrg
+    bool pyg = projection_yields_grid(); // hack 12/1/99 jhrg
+    if (pyg || !send_p())
+        fprintf(out, "{  Array: ") ;
+    else
+        fprintf(out, "{") ;
+    _array_var->print_val(out, "", false);
+    if (pyg || !send_p())
+        fprintf(out, "  Maps: ") ;
+    for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
+         i++, (void)(i != _map_vars.end() && fprintf(out, ", "))) {
+        (*i)->print_val(out, "", false);
+    }
+    fprintf(out, " }") ;
+
+    if (print_decl_p)
+        fprintf(out, ";\n") ;
+}
+#endif
+
+void
+Grid::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " ;
+    }
+
+    // If we are printing a value on the client-side, projection_yields_grid
+    // should not be called since we don't *have* a projection without a
+    // Constraint. I think that if we are here and send_p() is not true, then
+    // the value of this function should be ignored. 4/6/2000 jhrg
+    bool pyg = projection_yields_grid(); // hack 12/1/99 jhrg
+    if (pyg || !send_p())
+	out << "{  Array: " ;
+    else
+	out << "{" ;
+    _array_var->print_val(out, "", false);
+    if (pyg || !send_p())
+	out << "  Maps: " ;
+    for (Map_citer i = _map_vars.begin(); i != _map_vars.end();
+         i++, (void)(i != _map_vars.end() && out << ", ")) {
+        (*i)->print_val(out, "", false);
+    }
+    out << " }" ;
+
+    if (print_decl_p)
+	out << ";\n" ;
+}
+
+// Grids have ugly semantics.
+
+/** @brief Return true if this Grid is well formed.
+
+    The array dimensions and number of map vectors must match and
+    both the array and maps must be of simple-type elements. */
+bool
+Grid::check_semantics(string &msg, bool all)
+{
+    if (!BaseType::check_semantics(msg))
+        return false;
+
+    msg = "";
+
+    if (!_array_var) {
+        msg += "Null grid base array in `" + name() + "'\n";
+        return false;
+    }
+
+    // Is it an array?
+    if (_array_var->type() != dods_array_c) {
+        msg += "Grid `" + name() + "'s' member `" + _array_var->name() + "' must be an array\n";
+        return false;
+    }
+
+    Array *av = (Array *)_array_var; // past test above, must be an array
+
+    // Array must be of a simple_type.
+    if (!av->var()->is_simple_type()) {
+        msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
+        return false;
+    }
+
+    // enough maps?
+    if ((unsigned)_map_vars.size() != av->dimensions()) {
+        msg += "The number of map variables for grid `" + this->name() + "' does not match the number of dimensions of `";
+        msg += av->name() + "'\n";
+        return false;
+    }
+
+    const string array_var_name = av->name();
+    Array::Dim_iter asi = av->dim_begin() ;
+    for (Map_iter mvi = _map_vars.begin();
+         mvi != _map_vars.end(); mvi++, asi++) {
+
+        BaseType *mv = *mvi;
+
+        // check names
+        if (array_var_name == mv->name()) {
+            msg += "Grid map variable `" + mv->name() + "' conflicts with the grid array name in grid `" + name() + "'\n";
+            return false;
+        }
+        // check types
+        if (mv->type() != dods_array_c) {
+            msg += "Grid map variable  `" + mv->name() + "' is not an array\n";
+            return false;
+        }
+
+        Array *mv_a = (Array *)mv; // downcast to (Array *)
+
+        // Array must be of a simple_type.
+        if (!mv_a->var()->is_simple_type()) {
+            msg += "The field variable `" + this->name() + "' must be an array of simple type elements (e.g., int32, String)\n";
+            return false;
+        }
+
+        // check shape
+        if (mv_a->dimensions() != 1) {// maps must have one dimension
+            msg += "Grid map variable  `" + mv_a->name() + "' must be only one dimension\n";
+            return false;
+        }
+        // size of map must match corresponding array dimension
+        Array::Dim_iter mv_asi = mv_a->dim_begin() ;
+        int mv_a_size = mv_a->dimension_size(mv_asi) ;
+        int av_size = av->dimension_size(asi) ;
+        if (mv_a_size != av_size) {
+            msg += "Grid map variable  `" + mv_a->name() + "'s' size does not match the size of array variable '";
+            msg += _array_var->name() + "'s' cooresponding dimension\n";
+            return false;
+        }
+    }
+
+    if (all) {
+        if (!_array_var->check_semantics(msg, true))
+            return false;
+        for (Map_iter mvi = _map_vars.begin(); mvi != _map_vars.end(); mvi++) {
+            if (!(*mvi)->check_semantics(msg, true)) {
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Grid::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Grid::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    Constructor::dump(strm) ;
+    if (_array_var) {
+        strm << DapIndent::LMarg << "array var: " << endl ;
+        DapIndent::Indent() ;
+        _array_var->dump(strm) ;
+        DapIndent::UnIndent() ;
+    }
+    else {
+        strm << DapIndent::LMarg << "array var: null" << endl ;
+    }
+    strm << DapIndent::LMarg << "map var: " << endl ;
+    DapIndent::Indent() ;
+    Map_citer i = _map_vars.begin() ;
+    Map_citer ie = _map_vars.end() ;
+    for (; i != ie; i++) {
+        (*i)->dump(strm) ;
+    }
+    DapIndent::UnIndent() ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Grid.h b/Grid.h
new file mode 100644
index 0000000..0ffef27
--- /dev/null
+++ b/Grid.h
@@ -0,0 +1,223 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface to the Grid ctor class. Grids contain a single array (the `main'
+// array) of dimension N and N single dimension arrays (map arrays). For any
+// dimension n of the main array, the size of the nth map array must match
+// the size of the main array's nth dimension. Grids are used to map
+// non-integer scales to multidimensional point data.
+//
+// jhrg 9/15/94
+
+#ifndef _grid_h
+#define _grid_h 1
+
+#include <vector>
+
+//#include "Pix.h"
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _array_h
+#include "Array.h"
+#endif
+
+#ifndef _constructor_h
+#include "Constructor.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** The Grid data type is a collection of an Array and a set of ``Map''
+    vectors.  The Map vectors are one-dimensional arrays corresponding
+    to each dimension of the central Array.  Using this scheme, a Grid
+    can represent, in a rectilinear array, data which is not in
+    reality rectilinear.  An example will help make it clear.
+
+    Assume that the following array contains measurements of some real
+    quantity, conducted at nine different points in space:
+
+    <pre>
+    A = [ 1  2  3  4 ]
+        [ 2  4  6  8 ]
+        [ 3  6  9  12]
+    </pre>
+
+    To locate this Array in the real world, we could note the location
+    of one corner of the grid, and the grid spacing.  This would allow
+    us to calculate the location of any of the other points of the
+    Array.
+
+    This approach will not work, however, unless the grid spacing is
+    precisely regular.  If the distance between Row 1 and Row 2 is not
+    the same as the distance between Row 2 and Row 3, the scheme will
+    break down.  The solution is to equip the Array with two Map
+    vectors that define the location of each row or column of the
+    array:
+
+    <pre>
+         A = [ 1  2  3  4 ] Row = [ 0 ]
+             [ 2  4  6  8 ]       [ 3 ]
+             [ 3  6  9  12]       [ 8 ]
+
+    Column = [ 0  2  8  27]
+    </pre>
+
+    The real location of the point in the first row and column of the
+    array is now exactly fixed at (0,0), and the point in the last row
+    and last column is at (8,27).
+
+    The Grid data type has two parts: an Array, and a singly-linked
+    list of Map vectors to describe the Array.  The access functions
+    for this class include a function to return the Array
+    (<tt>get_array()</tt>), and a set of functions for cycling through the
+    list of Map vectors.
+
+    @todo Move, in some sense, the _map_vars up to Constructor. Look at using
+    Constructor's _var field for these.
+    @todo Along the same lines as the previous item, consider removing the
+    Part enum and adopting the convention that the first variable added is
+    the array and any subsequent variables are maps.
+
+    @brief Holds the Grid data type.
+    @see Array
+    */
+
+class Grid: public Constructor
+{
+private:
+    BaseType *_array_var;
+    std::vector<BaseType *> _map_vars;
+
+protected: // subclasses need access [mjohnson 11 nov 2009]
+    void _duplicate(const Grid &s);
+
+public:
+
+    Grid(const string &n);
+    Grid(const string &n, const string &d);
+    Grid(const Grid &rhs);
+    virtual ~Grid();
+
+    typedef std::vector<BaseType *>::const_iterator Map_citer ;
+    typedef std::vector<BaseType *>::iterator Map_iter ;
+    typedef std::vector<BaseType *>::reverse_iterator Map_riter ;
+
+
+    Grid &operator=(const Grid &rhs);
+    virtual BaseType *ptr_duplicate();
+
+    virtual int element_count(bool leaves = false);
+
+    virtual void set_send_p(bool state);
+    virtual void set_read_p(bool state);
+    virtual void set_in_selection(bool state);
+
+    virtual BaseType *var(const string &n, bool exact = true,
+                          btp_stack *s = 0);
+
+    virtual BaseType *var(const string &n, btp_stack &s);
+
+    virtual void add_var(BaseType *bt, Part part);
+
+    virtual void set_array(Array* p_new_arr);
+    virtual Array* add_map(Array* p_new_map, bool add_copy);
+    virtual Array* prepend_map(Array* p_new_map, bool add_copy);
+
+    BaseType *array_var();
+    Array *get_array();
+
+
+    virtual unsigned int width();
+
+    virtual int components(bool constrained = false);
+
+    virtual bool projection_yields_grid();
+
+    virtual void clear_constraint();
+
+    virtual void intern_data(ConstraintEvaluator &eval, DDS &dds);
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *buf, bool reuse = false);
+
+    virtual unsigned int buf2val(void **val);
+
+    virtual void print_decl(ostream &out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+
+    virtual void print_xml(ostream &out, string space = "    ",
+                           bool constrained = false);
+
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+#if FILE_METHODS
+    virtual void print_decl(FILE *out, string space = "    ",
+                            bool print_semi = true,
+                            bool constraint_info = false,
+                            bool constrained = false);
+    virtual void print_xml(FILE *out, string space = "    ",
+                           bool constrained = false);
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+
+    virtual void transfer_attributes(AttrTable *at_container);
+
+    virtual bool check_semantics(string &msg, bool all = false);
+
+    Map_iter map_begin() ;
+    Map_iter map_end() ;
+    Map_riter map_rbegin() ;
+    Map_riter map_rend() ;
+    Map_iter get_map_iter(int i);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _grid_h
+
diff --git a/GridGeoConstraint.cc b/GridGeoConstraint.cc
new file mode 100644
index 0000000..09dc295
--- /dev/null
+++ b/GridGeoConstraint.cc
@@ -0,0 +1,396 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// The Grid Selection Expression Clause class.
+
+
+#include "config.h"
+
+static char id[] not_used =
+    { "$Id: GridGeoConstraint.cc 24281 2011-03-09 00:22:31Z jimg $"
+    };
+
+#include <cmath>
+
+#include <iostream>
+#include <sstream>
+
+//#define DODS_DEBUG
+
+#include "debug.h"
+#include "dods-datatypes.h"
+#include "GridGeoConstraint.h"
+#include "Float64.h"
+
+#include "Error.h"
+#include "InternalErr.h"
+#include "ce_functions.h"
+#include "util.h"
+
+using namespace std;
+
+namespace libdap {
+
+/** @brief Initialize GeoConstraint with a Grid.
+
+    @param grid Set the GeoConstraint to use this Grid variable. It is the
+    caller's responsibility to ensure that the value \e grid is a valid Grid
+    variable.
+ */
+GridGeoConstraint::GridGeoConstraint(Grid *grid)
+        : GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0)
+{
+    if (d_grid->get_array()->dimensions() < 2
+        || d_grid->get_array()->dimensions() > 3)
+        throw Error("The geogrid() function works only with Grids of two or three dimensions.");
+
+    // Is this Grid a geo-referenced grid? Throw Error if not.
+    if (!build_lat_lon_maps())
+        throw Error(string("The grid '") + d_grid->name()
+                    + "' does not have identifiable latitude/longitude map vectors.");
+
+    if (!lat_lon_dimensions_ok())
+        throw Error("The geogrid() function will only work when the Grid's Longitude and Latitude\nmaps are the rightmost dimensions.");
+}
+
+GridGeoConstraint::GridGeoConstraint(Grid *grid, Array *lat, Array *lon)
+        : GeoConstraint(), d_grid(grid), d_latitude(0), d_longitude(0)
+{
+    if (d_grid->get_array()->dimensions() < 2
+        || d_grid->get_array()->dimensions() > 3)
+        throw Error("The geogrid() function works only with Grids of two or three dimensions.");
+
+    // Is this Grid a geo-referenced grid? Throw Error if not.
+    if (!build_lat_lon_maps(lat, lon))
+        throw Error(string("The grid '") + d_grid->name()
+                    + "' does not have valid latitude/longitude map vectors.");
+
+
+    if (!lat_lon_dimensions_ok())
+        throw Error("The geogrid() function will only work when the Grid's Longitude and Latitude\nmaps are the rightmost dimensions.");
+}
+
+/** A private method called by the constructor that searches for latitude
+    and longitude map vectors. This method returns false if either map
+    cannot be found. It assumes that the d_grid and d_dds fields are set.
+
+    The d_longitude, d_lon, d_lon_length and d_lon_grid_dim (and matching
+    lat) fields are modified.
+
+    @note Rules used to find Maps:<ul>
+    <li>Latitude: If the Map has a units attribute of "degrees_north",
+    "degree_north", "degree_N", or "degrees_N"</li>
+    <li>Longitude: If the map has a units attribute of "degrees_east"
+    (eastward positive), "degree_east", "degree_E", or "degrees_E"</li>
+    </ul>
+
+    @return True if the maps are found, otherwise False */
+bool GridGeoConstraint::build_lat_lon_maps()
+{
+    Grid::Map_iter m = d_grid->map_begin();
+    // Assume that a Grid is correct and thus has exactly as many maps as its
+    // array part has dimensions. Thus don't bother to test the Grid's array
+    // dimension iterator for '!= dim_end()'.
+    Array::Dim_iter d = d_grid->get_array()->dim_begin();
+    // The fields d_latitude and d_longitude may be initialized to null or they
+    // may already contain pointers to the maps to use. In the latter case,
+    // skip the heuristics used in this code. However, given that all this
+    // method does is find the lat/lon maps, if they are given in the ctor,
+    // This method will likely not be called at all.
+    while (m != d_grid->map_end() && (!d_latitude || !d_longitude)) {
+        string units_value = (*m)->get_attr_table().get_attr("units");
+        units_value = remove_quotes(units_value);
+        string map_name = (*m)->name();
+
+        // The 'units' attribute must match exactly; the name only needs to
+        // match a prefix.
+        if (!d_latitude
+            && unit_or_name_match(get_coards_lat_units(), get_lat_names(),
+                                  units_value, map_name)) {
+
+            // Set both d_latitude (a pointer to the real map vector) and
+            // d_lat, a vector of the values represented as doubles. It's easier
+            // to work with d_lat, but it's d_latitude that needs to be set
+            // when constraining the grid. Also, record the grid variable's
+            // dimension iterator so that it's easier to set the Grid's Array
+            // (which also has to be constrained).
+            d_latitude = dynamic_cast < Array * >(*m);
+            if (!d_latitude)
+                throw InternalErr(__FILE__, __LINE__, "Expected an array.");
+            if (!d_latitude->read_p())
+                d_latitude->read();
+
+            set_lat(extract_double_array(d_latitude));   // throws Error
+            set_lat_length(d_latitude->length());
+
+            set_lat_dim(d);
+        }
+
+        if (!d_longitude        // && !units_value.empty()
+            && unit_or_name_match(get_coards_lon_units(), get_lon_names(),
+                                  units_value, map_name)) {
+
+            d_longitude = dynamic_cast < Array * >(*m);
+            if (!d_longitude)
+                throw InternalErr(__FILE__, __LINE__, "Expected an array.");
+            if (!d_longitude->read_p())
+                d_longitude->read();
+
+            set_lon(extract_double_array(d_longitude));
+            set_lon_length(d_longitude->length());
+
+            set_lon_dim(d);
+
+            if (m + 1 == d_grid->map_end())
+            	set_longitude_rightmost(true);
+        }
+
+        ++m;
+        ++d;
+    }
+
+    return get_lat() && get_lon();
+}
+
+/** A private method called by the constructor that check to make sure the
+    two arrays passed to the constructor are valid latitude and longitude
+    maps. If so, a they are read in and the values are slurped up by this
+    object. Then the Grid's dimension iterator is used to record a reference
+    the the lat and lon dimension of the Grid itself.
+
+    @return True if the maps are valid, otherwise False */
+bool GridGeoConstraint::build_lat_lon_maps(Array *lat, Array *lon)
+{
+    Grid::Map_iter m = d_grid->map_begin();
+
+    Array::Dim_iter d = d_grid->get_array()->dim_begin();
+
+    while (m != d_grid->map_end() && (!d_latitude || !d_longitude)) {
+	// Look for the Grid map that matches the variable passed as 'lat'
+	if (!d_latitude && *m == lat) {
+
+            d_latitude = lat;
+
+            if (!d_latitude->read_p())
+                d_latitude->read();
+
+            set_lat(extract_double_array(d_latitude));   // throws Error
+            set_lat_length(d_latitude->length());
+
+            set_lat_dim(d);
+        }
+
+        if (!d_longitude && *m == lon) {
+
+            d_longitude = lon;
+
+            if (!d_longitude->read_p())
+                d_longitude->read();
+
+            set_lon(extract_double_array(d_longitude));
+            set_lon_length(d_longitude->length());
+
+            set_lon_dim(d);
+
+            if (m + 1 == d_grid->map_end())
+            	set_longitude_rightmost(true);
+        }
+
+        ++m;
+        ++d;
+    }
+
+    return get_lat() && get_lon();
+}
+
+/** Are the latitude and longitude dimensions ordered so that this class can
+    properly constrain the data? This method throws Error if lat and lon are
+    not to two 'fastest-varying' (or 'rightmost') dimensions. It also sets the
+    internal property \e longitude_rightmost if that's true.
+
+    @note Called by the constructor once build_lat_lon_maps() has returned.
+
+    @return True if the lat/lon maps are the two rightmost maps,
+    false otherwise; modifies the \e longitude_rightmost property as aside
+    effect. */
+bool
+GridGeoConstraint::lat_lon_dimensions_ok()
+{
+    // get the last two map iterators
+    Grid::Map_riter rightmost = d_grid->map_rbegin();
+    Grid::Map_riter next_rightmost = rightmost + 1;
+
+    if (*rightmost == d_longitude && *next_rightmost == d_latitude)
+        set_longitude_rightmost(true);
+    else if (*rightmost == d_latitude && *next_rightmost == d_longitude)
+        set_longitude_rightmost(false);
+    else
+        return false;
+
+    return true;
+}
+
+/** Once the bounding box is set use this method to apply the constraint. This
+    modifies the data values in the Grid so that the software in
+    Vector::serialize() will work correctly. Vector::serialize() assumes that
+    the BaseType::read() method is called \e after the projection is applied to
+    the data. That is, the projection is applied, then data are read. but
+    geogrid() first reads all the data values and then computes the projection.
+    To make Vector::serialize() work, this method uses the projection
+    information recorded in the Grid by set_bounding_box() to arrange data so
+    that the information to be sent is all that is held by the Grid. Call this
+    after applying any 'Grid selection expressions' of the sort that can be
+    passed to the grid() function.
+
+    @note Why do this here? The grid() function uses the standard logic in
+    Vector and elsewhere to read data that's to be sent. The problem is that
+    the data values need to be reordered using information only this object
+    has. If this were implemented as a 'selection function' (i.e., if the code
+    was run by ConstraintExpression::eval() then we might be able to better
+    optimize how data are read, but in this case we have read all the data
+    and may have already reorganized it. Set up the internal buffers so they
+    hold the correct values and mark the Grid's array and lat/lon maps as
+    read. */
+void GridGeoConstraint::apply_constraint_to_data()
+{
+    if (!is_bounding_box_set())
+        throw InternalErr("The Latitude and Longitude constraints must be set before calling apply_constraint_to_data().");
+
+    Array::Dim_iter fd = d_latitude->dim_begin();
+
+    if (get_latitude_sense() == inverted) {
+        int tmp = get_latitude_index_top();
+        set_latitude_index_top(get_latitude_index_bottom());
+        set_latitude_index_bottom(tmp);
+    }
+
+    // It's easy to flip the Latitude values; if the bottom index value
+    // is before/above the top index, return an error explaining that.
+    if (get_latitude_index_top() > get_latitude_index_bottom())
+        throw Error("The upper and lower latitude indices appear to be reversed. Please provide the latitude bounding box numbers giving the northern-most latitude first.");
+
+    // Constrain the lat vector and lat dim of the array
+    d_latitude->add_constraint(fd, get_latitude_index_top(), 1,
+                               get_latitude_index_bottom());
+    d_grid->get_array()->add_constraint(get_lat_dim(),
+                                        get_latitude_index_top(), 1,
+                                        get_latitude_index_bottom());
+
+    // Does the longitude constraint cross the edge of the longitude vector?
+    // If so, reorder the grid's data (array), longitude map vector and the
+    // local vector of longitude data used for computation.
+    if (get_longitude_index_left() > get_longitude_index_right()) {
+        reorder_longitude_map(get_longitude_index_left());
+
+        // If the longitude constraint is 'split', join the two parts, reload
+        // the data into the Grid's Array and make sure the Array is marked as
+        // already read. This should be true for the whole Grid, but if some
+        // future modification changes that, the array will be covered here.
+        // Note that the following method only reads the data out and stores
+        // it in this object after joining the two parts. The method
+        // apply_constraint_to_data() transfers the data back from the this
+        // object to the DAP Grid variable.
+        reorder_data_longitude_axis(*d_grid->get_array(), get_lon_dim());
+
+        // Now that the data are all in local storage alter the indices; the
+        // left index has now been moved to 0, and the right index is now
+        // at lon_vector_length-left+right.
+        set_longitude_index_right(get_lon_length() - get_longitude_index_left()
+                                  + get_longitude_index_right());
+        set_longitude_index_left(0);
+    }
+
+    // If the constraint used the -180/179 (neg_pos) notation, transform
+    // the longitude map so it uses the -180/179 notation. Note that at this
+    // point, d_longitude always uses the pos notation because of the earlier
+    // conditional transformation.
+
+    // Do this _before_ applying the constraint since set_array_using_double()
+    // tests the array length using Vector::length() and that method returns
+    // the length _as constrained_. We want to move all of the longitude
+    // values from d_lon back into the map, not just the number that will be
+    // sent (although an optimization might do this, it's hard to imagine
+    // it would gain much).
+    if (get_longitude_notation() == neg_pos) {
+        transform_longitude_to_neg_pos_notation();
+    }
+
+    // Apply constraint; stride is always one and maps only have one dimension
+    fd = d_longitude->dim_begin();
+    d_longitude->add_constraint(fd, get_longitude_index_left(), 1,
+                                get_longitude_index_right());
+
+    d_grid->get_array()->add_constraint(get_lon_dim(),
+                                        get_longitude_index_left(),
+                                        1, get_longitude_index_right());
+
+    // Transfer values from the local lat vector to the Grid's
+    // Here test the sense of the latitude vector and invert the vector if the
+    // sense is 'inverted' so that the top is always the northern-most value
+    if (get_latitude_sense() == inverted) {
+	DBG(cerr << "Inverted latitude sense" << endl);
+	transpose_vector(get_lat() + get_latitude_index_top(),
+		get_latitude_index_bottom() - get_latitude_index_top() + 1);
+	// Now read the Array data and flip the latitudes.
+	flip_latitude_within_array(*d_grid->get_array(),
+		get_latitude_index_bottom() - get_latitude_index_top() + 1,
+		get_longitude_index_right() - get_longitude_index_left() + 1);
+    }
+
+    set_array_using_double(d_latitude, get_lat() + get_latitude_index_top(),
+                           get_latitude_index_bottom() - get_latitude_index_top() + 1);
+
+    set_array_using_double(d_longitude, get_lon() + get_longitude_index_left(),
+                           get_longitude_index_right() - get_longitude_index_left() + 1);
+
+    // Look for any non-lat/lon maps and make sure they are read correctly
+    Grid::Map_iter i = d_grid->map_begin();
+    Grid::Map_iter end = d_grid->map_end();
+    while (i != end) {
+	if (*i != d_latitude && *i != d_longitude) {
+	    if ((*i)->send_p()) {
+		DBG(cerr << "reading grid map: " << (*i)->name() << endl);
+		//(*i)->set_read_p(false);
+		(*i)->read();
+	    }
+	}
+	++i;
+    }
+
+    // ... and then the Grid's array if it has been read.
+    if (get_array_data()) {
+        int size = d_grid->get_array()->val2buf(get_array_data());
+
+        if (size != get_array_data_size())
+            throw InternalErr(__FILE__, __LINE__, "Expected data size not copied to the Grid's buffer.");
+
+        d_grid->set_read_p(true);
+    }
+    else {
+        d_grid->get_array()->read();
+    }
+}
+
+} // namespace libdap
diff --git a/GridGeoConstraint.h b/GridGeoConstraint.h
new file mode 100644
index 0000000..68a6178
--- /dev/null
+++ b/GridGeoConstraint.h
@@ -0,0 +1,86 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _grid_geo_constraint_h
+#define _grid_geo_constraint_h 1
+
+#include <string>
+#include <sstream>
+#include <set>
+
+#ifndef _geo_constraint_h
+#include "GeoConstraint.h"
+#endif
+
+namespace libdap
+{
+
+// Defined in GeoConstraint; maybe move to util.cc/h?
+extern bool unit_or_name_match(set < string > units, set < string > names,
+			       const string & var_units,
+			       const string & var_name);
+
+/** Geographical constraint applied to a grid.
+    @author James Gallagher */
+
+class GridGeoConstraint : public GeoConstraint
+{
+
+private:
+    // Specific to a Grid
+    Grid *d_grid;               //< Constrain this Grid
+
+    Array *d_latitude;          //< A pointer to the Grid's latitude map
+    Array *d_longitude;         //< A pointer to the Grid's longitude map
+
+    bool build_lat_lon_maps();
+    bool build_lat_lon_maps(Array *lat, Array *lon);
+
+    bool lat_lon_dimensions_ok();
+
+    friend class GridGeoConstraintTest; // Unit tests
+
+public:
+    /** @name Constructors */
+    //@{
+    GridGeoConstraint(Grid *grid);
+    GridGeoConstraint(Grid *grid, Array *lat, Array *lon);
+    //@}
+
+    virtual ~GridGeoConstraint()
+    {}
+
+    virtual void apply_constraint_to_data() ;
+
+    virtual Grid *get_constrained_grid() const
+    {
+        return d_grid;
+    }
+};
+
+} // namespace libdap
+
+#endif // _grid_geo_constraint_h
+
diff --git a/HTTPCache.cc b/HTTPCache.cc
new file mode 100644
index 0000000..500829b
--- /dev/null
+++ b/HTTPCache.cc
@@ -0,0 +1,1622 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+// #define DODS_DEBUG
+// #define DODS_DEBUG2
+#undef USE_GETENV
+
+#include <pthread.h>
+#include <limits.h>
+#include <unistd.h>   // for stat
+#include <sys/types.h>  // for stat and mkdir
+#include <sys/stat.h>
+
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+#include "Error.h"
+#include "InternalErr.h"
+#include "ResponseTooBigErr.h"
+#ifndef WIN32
+#include "SignalHandler.h"
+#endif
+#include "HTTPCacheInterruptHandler.h"
+#include "HTTPCacheTable.h"
+#include "HTTPCache.h"
+
+#include "util_mit.h"
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+HTTPCache *HTTPCache::_instance = 0;
+
+// instance_mutex is used to ensure that only one instance is created.
+// That is, it protects the body of the HTTPCache::instance() method. This
+// mutex is initialized from within the static function once_init_routine()
+// and the call to that takes place using pthread_once_init() where the mutex
+// once_block is used to protect that call. All of this ensures that no matter
+// how many threads call the instance() method, only one instance is ever
+// made.
+static pthread_mutex_t instance_mutex;
+static pthread_once_t once_block = PTHREAD_ONCE_INIT;
+
+#ifdef WIN32
+#include <direct.h>
+#include <time.h>
+#include <fcntl.h>
+#define MKDIR(a,b) _mkdir((a))
+#define UMASK(a) _umask((a))
+#define REMOVE(a) remove((a))
+#define MKSTEMP(a) _open(_mktemp((a)),_O_CREAT,_S_IREAD|_S_IWRITE)
+#define DIR_SEPARATOR_CHAR '\\'
+#define DIR_SEPARATOR_STR "\\"
+#else
+#define MKDIR(a,b) mkdir((a), (b))
+#define UMASK(a) umask((a))
+#define REMOVE(a) remove((a))
+#define MKSTEMP(a) mkstemp((a))
+#define DIR_SEPARATOR_CHAR '/'
+#define DIR_SEPARATOR_STR "/"
+#endif
+
+#ifdef WIN32
+#define CACHE_LOCATION "\\tmp\\"
+#define CACHE_ROOT "dods-cache\\"
+#else
+#define CACHE_LOCATION "/tmp/"
+#define CACHE_ROOT "dods-cache/"
+#endif
+#define CACHE_INDEX ".index"
+#define CACHE_LOCK ".lock"
+#define CACHE_META ".meta"
+//#define CACHE_EMPTY_ETAG "@cache@"
+
+#define NO_LM_EXPIRATION 24*3600 // 24 hours
+
+#define DUMP_FREQUENCY 10 // Dump index every x loads
+
+#define MEGA 0x100000L
+#define CACHE_TOTAL_SIZE 20 // Default cache size is 20M
+#define CACHE_FOLDER_PCT 10 // 10% of cache size for metainfo etc.
+#define CACHE_GC_PCT 10  // 10% of cache size free after GC
+#define MIN_CACHE_TOTAL_SIZE 5 // 5M Min cache size
+#define MAX_CACHE_ENTRY_SIZE 3 // 3M Max size of single cached entry
+
+static void
+once_init_routine()
+{
+    int status;
+    status = INIT(&instance_mutex);
+
+    if (status != 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not initialize the HTTP Cache mutex. Exiting.");
+}
+
+/** Get a pointer to the HTTP 1.1 compliant cache. If not already
+    instantiated, this creates an instance of the HTTP cache object and
+    initializes it to use \c cache_root as the location of the persistent
+    store. If there's an index (\c .index) file in that directory, it is read
+    as part of the initialization. If the cache has already been initialized,
+    this method returns a pointer to that instance. Note HTTPCache uses the
+    singleton pattern; A process may have only one instance of this object.
+    Also note that HTTPCache is MT-safe. However, if the \c force parameter
+    is set to true, it may be possible for two or more processes to access
+    the persistent store at the same time resulting in undefined behavior.
+
+    Default values: is_cache_enabled(): true, is_cache_protected(): false,
+    is_expire_ignored(): false, the total size of the cache is 20M, 2M of that
+    is reserved for response headers, during GC the cache is reduced to at
+    least 18M (total size - 10% of the total size), and the max size for an
+    individual entry is 3M. It is possible to change the size of the cache,
+    but not to make it smaller than 5M. If expiration information is not sent
+    with a response, it is assumed to expire in 24 hours.
+
+    @param cache_root The fully qualified pathname of the directory which
+    will hold the cache data (i.e., the persistent store).
+    @param force Force access to the persistent store if true. By default
+    false. Use this only if you're sure no one else is using the same cache
+    root! This is included so that programs may use a cache that was
+    left in an inconsistent state.
+    @return A pointer to the HTTPCache object.
+    @exception Error thrown if the cache root cannot set. */
+
+HTTPCache *
+HTTPCache::instance(const string &cache_root, bool force)
+{
+    int status = pthread_once(&once_block, once_init_routine);
+    if (status != 0)
+	throw InternalErr(__FILE__, __LINE__, "Could not initialize the HTTP Cache mutex. Exiting.");
+
+    LOCK(&instance_mutex);
+
+    DBG(cerr << "Entering instance(); (" << hex << _instance << dec << ")"
+	    << "... ");
+
+    try {
+        if (!_instance) {
+            _instance = new HTTPCache(cache_root, force);
+
+            DBG(cerr << "New instance: " << _instance << ", cache root: "
+                << _instance->d_cache_root << endl);
+
+            atexit(delete_instance);
+
+#ifndef WIN32
+            // Register the interrupt handler. If we've already registered
+            // one, barf. If this becomes a problem, hack SignalHandler so
+            // that we can chain these handlers... 02/10/04 jhrg
+            //
+            // Technically we're leaking memory here. However, since this
+            // class is a singleton, we know that only three objects will
+            // ever be created and they will all exist until the process
+            // exits. We can let this slide... 02/12/04 jhrg
+            EventHandler *old_eh = SignalHandler::instance()->register_handler
+                                   (SIGINT, new HTTPCacheInterruptHandler);
+            if (old_eh) {
+                SignalHandler::instance()->register_handler(SIGINT, old_eh);
+                throw SignalHandlerRegisteredErr(
+                    "Could not register event handler for SIGINT without superseding an existing one.");
+            }
+
+            old_eh = SignalHandler::instance()->register_handler
+                     (SIGPIPE, new HTTPCacheInterruptHandler);
+            if (old_eh) {
+                SignalHandler::instance()->register_handler(SIGPIPE, old_eh);
+                throw SignalHandlerRegisteredErr(
+                    "Could not register event handler for SIGPIPE without superseding an existing one.");
+            }
+
+            old_eh = SignalHandler::instance()->register_handler
+                     (SIGTERM, new HTTPCacheInterruptHandler);
+            if (old_eh) {
+                SignalHandler::instance()->register_handler(SIGTERM, old_eh);
+                throw SignalHandlerRegisteredErr(
+                    "Could not register event handler for SIGTERM without superseding an existing one.");
+            }
+#endif
+        }
+    }
+    catch (...) {
+        DBG2(cerr << "The constructor threw an Error!" << endl);
+        UNLOCK(&instance_mutex);
+        throw;
+    }
+
+    UNLOCK(&instance_mutex);
+    DBGN(cerr << "returning " << hex << _instance << dec << endl);
+
+    return _instance;
+}
+
+/** This static method is called using atexit(). It deletes the singleton;
+    see ~HTTPCache for all that implies. */
+
+void
+HTTPCache::delete_instance()
+{
+    DBG(cerr << "Entering delete_instance()..." << endl);
+    if (HTTPCache::_instance) {
+        DBG(cerr << "Deleting the cache: " << HTTPCache::_instance << endl);
+        delete HTTPCache::_instance;
+        HTTPCache::_instance = 0;
+    }
+
+    DBG(cerr << "Exiting delete_instance()" << endl);
+}
+
+/** Create an instance of the HTTP 1.1 compliant cache. This initializes the
+    both the cache root and the path to the index file. It then reads the
+    cache index file if one is present.
+
+    A private method.
+
+    @note This assumes that the cache directory structure should be created!
+    @param cache_root The fully qualified pathname of the directory which
+    will hold the cache data.
+    @param force Force access to the persistent store!
+    @exception Error Thrown if the single user/process lock for the
+    persistent store cannot be obtained.
+    @see cache_index_read */
+
+HTTPCache::HTTPCache(string cache_root, bool force) :
+        d_locked_open_file(0),
+        d_cache_enabled(false),
+        d_cache_protected(false),
+        d_expire_ignored(false),
+        d_always_validate(false),
+        d_total_size(CACHE_TOTAL_SIZE * MEGA),
+        d_folder_size(CACHE_TOTAL_SIZE / CACHE_FOLDER_PCT),
+        d_gc_buffer(CACHE_TOTAL_SIZE / CACHE_GC_PCT),
+        d_max_entry_size(MAX_CACHE_ENTRY_SIZE * MEGA),
+        d_default_expiration(NO_LM_EXPIRATION),
+        d_max_age(-1),
+        d_max_stale(-1),
+        d_min_fresh(-1),
+        d_http_cache_table(0)
+{
+    DBG(cerr << "Entering the constructor for " << this << "... ");
+#if 0
+	int status = pthread_once(&once_block, once_init_routine);
+	if (status != 0)
+		throw InternalErr(__FILE__, __LINE__, "Could not initialize the HTTP Cache mutex. Exiting.");
+#endif
+	INIT(&d_cache_mutex);
+
+	// This used to throw an Error object if we could not get the
+	// single user lock. However, that results in an invalid object. It's
+	// better to have an instance that has default values. If we cannot get
+	// the lock, make sure to set the cache as *disabled*. 03/12/03 jhrg
+	//
+	// I fixed this block so that the cache root is set before we try to get
+	// the single user lock. That was the fix for bug #661. To make that
+	// work, I had to move the call to create_cache_root out of
+	// set_cache_root(). 09/08/03 jhrg
+
+	set_cache_root(cache_root);
+	int block_size;
+
+	if (!get_single_user_lock(force))
+	    throw Error("Could not get single user lock for the cache");
+
+#ifdef WIN32
+	//  Windows is unable to provide us this information.  4096 appears
+	//  a best guess.  It is likely to be in the range [2048, 8192] on
+	//  windows, but will the level of truth of that statement vary over
+	//  time ?
+	block_size = 4096;
+#else
+	struct stat s;
+	if (stat(cache_root.c_str(), &s) == 0)
+		block_size = s.st_blksize;
+	else
+		throw Error("Could not set file system block size.");
+#endif
+	d_http_cache_table = new HTTPCacheTable(d_cache_root, block_size);
+	d_cache_enabled = true;
+
+	DBGN(cerr << "exiting" << endl);
+}
+
+/** Destroy an instance of HTTPCache. This writes the cache index and frees
+    the in-memory cache table structure. The persistent cache (the response
+    headers and bodies and the index file) are not removed. To remove those,
+    either erase the directory that contains the cache using a file system
+    command or use the purge_cache() method (which leaves the cache directory
+    structure in place but removes all the cached information).
+
+    This class uses the singleton pattern. Clients should \e never call this
+    method. The HTTPCache::instance() method arranges to call the
+    HTTPCache::delete_instance() using \c atexit(). If delete is called more
+    than once, the result will likely be an index file that is corrupt. */
+
+HTTPCache::~HTTPCache()
+{
+    DBG(cerr << "Entering the destructor for " << this << "... ");
+
+    try {
+        if (startGC())
+            perform_garbage_collection();
+
+        d_http_cache_table->cache_index_write();
+    }
+    catch (Error &e) {
+        // If the cache index cannot be written, we've got problems. However,
+        // unless we're debugging, still free up the cache table in memory.
+        // How should we let users know they cache index is not being
+        // written?? 10/03/02 jhrg
+        DBG(cerr << e.get_error_message() << endl);
+    }
+
+    delete d_http_cache_table;
+
+    release_single_user_lock();
+
+    DBGN(cerr << "exiting destructor." << endl);
+    DESTROY(&d_cache_mutex);
+}
+
+
+/** @name Garbage collection
+    These private methods manage the garbage collection tasks for the cache. */
+//@{
+
+/** Enough removed from cache? A private method.
+    @return True if enough has been removed from the cache. */
+
+bool
+HTTPCache::stopGC() const
+{
+    return (d_http_cache_table->get_current_size() + d_folder_size < d_total_size - d_gc_buffer);
+}
+
+/** Is there too much in the cache. A private method.
+
+    @todo Modify this method so that it does not count locked entries. See
+    the note for hits_gc().
+    @return True if garbage collection should be performed. */
+
+bool
+HTTPCache::startGC() const
+{
+    DBG(cerr << "startGC, current_size: " << d_http_cache_table->get_current_size() << endl);
+    return (d_http_cache_table->get_current_size() + d_folder_size > d_total_size);
+}
+
+/** Perform garbage collection on the cache. First, all expired responses are
+    removed. Then, if the size of the cache is still too large, the cache is
+    scanned for responses larger than the max_entry_size property. At the
+    same time, responses are removed based on the number of cache hits. This
+    process continues until the size of the cache has been reduced to 90% of
+    the max_size property value. Once the garbage collection is complete,
+    update the index file. Note that locked entries are not removed!
+
+    A private method.
+
+    @see stopGC
+    @see expired_gc
+    @see hits_gc */
+
+void
+HTTPCache::perform_garbage_collection()
+{
+    DBG(cerr << "Performing garbage collection" << endl);
+
+    // Remove all the expired responses.
+    expired_gc();
+
+    // Remove entries larger than max_entry_size.
+    too_big_gc();
+
+    // Remove entries starting with zero hits, 1, ..., until stopGC()
+    // returns true.
+    hits_gc();
+}
+
+/** Scan the current cache table and remove anything that has expired. Don't
+    remove locked entries.
+
+    A private method. */
+
+void
+HTTPCache::expired_gc()
+{
+    if (!d_expire_ignored) {
+        d_http_cache_table->delete_expired_entries();
+    }
+}
+
+/** Scan the cache for entires that are larger than max_entry_size. Also
+    start removing entires with low hit counts. Start looking for entries
+    with zero hits, then one, and so on. Stop when the method stopGC returns
+    true. Locked entries are never removed.
+
+    @note Potential infinite loop. What if more than 80% of the cache holds
+    entries that are locked? One solution is to modify startGC() so that it
+    does not count locked entries.
+
+    @todo Change this method to that it looks at the oldest entries first,
+    using the CacheEntry::date to determine entry age. Using the current
+    algorithm it's possible to remove the latest entry which is probably not
+    what we want.
+
+    A private method. */
+
+void
+HTTPCache::hits_gc()
+{
+    int hits = 0;
+
+    if (startGC()) {
+		while (!stopGC()) {
+			d_http_cache_table->delete_by_hits(hits);
+			hits++;
+		}
+	}
+}
+
+/** Scan the current cache table and remove anything that has is too big.
+ 	Don't remove locked entries.
+
+    A private method. */
+void HTTPCache::too_big_gc() {
+	if (startGC())
+		d_http_cache_table->delete_by_size(d_max_entry_size);
+}
+
+//@} End of the garbage collection methods.
+
+/** Lock the persistent store part of the cache. Return true if the cache lock
+    was acquired, false otherwise. This is a single user cache, so it
+    requires locking at the process level.
+
+    A private method.
+
+    @param force If True force access to the persistent store. False by
+    default.
+    @return True if the cache was locked for our use, False otherwise. */
+
+bool HTTPCache::get_single_user_lock(bool force) 
+{
+    if (!d_locked_open_file) {
+	FILE * fp = NULL;
+
+	try {
+	    // It's OK to call create_cache_root if the directory already
+	    // exists.
+	    create_cache_root(d_cache_root);
+	}
+	catch (Error &e) {
+	    // We need to catch and return false because this method is
+	    // called from a ctor and throwing at this point will result in a
+	    // partially constructed object. 01/22/04 jhrg
+	    DBG(cerr << "Failure to create the cache root" << endl);
+	    return false;
+	}
+
+	// Try to read the lock file. If we can open for reading, it exists.
+	string lock = d_cache_root + CACHE_LOCK;
+	if ((fp = fopen(lock.c_str(), "r")) != NULL) {
+	    int res = fclose(fp);
+	    if (res) {
+		DBG(cerr << "Failed to close " << (void *)fp << endl);
+	    }
+	    if (force)
+		REMOVE(lock.c_str());
+	    else
+		return false;
+	}
+
+	if ((fp = fopen(lock.c_str(), "w")) == NULL) {
+	    DBG(cerr << "Could not open for write access" << endl);
+	    return false;
+	}
+
+	d_locked_open_file = fp;
+	return true;
+    }
+
+    cerr << "locked_open_file is true" << endl;
+    return false;
+}
+
+/** Release the single user (process) lock. A private method. */
+
+void
+HTTPCache::release_single_user_lock()
+{
+    if (d_locked_open_file) {
+        int res = fclose(d_locked_open_file);
+        if (res) {
+            DBG(cerr << "Failed to close " << (void *)d_locked_open_file << endl) ;
+        }
+        d_locked_open_file = 0;
+    }
+
+    string lock = d_cache_root + CACHE_LOCK;
+    REMOVE(lock.c_str());
+}
+
+/** @name Accessors and Mutators for various properties. */
+//@{
+
+/** Get the current cache root directory.
+    @return A string that contains the cache root directory. */
+
+string
+HTTPCache::get_cache_root() const
+{
+    return d_cache_root;
+}
+
+
+/** Create the cache's root directory. This is the persistent store used by
+    the cache. Paths must always end in DIR_SEPARATOR_CHAR.
+
+    A private method.
+
+    @param cache_root The pathname to the desired cache root directory.
+    @exception Error Thrown if the given pathname cannot be created. */
+
+void
+HTTPCache::create_cache_root(const string &cache_root)
+{
+    struct stat stat_info;
+    string::size_type cur = 0;
+
+#ifdef WIN32
+    cur = cache_root[1] == ':' ? 3 : 1;
+    typedef int mode_t;
+#else
+    cur = 1;
+#endif
+    while ((cur = cache_root.find(DIR_SEPARATOR_CHAR, cur)) != string::npos) {
+        string dir = cache_root.substr(0, cur);
+        if (stat(dir.c_str(), &stat_info) == -1) {
+            DBG2(cerr << "Cache....... Creating " << dir << endl);
+            mode_t mask = UMASK(0);
+            if (MKDIR(dir.c_str(), 0777) < 0) {
+                DBG2(cerr << "Error: can't create." << endl);
+                UMASK(mask);
+                throw Error(string("Could not create the directory for the cache. Failed when building path at ") + dir + string("."));
+            }
+            UMASK(mask);
+        }
+        else {
+            DBG2(cerr << "Cache....... Found " << dir << endl);
+        }
+        cur++;
+    }
+}
+
+/** Set the cache's root directory to the given path. If no path is given,
+    look at the DODS_CACHE, TMP and TEMP environment variables (in that
+    order) to guess at a good location. If those are all NULL, use \c /tmp.
+    If the cache root directory cannot be created, throw an exception.
+
+    Note that in most cases callers should look for this path in the user's
+    .dodsrc file.
+
+    A private method.
+
+    @see RCReader
+    @param root Set the cache root to this pathname. Defaults to "".
+    @exception Error Thrown if the path can neither be deduced nor created. */
+
+void
+HTTPCache::set_cache_root(const string &root)
+{
+    if (root != "") {
+        d_cache_root = root;
+        // cache root should end in /.
+        if (d_cache_root[d_cache_root.size()-1] != DIR_SEPARATOR_CHAR)
+            d_cache_root += DIR_SEPARATOR_CHAR;
+    }
+    else {
+        // If no cache root has been indicated then look for a suitable
+        // location.
+#ifdef USE_GETENV
+        char * cr = (char *) getenv("DODS_CACHE");
+        if (!cr) cr = (char *) getenv("TMP");
+        if (!cr) cr = (char *) getenv("TEMP");
+        if (!cr) cr = (char*)CACHE_LOCATION;
+        d_cache_root = cr;
+#else
+        d_cache_root = CACHE_LOCATION;
+#endif
+
+        if (d_cache_root[d_cache_root.size()-1] != DIR_SEPARATOR_CHAR)
+            d_cache_root += DIR_SEPARATOR_CHAR;
+
+        d_cache_root += CACHE_ROOT;
+    }
+
+    // Test d_hhtp_cache_table because this method can be called before that
+    // instance is created and also can be called later to cahnge the cache
+    // root. jhrg 05.14.08
+    if (d_http_cache_table)
+    	d_http_cache_table->set_cache_root(d_cache_root);
+}
+
+/** Enable or disable the cache. The cache can be temporarily suspended using
+    the enable/disable property. This does not prevent the cache from being
+    enabled/disable at a later point in time.
+
+    Default: yes
+
+    This method locks the class' interface.
+
+    @param mode True if the cache should be enabled, False if it should be
+    disabled. */
+
+void
+HTTPCache::set_cache_enabled(bool mode)
+{
+    lock_cache_interface();
+
+    d_cache_enabled = mode;
+
+    unlock_cache_interface();
+}
+
+/** Is the cache currently enabled? */
+
+bool
+HTTPCache::is_cache_enabled() const
+{
+    DBG2(cerr << "In HTTPCache::is_cache_enabled: (" << d_cache_enabled << ")"
+         << endl);
+    return d_cache_enabled;
+}
+
+/** Set the cache's disconnected property. The cache can operate either
+    disconnected from the network or using a proxy cache (but tell that proxy
+    not to use the network).
+
+    This method locks the class' interface.
+
+    @param mode One of DISCONNECT_NONE, DISCONNECT_NORMAL or
+    DISCONNECT_EXTERNAL.
+    @see CacheDIsconnectedMode */
+
+void
+HTTPCache::set_cache_disconnected(CacheDisconnectedMode mode)
+{
+    lock_cache_interface();
+
+    d_cache_disconnected = mode;
+
+    unlock_cache_interface();
+}
+
+/** Get the cache's disconnected mode property. */
+
+CacheDisconnectedMode
+HTTPCache::get_cache_disconnected() const
+{
+    return d_cache_disconnected;
+}
+
+/** How should the cache handle the Expires header?
+    Default: no
+
+    This method locks the class' interface.
+
+    @param mode True if a responses Expires header should be ignored, False
+    otherwise. */
+
+void
+HTTPCache::set_expire_ignored(bool mode)
+{
+    lock_cache_interface();
+
+    d_expire_ignored = mode;
+
+    unlock_cache_interface();
+}
+
+/* Is the cache ignoring Expires headers returned with responses that have
+   been cached? */
+
+bool
+HTTPCache::is_expire_ignored() const
+{
+    return d_expire_ignored;
+}
+
+/** Cache size management. The default cache size is 20M. The minimum size is
+    5M in order not to get into weird problems while writing the cache. The
+    size is indicated in Mega bytes. Note that reducing the size of the cache
+    may trigger a garbage collection operation.
+
+    @note The maximum cache size is UINT_MAX bytes (usually 4294967295 for
+    32-bit computers). If \e size is larger the value will be truncated to
+    the value of that constant. It seems pretty unlikely that will happen
+    given that the parameter is an unsigned long. This is a fix for bug 689
+    which was reported when the parameter type was signed.
+
+    This method locks the class' interface.
+
+    @param size The maximum size of the cache in megabytes. */
+
+void
+HTTPCache::set_max_size(unsigned long size)
+{
+    lock_cache_interface();
+
+    try {
+        unsigned long new_size = size < MIN_CACHE_TOTAL_SIZE ?
+                                 MIN_CACHE_TOTAL_SIZE * MEGA :
+                                 (size > ULONG_MAX ? ULONG_MAX : size * MEGA);
+        unsigned long old_size = d_total_size;
+        d_total_size = new_size;
+        d_folder_size = d_total_size / CACHE_FOLDER_PCT;
+        d_gc_buffer = d_total_size / CACHE_GC_PCT;
+
+        if (new_size < old_size && startGC()) {
+            perform_garbage_collection();
+            d_http_cache_table->cache_index_write();
+        }
+    }
+    catch (...) {
+        unlock_cache_interface();
+        DBGN(cerr << "Unlocking interface." << endl);
+        throw;
+    }
+
+    DBG2(cerr << "Cache....... Total cache size: " << d_total_size
+         << " with " << d_folder_size
+         << " bytes for meta information and folders and at least "
+         << d_gc_buffer << " bytes free after every gc" << endl);
+
+    unlock_cache_interface();
+}
+
+/** How big is the cache? The value returned is the size in megabytes. */
+
+unsigned long
+HTTPCache::get_max_size() const
+{
+    return d_total_size / MEGA;
+}
+
+/** Set the maximum size for a single entry in the cache.
+
+    Default: 3M
+
+    This method locks the class' interface.
+
+    @param size The size in megabytes. */
+
+void
+HTTPCache::set_max_entry_size(unsigned long size)
+{
+    lock_cache_interface();
+
+    try {
+        unsigned long new_size = size * MEGA;
+        if (new_size > 0 && new_size < d_total_size - d_folder_size) {
+            unsigned long old_size = d_max_entry_size;
+            d_max_entry_size = new_size;
+            if (new_size < old_size && startGC()) {
+                perform_garbage_collection();
+                d_http_cache_table->cache_index_write();
+            }
+        }
+    }
+    catch (...) {
+        unlock_cache_interface();
+        throw;
+    }
+
+    DBG2(cerr << "Cache...... Max entry cache size is "
+         << d_max_entry_size << endl);
+
+    unlock_cache_interface();
+}
+
+/** Get the maximum size of an individual entry in the cache.
+
+    @return The maximum size in megabytes. */
+
+unsigned long
+HTTPCache::get_max_entry_size() const
+{
+    return d_max_entry_size / MEGA;
+}
+
+/** Set the default expiration time. Use the <i>default expiration</i>
+    property to determine when a cached response becomes stale if the
+    response lacks the information necessary to compute a specific value.
+
+    Default: 24 hours (86,400 seconds)
+
+    This method locks the class' interface.
+
+    @param exp_time The time in seconds. */
+
+void
+HTTPCache::set_default_expiration(const int exp_time)
+{
+    lock_cache_interface();
+
+    d_default_expiration = exp_time;
+
+    unlock_cache_interface();
+}
+
+/** Get the default expiration time used by the cache. */
+
+int
+HTTPCache::get_default_expiration() const
+{
+    return d_default_expiration;
+}
+
+/** Should every cache entry be validated?
+    @param validate True if every cache entry should be validated before
+    being used. */
+
+void
+HTTPCache::set_always_validate(bool validate)
+{
+    d_always_validate = validate;
+}
+
+/** Should every cache entry be validated before each use?
+    @return True if all cache entries require validation. */
+
+bool
+HTTPCache::get_always_validate() const
+{
+    return d_always_validate;
+}
+
+/** Set the request Cache-Control headers. If a request must be satisfied
+    using HTTP, these headers should be included in request since they might
+    be pertinent to a proxy cache.
+
+    Ignored headers: no-transform, only-if-cached. These headers are not used
+    by HTTPCache and are not recorded. However, if present in the vector
+    passed to this method, they will be present in the vector returned by
+    get_cache_control.
+
+    This method locks the class' interface.
+
+    @param cc A vector of strings, each string holds one Cache-Control
+    header.
+    @exception InternalErr Thrown if one of the strings in \c cc does not
+    start with 'Cache-Control: '. */
+
+void
+HTTPCache::set_cache_control(const vector<string> &cc)
+{
+    lock_cache_interface();
+
+    try {
+        d_cache_control = cc;
+
+        vector<string>::const_iterator i;
+        for (i = cc.begin(); i != cc.end(); ++i) {
+            string header = (*i).substr(0, (*i).find(':'));
+            string value = (*i).substr((*i).find(": ") + 2);
+            if (header != "Cache-Control") {
+                throw InternalErr(__FILE__, __LINE__, "Expected cache control header not found.");
+            }
+            else {
+                if (value == "no-cache" || value == "no-store")
+                    d_cache_enabled = false;
+                else if (value.find("max-age") != string::npos) {
+                    string max_age = value.substr(value.find("=" + 1));
+                    d_max_age = parse_time(max_age.c_str());
+                }
+                else if (value == "max-stale")
+                    d_max_stale = 0; // indicates will take anything;
+                else if (value.find("max-stale") != string::npos) {
+                    string max_stale = value.substr(value.find("=" + 1));
+                    d_max_stale = parse_time(max_stale.c_str());
+                }
+                else if (value.find("min-fresh") != string::npos) {
+                    string min_fresh = value.substr(value.find("=" + 1));
+                    d_min_fresh = parse_time(min_fresh.c_str());
+                }
+            }
+        }
+    }
+    catch (...) {
+        unlock_cache_interface();
+        throw;
+    }
+
+    unlock_cache_interface();
+}
+
+
+/** Get the Cache-Control headers.
+
+    @return A vector of strings, one string for each header. */
+
+vector<string>
+HTTPCache::get_cache_control()
+{
+    return d_cache_control;
+}
+
+//@}
+
+/** Look in the cache for the given \c url. Is it in the cache table?
+
+    This method locks the class' interface.
+
+	@todo Remove this is broken.
+    @param url The url to look for.
+    @return True if \c url is found, otherwise False. */
+
+bool
+HTTPCache::is_url_in_cache(const string &url)
+{
+    DBG(cerr << "Is this url in the cache? (" << url << ")" << endl);
+
+    HTTPCacheTable::CacheEntry *entry = d_http_cache_table->get_locked_entry_from_cache_table(url);
+    bool status = entry != 0;
+    if (entry) {
+        entry->unlock_read_response();
+    }
+    return  status;
+}
+
+/** Is the header a hop by hop header? If so, we're not supposed to store it
+    in the cache. See RFC 2616, Section 13.5.1.
+
+    @return True if the header is, otherwise False. */
+
+bool
+is_hop_by_hop_header(const string &header)
+{
+    return header.find("Connection") != string::npos
+           || header.find("Keep-Alive") != string::npos
+           || header.find("Proxy-Authenticate") != string::npos
+           || header.find("Proxy-Authorization") != string::npos
+           || header.find("Transfer-Encoding") != string::npos
+           || header.find("Upgrade") != string::npos;
+}
+
+/** Dump the headers out to the meta data file. The file is truncated if it
+    already exists.
+
+    @todo This code could be replaced with STL/iostream stuff.
+
+    A private method.
+
+    @param cachename Base name of file for meta data.
+    @param headers A vector of strings, one header per string.
+    @exception InternalErr Thrown if the file cannot be opened. */
+
+void
+HTTPCache::write_metadata(const string &cachename, const vector<string> &headers)
+{
+    string fname = cachename + CACHE_META;
+    d_open_files.push_back(fname);
+
+    FILE *dest = fopen(fname.c_str(), "w");
+    if (!dest) {
+        throw InternalErr(__FILE__, __LINE__,
+                          "Could not open named cache entry file.");
+    }
+
+    vector<string>::const_iterator i;
+    for (i = headers.begin(); i != headers.end(); ++i) {
+        if (!is_hop_by_hop_header(*i)) {
+            int s = fwrite((*i).c_str(), (*i).size(), 1, dest);
+            if (s != 1)
+            	throw InternalErr(__FILE__, __LINE__, "could not write header: '" + (*i) + "' " + long_to_string(s));
+            s = fwrite("\n", 1, 1, dest);
+            if (s != 1)
+            	throw InternalErr(__FILE__, __LINE__, "could not write header: " + long_to_string(s));
+        }
+    }
+
+    int res = fclose(dest);
+    if (res) {
+        DBG(cerr << "HTTPCache::write_metadata - Failed to close "
+            << dest << endl);
+    }
+
+    d_open_files.pop_back();
+}
+
+/** Read headers from a .meta.
+
+    @todo This code could be replaced with STL/iostream code.
+
+    A private method.
+
+    @param cachename The name of the file in the persistent store.
+    @param headers The headers are returned using this parameter.
+    @exception InternalErr Thrown if the file cannot be opened. */
+
+void
+HTTPCache::read_metadata(const string &cachename, vector<string> &headers)
+{
+    FILE *md = fopen(string(cachename + CACHE_META).c_str(), "r");
+    if (!md) {
+        throw InternalErr(__FILE__, __LINE__,
+                          "Could not open named cache entry meta data file.");
+    }
+
+    char line[1024];
+    while (!feof(md) && fgets(line, 1024, md)) {
+        line[min(1024, static_cast<int>(strlen(line)))-1] = '\0'; // erase newline
+        headers.push_back(string(line));
+    }
+
+    int res = fclose(md);
+    if (res) {
+        DBG(cerr << "HTTPCache::read_metadata - Failed to close "
+            << md << endl);
+    }
+}
+
+/** Write the body of the HTTP response to the cache.
+
+    This method used to throw ResponseTooBig if any response was larger than
+    max_entry_size. I've disabled that since perform_garbage_collection will
+    remove any such entry if it's causing problems. Note that if
+    parse_headers finds a Content-Length header that indicates a response is
+    too big, the response won't be cached. The idea here is that once we've
+    already written a bunch of bytes to the cache, we might as well continue.
+    If it overflows the cache, perform_garbage_collection() will remove it.
+
+    A private method.
+
+    @param cachename Write data to this file.
+    @param src Read data from this stream.
+    @return The total number of bytes written.
+    @exception InternalErr Thrown if the file cannot be opened or if an I/O
+    error was detected.
+    @exception ResponseTooBig Thrown if the response was found to be bigger
+    than the max_entry_size property. This is not longer thrown. 10/11/02
+    jhrg */
+
+int
+HTTPCache::write_body(const string &cachename, const FILE *src)
+{
+    d_open_files.push_back(cachename);
+
+    FILE *dest = fopen(cachename.c_str(), "wb");
+    if (!dest) {
+        throw InternalErr(__FILE__, __LINE__,
+                          "Could not open named cache entry file.");
+    }
+
+    // Read and write in 1k blocks; an attempt at doing this efficiently.
+    // 09/30/02 jhrg
+    char line[1024];
+    size_t n;
+    int total = 0;
+    while ((n = fread(line, 1, 1024, const_cast<FILE *>(src))) > 0) {
+        total += fwrite(line, 1, n, dest);
+        DBG2(sleep(3));
+    }
+
+    if (ferror(const_cast<FILE *>(src)) || ferror(dest)) {
+        int res = fclose(dest);
+        res = res & unlink(cachename.c_str());
+        if (res) {
+            DBG(cerr << "HTTPCache::write_body - Failed to close/unlink "
+                << dest << endl);
+        }
+        throw InternalErr(__FILE__, __LINE__,
+                          "I/O error transferring data to the cache.");
+    }
+
+    rewind(const_cast<FILE *>(src));
+
+    int res = fclose(dest);
+    if (res) {
+        DBG(cerr << "HTTPCache::write_body - Failed to close "
+            << dest << endl);
+    }
+
+    d_open_files.pop_back();
+
+    return total;
+}
+
+/** Get a pointer to file that contains the body of a cached response. The
+    returned FILE* can be used both for reading and for writing.
+
+    A private method.
+
+    @param cachename The name of the file that holds the response body.
+    @exception InternalErr Thrown if the file cannot be opened. */
+
+FILE *
+HTTPCache::open_body(const string &cachename)
+{
+    DBG(cerr << "cachename: " << cachename << endl);
+
+    FILE *src = fopen(cachename.c_str(), "rb"); // Read only
+    if (!src)
+	throw InternalErr(__FILE__, __LINE__, "Could not open cache file.");
+
+    return src;
+}
+
+/** Add a new response to the cache, or replace an existing cached response
+    with new data. This method returns True if the information for \c url was
+    added to the cache. A response might not be cache-able; in that case this
+    method returns false. (For example, the response might contain the
+    'Cache-Control: no-cache' header.)
+
+    Note that the FILE *body is rewound so that the caller can re-read it
+    without using fseek or rewind.
+
+    If a response for \c url is already present in the cache, it will be
+    replaced by the new headers and body. To update a response in the cache
+    with new meta data, use update_response().
+
+    This method locks the class' interface.
+
+    @param url A string which holds the request URL.
+    @param request_time The time when the request was made, in seconds since
+    1 Jan 1970.
+    @param headers A vector of strings which hold the response headers.
+    @param body A FILE * to a file which holds the response body.
+    @return True if the response was cached, False if the response could not
+    be cached.
+    @exception InternalErr Thrown if there was a I/O error while writing to
+    the persistent store. */
+
+bool
+HTTPCache::cache_response(const string &url, time_t request_time,
+                          const vector<string> &headers, const FILE *body)
+{
+    lock_cache_interface();
+
+    DBG(cerr << "Caching url: " << url << "." << endl);
+
+    try {
+        // If this is not an http or https URL, don't cache.
+        if (url.find("http:") == string::npos &&
+            url.find("https:") == string::npos) {
+            unlock_cache_interface();
+            return false;
+        }
+
+        // This does nothing if url is not already in the cache. It's
+        // more efficient to do this than to first check and see if the entry
+        // exists. 10/10/02 jhrg
+        d_http_cache_table->remove_entry_from_cache_table(url);
+
+        HTTPCacheTable::CacheEntry *entry = new HTTPCacheTable::CacheEntry(url);
+        entry->lock_write_response();
+
+        try {
+            d_http_cache_table->parse_headers(entry, d_max_entry_size, headers); // etag, lm, date, age, expires, max_age.
+            if (entry->is_no_cache()) {
+                DBG(cerr << "Not cache-able; deleting HTTPCacheTable::CacheEntry: " << entry
+                    << "(" << url << ")" << endl);
+                entry->unlock_write_response();
+                delete entry; entry = 0;
+                unlock_cache_interface();
+                return false;
+            }
+
+            // corrected_initial_age, freshness_lifetime, response_time.
+            d_http_cache_table->calculate_time(entry, d_default_expiration, request_time);
+
+            d_http_cache_table->create_location(entry); // cachename, cache_body_fd
+            // move these write function to cache table
+            entry->set_size(write_body(entry->get_cachename(), body));
+            write_metadata(entry->get_cachename(), headers);
+            d_http_cache_table->add_entry_to_cache_table(entry);
+            entry->unlock_write_response();
+        }
+        catch (ResponseTooBigErr &e) {
+            // Oops. Bummer. Clean up and exit.
+            DBG(cerr << e.get_error_message() << endl);
+            REMOVE(entry->get_cachename().c_str());
+            REMOVE(string(entry->get_cachename() + CACHE_META).c_str());
+            DBG(cerr << "Too big; deleting HTTPCacheTable::CacheEntry: " << entry << "(" << url
+                << ")" << endl);
+            entry->unlock_write_response();
+            delete entry; entry = 0;
+            unlock_cache_interface();
+            return false;
+        }
+
+        if (d_http_cache_table->get_new_entries() > DUMP_FREQUENCY) {
+            if (startGC())
+                perform_garbage_collection();
+
+            d_http_cache_table->cache_index_write(); // resets new_entries
+        }
+    }
+    catch (...) {
+        unlock_cache_interface();
+        throw;
+    }
+
+    unlock_cache_interface();
+
+    return true;
+}
+
+/** Build the headers to send along with a GET request to make that request
+    conditional. This method examines the headers for a given response in the
+    cache and formulates the correct headers for a valid HTTP 1.1 conditional
+    GET request. See RFC 2616, Section 13.3.4.
+
+    Rules: If an ETag is present, it must be used. Use If-None-Match. If a
+    Last-Modified header is present, use it. Use If-Modified-Since. If both
+    are present, use both (this means that HTTP 1.0 daemons are more likely
+    to work). If a Last-Modified header is not present, use the value of the
+    Cache-Control max-age or Expires header(s). Note that a 'Cache-Control:
+    max-age' header overrides an Expires header (Sec 14.9.3).
+
+    This method locks the cache interface and the cache entry.
+
+    @param url Get the HTTPCacheTable::CacheEntry for this URL.
+    @return A vector of strings, one request header per string.
+    @exception Error Thrown if the \e url is not in the cache. */
+
+vector<string>
+HTTPCache::get_conditional_request_headers(const string &url)
+{
+    lock_cache_interface();
+
+    HTTPCacheTable::CacheEntry *entry = 0;
+    vector<string> headers;
+
+    DBG(cerr << "Getting conditional request headers for " << url << endl);
+
+    try {
+        entry = d_http_cache_table->get_locked_entry_from_cache_table(url);
+        if (!entry)
+            throw Error("There is no cache entry for the URL: " + url);
+
+        if (entry->get_etag() != "")
+            headers.push_back(string("If-None-Match: ") + entry->get_etag());
+
+        if (entry->get_lm() > 0) {
+        	time_t lm = entry->get_lm();
+            headers.push_back(string("If-Modified-Since: ")
+                              + date_time_str(&lm));
+        }
+        else if (entry->get_max_age() > 0) {
+        	time_t max_age = entry->get_max_age();
+            headers.push_back(string("If-Modified-Since: ")
+                              + date_time_str(&max_age));
+        }
+        else if (entry->get_expires() > 0) {
+        	time_t expires = entry->get_expires();
+            headers.push_back(string("If-Modified-Since: ")
+                              + date_time_str(&expires));
+        }
+        entry->unlock_read_response();
+        unlock_cache_interface();
+    }
+    catch (...) {
+	unlock_cache_interface();
+	if (entry) {
+	    entry->unlock_read_response();
+	}
+	throw;
+    }
+
+    return headers;
+}
+
+/** Functor/Predicate which orders two MIME headers based on the header name
+    only (discounting the value). */
+
+struct HeaderLess: binary_function<const string&, const string&, bool>
+{
+    bool operator()(const string &s1, const string &s2) const {
+        return s1.substr(0, s1.find(':')) < s2.substr(0, s2.find(':'));
+    }
+};
+
+/** Update the meta data for a response already in the cache. This method
+    provides a way to merge response headers returned from a conditional GET
+    request, for the given URL, with those already present.
+
+    This method locks the class' interface and the cache entry.
+
+    @param url Update the meta data for this cache entry.
+    @param request_time The time (Unix time, seconds since 1 Jan 1970) that
+    the conditional request was made.
+    @param headers New headers, one header per string, returned in the
+    response.
+    @exception Error Thrown if the \c url is not in the cache. */
+
+void
+HTTPCache::update_response(const string &url, time_t request_time,
+                           const vector<string> &headers)
+{
+    lock_cache_interface();
+
+    HTTPCacheTable::CacheEntry *entry = 0;
+    DBG(cerr << "Updating the response headers for: " << url << endl);
+
+    try {
+        entry = d_http_cache_table->get_write_locked_entry_from_cache_table(url);
+        if (!entry)
+            throw Error("There is no cache entry for the URL: " + url);
+
+        // Merge the new headers with the exiting HTTPCacheTable::CacheEntry object.
+        d_http_cache_table->parse_headers(entry, d_max_entry_size, headers);
+
+        // Update corrected_initial_age, freshness_lifetime, response_time.
+        d_http_cache_table->calculate_time(entry, d_default_expiration, request_time);
+
+        // Merge the new headers with those in the persistent store. How:
+        // Load the new headers into a set, then merge the old headers. Since
+        // set<> ignores duplicates, old headers with the same name as a new
+        // header will got into the bit bucket. Define a special compare
+        // functor to make sure that headers are compared using only their
+        // name and not their value too.
+        set<string, HeaderLess> merged_headers;
+
+        // Load in the new headers
+        copy(headers.begin(), headers.end(),
+             inserter(merged_headers, merged_headers.begin()));
+
+        // Get the old headers and load them in.
+        vector<string> old_headers;
+        read_metadata(entry->get_cachename(), old_headers);
+        copy(old_headers.begin(), old_headers.end(),
+             inserter(merged_headers, merged_headers.begin()));
+
+        // Read the values back out. Use reverse iterators with back_inserter
+        // to preserve header order. NB: vector<> does not support push_front
+        // so we can't use front_inserter(). 01/09/03 jhrg
+        vector<string> result;
+        copy(merged_headers.rbegin(), merged_headers.rend(),
+             back_inserter(result));
+
+        write_metadata(entry->get_cachename(), result);
+        entry->unlock_write_response();
+        unlock_cache_interface();
+    }
+    catch (...) {
+        if (entry) {
+            entry->unlock_read_response();
+        }
+        unlock_cache_interface();
+        throw;
+    }
+}
+
+/** Look in the cache and return the status (validity) of the cached
+    response. This method should be used to determine if a cached response
+    requires validation.
+
+    This method locks the class' interface and the cache entry.
+
+    @param url Find the cached response associated with this URL.
+    @return True indicates that the response can be used, False indicates
+    that it must first be validated.
+    @exception Error Thrown if the URL's response is not in the cache. */
+
+bool
+HTTPCache::is_url_valid(const string &url)
+{
+    lock_cache_interface();
+
+    bool freshness;
+    HTTPCacheTable::CacheEntry *entry = 0;
+
+    DBG(cerr << "Is this URL valid? (" << url << ")" << endl);
+
+    try {
+        if (d_always_validate) {
+            unlock_cache_interface();
+            return false;  // force re-validation.
+        }
+
+        entry = d_http_cache_table->get_locked_entry_from_cache_table(url);
+        if (!entry)
+            throw Error("There is no cache entry for the URL: " + url);
+
+        // If we supported range requests, we'd need code here to check if
+        // there was only a partial response in the cache. 10/02/02 jhrg
+
+        // In case this entry is of type "must-revalidate" then we consider it
+        // invalid.
+        if (entry->get_must_revalidate()) {
+            entry->unlock_read_response();
+            unlock_cache_interface();
+            return false;
+        }
+
+        time_t resident_time = time(NULL) - entry->get_response_time();
+        time_t current_age = entry->get_corrected_initial_age() + resident_time;
+
+        // Check that the max-age, max-stale, and min-fresh directives
+        // given in the request cache control header is followed.
+        if (d_max_age >= 0 && current_age > d_max_age) {
+            DBG(cerr << "Cache....... Max-age validation" << endl);
+            entry->unlock_read_response();
+            unlock_cache_interface();
+            return false;
+        }
+        if (d_min_fresh >= 0
+            && entry->get_freshness_lifetime() < current_age + d_min_fresh) {
+            DBG(cerr << "Cache....... Min-fresh validation" << endl);
+            entry->unlock_read_response();
+            unlock_cache_interface();
+            return false;
+        }
+
+        freshness = (entry->get_freshness_lifetime()
+                     + (d_max_stale >= 0 ? d_max_stale : 0) > current_age);
+        entry->unlock_read_response();
+        unlock_cache_interface();
+    }
+    catch (...) {
+    	if (entry) {
+    	    entry->unlock_read_response();
+    	}
+    	unlock_cache_interface();
+        throw;
+    }
+
+    return freshness;
+}
+
+/** Get information from the cache. For a given URL, get the headers, cache
+    object name and body
+    stored in the cache. Note that this method increments the hit counter for
+    <code>url</code>'s entry and \e locks that entry. To release the lock,
+    the method release_cached_response() \e must be called. Methods that
+    block on a locked entry are: get_conditional_request_headers(),
+    update_response() and is_url_valid(). In addition, purge_cache() throws
+    Error if it's called and any entries are locked. The garbage collection
+    system will not reclaim locked entries (but works fine when some entries
+    are locked).
+
+    This method locks the class' interface.
+
+    This method does \e not check to see that the response is valid, just
+    that it is in the cache. To see if a cached response is valid, use
+    is_url_valid(). The FILE* returned can be used for both reading and
+    writing. The latter allows a client to update the body of a cached
+    response without having to first dump it all to a separate file and then
+    copy it into the cache (using cache_response()).
+
+    @param url Get response information for this URL.
+    @param headers Return the response headers in this parameter
+    @param cacheName A value-result parameter; the name of the cache file
+    @return A FILE * to the response body.
+    @exception Error Thrown if the URL's response is not in the cache.
+    @exception InternalErr Thrown if the persistent store cannot be opened. */
+
+FILE * HTTPCache::get_cached_response(const string &url,
+		vector<string> &headers, string &cacheName) {
+    lock_cache_interface();
+
+    FILE *body;
+    HTTPCacheTable::CacheEntry *entry = 0;
+
+    DBG(cerr << "Getting the cached response for " << url << endl);
+
+    try {
+        entry = d_http_cache_table->get_locked_entry_from_cache_table(url);
+        if (!entry) {
+        	unlock_cache_interface();
+        	return 0;
+        }
+
+        cacheName = entry->get_cachename();
+        read_metadata(entry->get_cachename(), headers);
+
+        DBG(cerr << "Headers just read from cache: " << endl);
+        DBGN(copy(headers.begin(), headers.end(), ostream_iterator<string>(cerr, "\n")));
+
+        body = open_body(entry->get_cachename());
+
+        DBG(cerr << "Returning: " << url << " from the cache." << endl);
+
+        d_http_cache_table->bind_entry_to_data(entry, body);
+    }
+    catch (...) {
+    	// Why make this unlock operation conditional on entry?
+        if (entry)
+        	unlock_cache_interface();
+        fclose(body);
+        throw;
+    }
+
+    unlock_cache_interface();
+
+    return body;
+}
+
+/** Get information from the cache. This is a convenience method that calls
+ 	the three parameter version of get_cache_response().
+
+    This method locks the class' interface.
+
+    @param url Get response information for this URL.
+    @param headers Return the response headers in this parameter
+    @return A FILE * to the response body.
+    @exception Error Thrown if the URL's response is not in the cache.
+    @exception InternalErr Thrown if the persistent store cannot be opened. */
+
+FILE *
+HTTPCache::get_cached_response(const string &url, vector<string> &headers)
+{
+	string discard_name;
+	return get_cached_response(url, headers, discard_name);
+}
+
+/** Get a pointer to a cached response body. This is a convenience method that
+ 	calls the three parameter version of get_cache_response().
+
+    This method locks the class' interface.
+
+    @param url Find the body associated with this URL.
+    @return A FILE* that points to the response body.
+    @exception Error Thrown if the URL is not in the cache.
+    @exception InternalErr Thrown if an I/O error is detected. */
+
+FILE *
+HTTPCache::get_cached_response(const string &url)
+{
+	string discard_name;
+	vector<string> discard_headers;
+	return get_cached_response(url, discard_headers, discard_name);
+}
+
+/** Call this method to inform the cache that a particular response is no
+    longer in use. When a response is accessed using get_cached_response(), it
+    is locked so that updates and removal (e.g., by the garbage collector)
+    are not possible. Calling this method frees that lock.
+
+    This method locks the class' interface.
+
+    @param body Release the lock on the response information associated with
+    this FILE *.
+    @exception Error Thrown if \c body does not belong to an entry in the
+    cache or if the entry was already released. */
+
+void
+HTTPCache::release_cached_response(FILE *body)
+{
+    lock_cache_interface();
+
+    try {
+    	d_http_cache_table->uncouple_entry_from_data(body);
+    }
+    catch (...) {
+        unlock_cache_interface();
+        throw;
+    }
+
+    unlock_cache_interface();
+}
+
+/** Purge both the in-memory cache table and the contents of the cache on
+    disk. This method deletes every entry in the persistent store but leaves
+    the structure intact. The client of HTTPCache is responsible for making
+    sure that all threads have released any responses they pulled from the
+    cache. If this method is called when a response is still in use, it will
+    throw an Error object and not purge the cache.
+
+    This method locks the class' interface.
+
+    @exception Error Thrown if an attempt is made to purge the cache when
+    an entry is still in use. */
+
+void
+HTTPCache::purge_cache()
+{
+    lock_cache_interface();
+
+    try {
+        if (d_http_cache_table->is_locked_read_responses())
+            throw Error("Attempt to purge the cache with entries in use.");
+
+        d_http_cache_table->delete_all_entries();
+    }
+    catch (...) {
+        unlock_cache_interface();
+        throw;
+    }
+
+    unlock_cache_interface();
+}
+
+} // namespace libdap
diff --git a/HTTPCache.h b/HTTPCache.h
new file mode 100644
index 0000000..ae29742
--- /dev/null
+++ b/HTTPCache.h
@@ -0,0 +1,277 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2008 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _http_cache_h
+#define _http_cache_h
+
+#include <pthread.h>
+
+#ifdef WIN32
+#include <io.h>   // stat for win32? 09/05/02 jhrg
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+
+#ifndef _http_cache_table_h
+#include "HTTPCacheTable.h"
+#endif
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+#ifndef _internalerr_h
+#include "InternalErr.h"
+#endif
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+// The private method HTTPCache::write_body() could, at one time, throw
+// ResponseTooBig to signal that while writing a response body it was found
+// to be bigger than the max_entry_size property. But I bagged that; the
+// garbage collection methods remove entries larger than max_entry_size. It
+// might be that a really big entry belongs in the cache so long as it
+// doesn't push other entries out. 10/07/02 jhrg
+#ifndef _response_too_big_err_h
+#include "ResponseTooBigErr.h"
+#endif
+
+#ifndef _http_cache_disconnected_mode_h
+#include "HTTPCacheDisconnectedMode.h"
+#endif
+
+#ifndef _signal_handler_registered_err_h
+#include "SignalHandlerRegisteredErr.h"
+#endif
+
+using namespace std;
+
+namespace libdap
+{
+
+// This function is exported so the test code can use it too.
+bool is_hop_by_hop_header(const string &header);
+
+/** Implements a multi-process MT-safe HTTP 1.1 compliant (mostly) cache.
+
+    <i>Clients that run as users lacking a writable HOME directory MUST
+    disable this cache. Use Connect::set_cache_enable(false).</i>
+
+    The original design of this class was taken from the W3C libwww software, 
+    written by Henrik Frystyk Nielsen, Copyright MIT
+    1995. See the file MIT_COPYRIGHT. This software is a complete rewrite in
+    C++ with additional features useful to the DODS and OPeNDAP projects.
+
+    This cache does not implement range checking. Partial responses should
+    not be cached (HFN's version did, but it doesn't mesh well with the DAP
+    for which this is being written).
+
+    The cache uses the local file system to store responses. If it is being
+    used in a MT application, care should be taken to ensure that the number
+    of available file descriptors is not exceeded.
+
+    In addition, when used in a MT program only one thread should use the
+    mutators to set property values. Even though the methods are robust WRT
+    MT software, having several threads change values of cache's properties
+    will lead to odd behavior on the part of the cache. Many of the public
+    methods lock access to the class' interface. This is noted in the
+    documentation for those methods.
+
+    Even though the public interface to the cache is typically locked when
+    accessed, an extra locking mechanism is in place for `entries' which are
+    accessed. If a thread accesses a entry, that response must be locked to
+    prevent it from being updated until the thread tells the cache that it's
+    no longer using it. The method get_cache_response() and
+    get_cache_response_body() both lock an entry; use
+    release_cache_response() to release the lock. Entries are locked using a
+    combination of a counter and a mutex. The following methods block when
+    called on a locked entry: is_url_valid(),
+    get_conditional_request_headers(), update_response(). (The locking scheme
+    could be modified so that a distinction is made between reading from and
+    writing to an entry. In this case is_url_valid() and
+    get_conditional_request_headers() would only lock when an entry is in use
+    for writing. But I haven't done that.)
+
+	@todo Update documentation: get_cache_response() now also serves as 
+	is_url_in_cache() and is_url_valid() should only be called after a locked
+	cached response is accessed using get_cahced_response(). These lock the
+	cache for reading. The methods cache_response() and update_response()
+	lock an entry for writing.
+	
+	@todo Check that the lock-for-write and lock-for-read work together since
+	it's possible that an entry in use might have a stream of readers and never
+	free the 'read-lock' thus blocking a writer.
+	
+    @author James Gallagher <jgallagher at opendap.org> */
+class HTTPCache
+{
+private:
+    string d_cache_root;
+    FILE *d_locked_open_file; // Lock for single process use.
+
+    bool d_cache_enabled;
+    bool d_cache_protected;
+    CacheDisconnectedMode d_cache_disconnected;
+    bool d_expire_ignored;
+    bool d_always_validate;
+
+    unsigned long d_total_size; // How much can we store?
+    unsigned long d_folder_size; // How much of that is meta data?
+    unsigned long d_gc_buffer; // How much memory needed as buffer?
+    unsigned long d_max_entry_size; // Max individual entry size.
+    int d_default_expiration;
+
+    vector<string> d_cache_control;
+    // these are values read from a request-directive Cache-Control header.
+    // Not to be confused with values read from the response or a cached
+    // response (e.g., CacheEntry has a max_age field, too). These fields are
+    // set when the set_cache_control method is called.
+    time_t d_max_age;
+    time_t d_max_stale;  // -1: not set, 0:any response, >0 max time.
+    time_t d_min_fresh;
+
+    // Lock non-const methods (also ones that use the STL).
+    pthread_mutex_t d_cache_mutex;
+    
+    HTTPCacheTable *d_http_cache_table;
+
+    // d_open_files is used by the interrupt handler to clean up
+    vector<string> d_open_files;
+
+    static HTTPCache *_instance;
+
+    friend class HTTPCacheTest; // Unit tests
+    friend class HTTPCacheInterruptHandler;
+
+    // Private methods
+    HTTPCache(const HTTPCache &) {
+    	throw InternalErr(__FILE__, __LINE__, "Unimplemented");
+    }
+    HTTPCache() {
+    	throw InternalErr(__FILE__, __LINE__, "Unimplemented");
+    }
+    HTTPCache &operator=(const HTTPCache &) {
+    	throw InternalErr(__FILE__, __LINE__, "Unimplemented");
+    }
+
+    HTTPCache(string cache_root, bool force);
+
+    static void delete_instance(); // Run by atexit (hence static)
+    
+    void set_cache_root(const string &root = "");
+    void create_cache_root(const string &cache_root);
+    
+    // These will go away when the cache can be used by multiple processes.
+    bool get_single_user_lock(bool force = false);
+    void release_single_user_lock();
+    
+    bool is_url_in_cache(const string &url);
+
+    // I made these four methods so they could be tested by HTTPCacheTest.
+    // Otherwise they would be static functions. jhrg 10/01/02
+    void write_metadata(const string &cachename, const vector<string> &headers);
+    void read_metadata(const string &cachename, vector<string> &headers);
+    int write_body(const string &cachename, const FILE *src);
+    FILE *open_body(const string &cachename);
+
+    bool stopGC() const;
+    bool startGC() const;
+
+    void perform_garbage_collection();
+    void too_big_gc();
+    void expired_gc();
+    void hits_gc();
+
+public:
+    static HTTPCache *instance(const string &cache_root, bool force = false);
+    virtual ~HTTPCache();
+
+    string get_cache_root() const;
+
+    void set_cache_enabled(bool mode);
+    bool is_cache_enabled() const;
+
+    void set_cache_disconnected(CacheDisconnectedMode mode);
+    CacheDisconnectedMode get_cache_disconnected() const;
+
+    void set_expire_ignored(bool mode);
+    bool is_expire_ignored() const;
+
+    void set_max_size(unsigned long size);
+    unsigned long get_max_size() const;
+
+    void set_max_entry_size(unsigned long size);
+    unsigned long get_max_entry_size() const;
+
+    void set_default_expiration(int exp_time);
+    int get_default_expiration() const;
+
+    void set_always_validate(bool validate);
+    bool get_always_validate() const;
+
+    void set_cache_control(const vector<string> &cc);
+    vector<string> get_cache_control();
+
+    void lock_cache_interface() {
+    	DBG(cerr << "Locking interface... ");
+    	LOCK(&d_cache_mutex);
+    	DBGN(cerr << "Done" << endl);
+    }    	
+    void unlock_cache_interface() {
+    	DBG(cerr << "Unlocking interface... " );
+    	UNLOCK(&d_cache_mutex);
+    	DBGN(cerr << "Done" << endl);
+    }
+    
+    // This must lock for writing
+    bool cache_response(const string &url, time_t request_time,
+                        const vector<string> &headers, const FILE *body);
+    void update_response(const string &url, time_t request_time,
+                         const vector<string> &headers);
+
+    // This is separate from get_cached_response() because often an invalid
+    // cache entry just needs a header update. That is best left to the HTTP
+    // Connection code.
+    bool is_url_valid(const string &url);
+    
+    // Lock these for reading
+    vector<string> get_conditional_request_headers(const string &url);
+    FILE *get_cached_response(const string &url, vector<string> &headers,
+			      			  string &cacheName);
+    FILE *get_cached_response(const string &url, vector<string> &headers);
+    FILE *get_cached_response(const string &url);
+
+    void release_cached_response(FILE *response);
+
+    void purge_cache();
+};
+
+} // namespace libdap
+
+#endif // _http_cache_h
diff --git a/HTTPCacheDisconnectedMode.h b/HTTPCacheDisconnectedMode.h
new file mode 100644
index 0000000..e474c46
--- /dev/null
+++ b/HTTPCacheDisconnectedMode.h
@@ -0,0 +1,55 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _http_cache_disconnected_mode_h
+#define _http_cache_disconnected_mode_h
+
+namespace libdap
+{
+
+/** Disconnected Operation
+
+    The cache can be set to handle disconnected operation where it does not
+    use the network to validate entries and does not attempt to load new
+    documents. All requests that cannot be fulfilled by the cache will be
+    returned with a "504 Gateway Timeout" response. There are two operational
+    disconnected modes:
+
+    No network activity at all: Here it uses its own persistent cache to
+    answer the request, if possible.
+
+    Forward all disconnected requests to a proxy cache: Here it uses the
+    HTTP/1.1 cache-control header to indicate that the proxy should operate in
+    disconnected mode. */
+
+typedef enum {
+    DISCONNECT_NONE     = 0,
+    DISCONNECT_NORMAL   = 1,
+    DISCONNECT_EXTERNAL = 2
+} CacheDisconnectedMode;
+
+} // namespace libdap
+
+#endif // _http_cache_disconnected_mode_h
diff --git a/HTTPCacheInterruptHandler.h b/HTTPCacheInterruptHandler.h
new file mode 100644
index 0000000..98f253f
--- /dev/null
+++ b/HTTPCacheInterruptHandler.h
@@ -0,0 +1,95 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef http_cache_interrupt_handler_h
+#define http_cache_interrupt_handler_h
+
+#include <signal.h>
+
+#include <cassert>
+#include <iostream>
+#include <algorithm>
+
+#include "HTTPCache.h"
+#include "EventHandler.h"
+#include "debug.h"
+
+namespace libdap
+{
+
+static void
+unlink_file(const string &f)
+{
+    unlink(f.c_str());
+}
+
+/** Handle SIGINT for HTTPCache. When the cache is in use and the process is
+    sent SIGINT, we must make sure that the cache is left in a consistent
+    state. This includes removing the lock file, updating the index file and
+    making sure no partially written data or meta data files exist.
+
+    @see EventHandler
+    @see SignalHandler
+    @see HTTPCache
+    @author James Gallagher <jgallagher at opendap.org> */
+class HTTPCacheInterruptHandler : public EventHandler
+{
+private:
+
+public:
+    ///
+    HTTPCacheInterruptHandler()
+    {}
+
+    ///
+    virtual ~HTTPCacheInterruptHandler()
+    {}
+
+    /** Handle SIGINT. This handler first deletes any files opened but not
+    added to the cache index files and then calls
+    HTTPCache::delete_instance().
+
+    @param signum We know it is SIGINT; included here as a check and only
+    when NDEBUG is not defined.
+    @return Never returns. */
+    virtual void handle_signal(int signum)
+    {
+        assert(signum == SIGINT);
+        DBG(cerr << "Inside the HTTPCacheInterruptHandler." << endl);
+
+        vector<string> *of = &HTTPCache::_instance->d_open_files;
+
+        DBG(copy(of->begin(), of->end(),
+                 ostream_iterator<string>(cerr, "\n")));
+
+        for_each(of->begin(), of->end(), unlink_file);
+
+        HTTPCache::delete_instance();
+    }
+};
+
+} // namespace libdap
+
+#endif // http_cache_interrupt_handler_h
diff --git a/HTTPCacheResponse.h b/HTTPCacheResponse.h
new file mode 100644
index 0000000..b9d5c23
--- /dev/null
+++ b/HTTPCacheResponse.h
@@ -0,0 +1,96 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef cache_http_response_h
+#define cache_http_response_h
+
+#include <cstdio>
+
+#ifndef response_h
+#include "Response.h"
+#endif
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+namespace libdap
+{
+
+/** Encapsulate a response. Instead of directly returning the FILE pointer
+    from which a response is read, return an instance of this object. */
+class HTTPCacheResponse : public HTTPResponse
+{
+private:
+    HTTPCache *d_cache;  // pointer to singleton instance
+
+protected:
+    /** @name Suppressed default methods */
+    //@{
+    HTTPCacheResponse()
+    {}
+    HTTPCacheResponse(const HTTPCacheResponse &rs) : HTTPResponse(rs)
+    {}
+    HTTPCacheResponse &operator=(const HTTPCacheResponse &)
+    {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented assignment");
+    }
+    //@}
+
+public:
+    /** Build a Response object. Instances of this class are used to
+    represent responses from a local HTTP/1.1 cache. The stream and
+    headers pointer are passed to the parent (HTTPResponse); there's no
+    temporary file for the parent to manage since the body is read from a
+    file managed by the cache subsystem. This class releases the lock on
+    the cache entry when the destructor is called. */
+    HTTPCacheResponse(FILE *s, int status_code, vector<string> *headers, HTTPCache *c)
+            : HTTPResponse(s, status_code, headers, ""), d_cache(c)
+    {}
+
+    /** Build a Response object. Instances of this class are used to
+    represent responses from a local HTTP/1.1 cache. The stream and
+    headers pointer are passed to the parent (HTTPResponse); there's no
+    temporary file for the parent to manage since the body is read from a
+    file managed by the cache subsystem. This class releases the lock on
+    the cache entry when the destructor is called. */
+    HTTPCacheResponse(FILE *s, int status_code, vector<string> *headers,
+	    const string &file_name, HTTPCache *c)
+            : HTTPResponse(s, status_code, headers, file_name), d_cache(c)
+    {}
+
+    /** Free the cache entry lock. Call the parent's destructor. */
+    virtual ~HTTPCacheResponse()
+    {
+        DBG(cerr << "Freeing HTTPCache resources... ");
+        set_file(""); // This keeps ~HTTPResponse() from removing the cache entry.
+        d_cache->release_cached_response(get_stream());
+        DBGN(cerr << endl);
+    }
+};
+
+} // namespace libdap
+
+#endif // cache_http_response_h
diff --git a/HTTPCacheTable.cc b/HTTPCacheTable.cc
new file mode 100644
index 0000000..1ac4ec4
--- /dev/null
+++ b/HTTPCacheTable.cc
@@ -0,0 +1,863 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+// #define DODS_DEBUG
+
+// TODO: Remove unneeded includes.
+
+#include <pthread.h>
+#include <limits.h>
+#include <unistd.h>   // for stat
+#include <sys/types.h>  // for stat and mkdir
+#include <sys/stat.h>
+
+#include <cstring>
+#include <iostream>
+#include <sstream>
+#include <algorithm>
+#include <iterator>
+#include <set>
+
+#include "Error.h"
+#include "InternalErr.h"
+#include "ResponseTooBigErr.h"
+#ifndef WIN32
+#include "SignalHandler.h"
+#endif
+#include "HTTPCacheInterruptHandler.h"
+#include "HTTPCacheTable.h"
+
+#include "util_mit.h"
+#include "debug.h"
+
+#ifdef WIN32
+#include <direct.h>
+#include <time.h>
+#include <fcntl.h>
+#define MKDIR(a,b) _mkdir((a))
+#define REMOVE(a) do { \
+		int s = remove((a)); \
+		if (s != 0) \
+			throw InternalErr(__FILE__, __LINE__, "Coule not remove file: " + long_to_string(s)); \
+	} while(0);
+#define MKSTEMP(a) _open(_mktemp((a)),_O_CREAT,_S_IREAD|_S_IWRITE)
+#define DIR_SEPARATOR_CHAR '\\'
+#define DIR_SEPARATOR_STR "\\"
+#else
+#define MKDIR(a,b) mkdir((a), (b))
+#define REMOVE(a) remove((a))
+#define MKSTEMP(a) mkstemp((a))
+#define DIR_SEPARATOR_CHAR '/'
+#define DIR_SEPARATOR_STR "/"
+#endif
+
+#define CACHE_META ".meta"
+#define CACHE_INDEX ".index"
+#define CACHE_EMPTY_ETAG "@cache@"
+
+#define NO_LM_EXPIRATION 24*3600 // 24 hours
+#define MAX_LM_EXPIRATION 48*3600 // Max expiration from LM
+
+// If using LM to find the expiration then take 10% and no more than
+// MAX_LM_EXPIRATION.
+#ifndef LM_EXPIRATION
+#define LM_EXPIRATION(t) (min((MAX_LM_EXPIRATION), static_cast<int>((t) / 10)))
+#endif
+
+const int CACHE_TABLE_SIZE = 1499;
+
+using namespace std;
+
+namespace libdap {
+
+/** Compute the hash value for a URL.
+    @param url
+    @return An integer hash code between 0 and CACHE_TABLE_SIZE. */
+int
+get_hash(const string &url)
+{
+    int hash = 0;
+
+    for (const char *ptr = url.c_str(); *ptr; ptr++)
+        hash = (int)((hash * 3 + (*(unsigned char *)ptr)) % CACHE_TABLE_SIZE);
+
+    return hash;
+}
+
+HTTPCacheTable::HTTPCacheTable(const string &cache_root, int block_size) :
+    d_cache_root(cache_root), d_block_size(block_size), d_current_size(0), d_new_entries(0)
+{
+    d_cache_index = cache_root + CACHE_INDEX;
+
+    d_cache_table = new CacheEntries*[CACHE_TABLE_SIZE];
+
+    // Initialize the cache table.
+    for (int i = 0; i < CACHE_TABLE_SIZE; ++i)
+	d_cache_table[i] = 0;
+
+    cache_index_read();
+}
+
+/** Called by for_each inside ~HTTPCache().
+    @param e The cache entry to delete. */
+
+static inline void
+delete_cache_entry(HTTPCacheTable::CacheEntry *e)
+{
+    DBG2(cerr << "Deleting CacheEntry: " << e << endl);
+    delete e;
+}
+
+HTTPCacheTable::~HTTPCacheTable()
+{
+    for (int i = 0; i < CACHE_TABLE_SIZE; ++i) {
+	HTTPCacheTable::CacheEntries *cp = get_cache_table()[i];
+	if (cp) {
+	    // delete each entry
+	    for_each(cp->begin(), cp->end(), delete_cache_entry);
+
+	    // now delete the vector that held the entries
+	    delete get_cache_table()[i];
+	    get_cache_table()[i] = 0;
+	}
+    }
+
+    delete[] d_cache_table;
+}
+
+/** Functor which deletes and nulls a single CacheEntry if it has expired.
+    This functor is called by expired_gc which then uses the
+    erase(remove(...) ...) idiom to really remove all the vector entries that
+    belonged to the deleted CacheEntry objects.
+
+    @see expired_gc. */
+
+class DeleteExpired : public unary_function<HTTPCacheTable::CacheEntry *&, void> {
+	time_t d_time;
+	HTTPCacheTable &d_table;
+
+public:
+	DeleteExpired(HTTPCacheTable &table, time_t t) :
+		d_time(t), d_table(table) {
+		if (!t)
+			d_time = time(0); // 0 == now
+	} 
+
+	void operator()(HTTPCacheTable::CacheEntry *&e) {
+		if (e && !e->readers && (e->freshness_lifetime
+				< (e->corrected_initial_age + (d_time - e->response_time)))) {
+			DBG(cerr << "Deleting expired cache entry: " << e->url << endl);
+			d_table.remove_cache_entry(e);
+			delete e; e = 0;
+		}
+	}
+};
+
+// @param time base deletes againt this time, defaults to 0 (now)
+void HTTPCacheTable::delete_expired_entries(time_t time) {
+	// Walk through and delete all the expired entries.
+	for (int cnt = 0; cnt < CACHE_TABLE_SIZE; cnt++) {
+		HTTPCacheTable::CacheEntries *slot = get_cache_table()[cnt];
+		if (slot) {
+			for_each(slot->begin(), slot->end(), DeleteExpired(*this, time));
+			slot->erase(remove(slot->begin(), slot->end(),
+					static_cast<HTTPCacheTable::CacheEntry *>(0)), slot->end());
+		}
+	}
+}
+
+/** Functor which deletes and nulls a single CacheEntry which has less than
+    or equal to \c hits hits or if it is larger than the cache's
+    max_entry_size property.
+
+    @see hits_gc. */
+
+class DeleteByHits : public unary_function<HTTPCacheTable::CacheEntry *&, void> {
+	HTTPCacheTable &d_table;
+	int d_hits;
+
+public:
+	DeleteByHits(HTTPCacheTable &table, int hits) :
+		d_table(table), d_hits(hits) {
+	}
+
+	void operator()(HTTPCacheTable::CacheEntry *&e) {
+		if (e && !e->readers && e->hits <= d_hits) {
+			DBG(cerr << "Deleting cache entry: " << e->url << endl);
+			d_table.remove_cache_entry(e);
+			delete e; e = 0;
+		}
+	}
+};
+
+void 
+HTTPCacheTable::delete_by_hits(int hits) {
+    for (int cnt = 0; cnt < CACHE_TABLE_SIZE; cnt++) {
+        if (get_cache_table()[cnt]) {
+            HTTPCacheTable::CacheEntries *slot = get_cache_table()[cnt];
+            for_each(slot->begin(), slot->end(), DeleteByHits(*this, hits));
+            slot->erase(remove(slot->begin(), slot->end(),
+                               static_cast<HTTPCacheTable::CacheEntry*>(0)),
+                        slot->end());
+
+        }
+    }
+}
+
+/** Functor which deletes and nulls a single CacheEntry which is larger than 
+    a given size.
+    @see hits_gc. */
+
+class DeleteBySize : public unary_function<HTTPCacheTable::CacheEntry *&, void> {
+	HTTPCacheTable &d_table;
+	unsigned int d_size;
+
+public:
+	DeleteBySize(HTTPCacheTable &table, unsigned int size) :
+		d_table(table), d_size(size) {
+	}
+
+	void operator()(HTTPCacheTable::CacheEntry *&e) {
+		if (e && !e->readers && e->size > d_size) {
+			DBG(cerr << "Deleting cache entry: " << e->url << endl);
+			d_table.remove_cache_entry(e);
+			delete e; e = 0;
+		}
+	}
+};
+
+void HTTPCacheTable::delete_by_size(unsigned int size) {
+    for (int cnt = 0; cnt < CACHE_TABLE_SIZE; cnt++) {
+        if (get_cache_table()[cnt]) {
+            HTTPCacheTable::CacheEntries *slot = get_cache_table()[cnt];
+            for_each(slot->begin(), slot->end(), DeleteBySize(*this, size));
+            slot->erase(remove(slot->begin(), slot->end(),
+                               static_cast<HTTPCacheTable::CacheEntry*>(0)),
+                        slot->end());
+
+        }
+    }
+}
+
+/** @name Cache Index
+
+    These methods manage the cache's index file. Each cache holds an index
+    file named \c .index which stores the cache's state information. */
+
+//@{
+
+/** Remove the cache index file.
+
+    A private method.
+
+    @return True if the file was deleted, otherwise false. */
+
+bool
+HTTPCacheTable::cache_index_delete()
+{
+	d_new_entries = 0;
+	
+    return (REMOVE(d_cache_index.c_str()) == 0);
+}
+
+/** Read the saved set of cached entries from disk. Consistency between the
+    in-memory cache and the index is maintained by only reading the index
+    file when the HTTPCache object is created!
+
+    A private method.
+
+    @return True when a cache index was found and read, false otherwise. */
+
+bool
+HTTPCacheTable::cache_index_read()
+{
+    FILE *fp = fopen(d_cache_index.c_str(), "r");
+    // If the cache index can't be opened that's OK; start with an empty
+    // cache. 09/05/02 jhrg
+    if (!fp) {
+        return false;
+    }
+
+    char line[1024];
+    while (!feof(fp) && fgets(line, 1024, fp)) {
+    	add_entry_to_cache_table(cache_index_parse_line(line));
+        DBG2(cerr << line << endl);
+    }
+
+    int res = fclose(fp) ;
+    if (res) {
+        DBG(cerr << "HTTPCache::cache_index_read - Failed to close " << (void *)fp << endl);
+    }
+
+    d_new_entries = 0;
+    
+    return true;
+}
+
+/** Parse one line of the index file.
+
+    A private method.
+
+    @param line A single line from the \c .index file.
+    @return A CacheEntry initialized with the information from \c line. */
+
+HTTPCacheTable::CacheEntry *
+HTTPCacheTable::cache_index_parse_line(const char *line)
+{
+    // Read the line and create the cache object
+	HTTPCacheTable::CacheEntry *entry = new HTTPCacheTable::CacheEntry;
+    istringstream iss(line);
+    iss >> entry->url;
+    iss >> entry->cachename;
+
+    iss >> entry->etag;
+    if (entry->etag == CACHE_EMPTY_ETAG)
+        entry->etag = "";
+
+    iss >> entry->lm;
+    iss >> entry->expires;
+    iss >> entry->size;
+    iss >> entry->range; // range is not used. 10/02/02 jhrg
+
+    iss >> entry->hash;
+    iss >> entry->hits;
+    iss >> entry->freshness_lifetime;
+    iss >> entry->response_time;
+    iss >> entry->corrected_initial_age;
+
+    iss >> entry->must_revalidate;
+
+    return entry;
+}
+
+/** Functor which writes a single CacheEntry to the \c .index file. */
+
+class WriteOneCacheEntry :
+	public unary_function<HTTPCacheTable::CacheEntry *, void>
+{
+
+    FILE *d_fp;
+
+public:
+    WriteOneCacheEntry(FILE *fp) : d_fp(fp)
+    {}
+
+    void operator()(HTTPCacheTable::CacheEntry *e)
+    {
+        if (e && fprintf(d_fp,
+                         "%s %s %s %ld %ld %ld %c %d %d %ld %ld %ld %c\r\n",
+                         e->url.c_str(),
+                         e->cachename.c_str(),
+                         e->etag == "" ? CACHE_EMPTY_ETAG : e->etag.c_str(),
+                         (long)(e->lm),
+                         (long)(e->expires),
+                         e->size,
+                         e->range ? '1' : '0', // not used. 10/02/02 jhrg
+                         e->hash,
+                         e->hits,
+                         (long)(e->freshness_lifetime),
+                         (long)(e->response_time),
+                         (long)(e->corrected_initial_age),
+                         e->must_revalidate ? '1' : '0') < 0)
+            throw Error("Cache Index. Error writing cache index\n");
+    }
+};
+
+/** Walk through the list of cached objects and write the cache index file to
+    disk. If the file does not exist, it is created. If the file does exist,
+    it is overwritten. As a side effect, zero the new_entries counter.
+
+    A private method.
+
+    @exception Error Thrown if the index file cannot be opened for writing.
+    @note The HTTPCache destructor calls this method and silently ignores
+    this exception. */
+void
+HTTPCacheTable::cache_index_write()
+{
+    DBG(cerr << "Cache Index. Writing index " << d_cache_index << endl);
+
+    // Open the file for writing.
+    FILE * fp = NULL;
+    if ((fp = fopen(d_cache_index.c_str(), "wb")) == NULL) {
+        throw Error(string("Cache Index. Can't open `") + d_cache_index
+                    + string("' for writing"));
+    }
+
+    // Walk through the list and write it out. The format is really
+    // simple as we keep it all in ASCII.
+
+    for (int cnt = 0; cnt < CACHE_TABLE_SIZE; cnt++) {
+        HTTPCacheTable::CacheEntries *cp = get_cache_table()[cnt];
+        if (cp)
+            for_each(cp->begin(), cp->end(), WriteOneCacheEntry(fp));
+    }
+
+    /* Done writing */
+    int res = fclose(fp);
+    if (res) {
+        DBG(cerr << "HTTPCache::cache_index_write - Failed to close "
+            << (void *)fp << endl);
+    }
+
+    d_new_entries = 0;
+}
+
+//@} End of the cache index methods.
+/** Create the directory path for cache file. The cache uses a set of
+    directories within d_cache_root to store individual responses. The name
+    of the directory that holds a given response is the value returned by the
+    get_hash() function (i.e., it's a number). If the directory exists, this
+    method does nothing.
+
+    A private method.
+
+    @param hash The hash value (i.e., directory name). An integer between 0
+    and CACHE_TABLE_SIZE (See HTTPCache.h).
+    @return The pathname to the directory (even if it already existed).
+    @exception Error Thrown if the directory cannot be created.*/
+
+string
+HTTPCacheTable::create_hash_directory(int hash)
+{
+    struct stat stat_info;
+    ostringstream path;
+
+    path << d_cache_root << hash;
+    string p = path.str();
+
+    if (stat(p.c_str(), &stat_info) == -1) {
+        DBG2(cerr << "Cache....... Create dir " << p << endl);
+        if (MKDIR(p.c_str(), 0777) < 0) {
+            DBG2(cerr << "Cache....... Can't create..." << endl);
+            throw Error("Could not create cache slot to hold response! Check the write permissions on your disk cache directory. Cache root: " + d_cache_root + ".");
+        }
+    }
+    else {
+        DBG2(cerr << "Cache....... Directory " << p << " already exists"
+             << endl);
+    }
+
+    return p;
+}
+
+/** Create the directory for this url (using the hash value from get_hash())
+    and a file within that directory to hold the response's information. The
+    cache name and cache_body_fd fields of \c entry are updated.
+
+    mkstemp opens the file it creates, which is a good thing but it makes
+    tracking resources hard for the HTTPCache object (because an exception
+    might cause a file descriptor resource leak). So I close that file
+    descriptor here.
+
+    A private method.
+
+    @param entry The cache entry object to operate on.
+    @exception Error If the file for the response's body cannot be created. */
+
+void
+HTTPCacheTable::create_location(HTTPCacheTable::CacheEntry *entry)
+{
+    string hash_dir = create_hash_directory(entry->hash);
+#ifdef WIN32
+    hash_dir += "\\dodsXXXXXX";
+#else
+    hash_dir += "/dodsXXXXXX"; // mkstemp uses six characters.
+#endif
+
+    // mkstemp uses the storage passed to it; must be writable and local.
+    // char *templat = new char[hash_dir.size() + 1];
+    vector<char> templat(hash_dir.size() + 1);
+    strncpy(&templat[0], hash_dir.c_str(), hash_dir.size() + 1);
+
+    // Open truncated for update. NB: mkstemp() returns a file descriptor.
+    // man mkstemp says "... The file is opened with the O_EXCL flag,
+    // guaranteeing that when mkstemp returns successfully we are the only
+    // user." 09/19/02 jhrg
+#ifndef WIN32
+    // Make sure that temp files are accessible only by the owner.
+    umask(077);
+#endif
+    int fd = MKSTEMP(&templat[0]); // fd mode is 666 or 600 (Unix)
+    if (fd < 0) {
+        // delete[] templat; templat = 0;
+        close(fd);
+        throw Error("The HTTP Cache could not create a file to hold the response; it will not be cached.");
+    }
+
+    entry->cachename = &templat[0];
+    // delete[] templat; templat = 0;
+    close(fd);
+}
+
+
+/** compute real disk space for an entry. */
+static inline int
+entry_disk_space(int size, unsigned int block_size)
+{
+    unsigned int num_of_blocks = (size + block_size) / block_size;
+    
+    DBG(cerr << "size: " << size << ", block_size: " << block_size
+        << ", num_of_blocks: " << num_of_blocks << endl);
+
+    return num_of_blocks * block_size;
+}
+
+/** @name Methods to manipulate instances of CacheEntry. */
+
+//@{
+
+/** Add a CacheEntry to the cache table. As each entry is read, load it into
+    the in-memory cache table and update the HTTPCache's current_size. The
+    later is used by the garbage collection method.
+
+    @param entry The CacheEntry instance to add. */
+void
+HTTPCacheTable::add_entry_to_cache_table(CacheEntry *entry)
+{
+    int hash = entry->hash;
+
+    if (!d_cache_table[hash])
+        d_cache_table[hash] = new CacheEntries;
+
+    d_cache_table[hash]->push_back(entry);
+    
+    DBG(cerr << "add_entry_to_cache_table, current_size: " << d_current_size
+        << ", entry->size: " << entry->size << ", block size: " << d_block_size 
+        << endl);
+    
+    d_current_size += entry_disk_space(entry->size, d_block_size);
+
+    DBG(cerr << "add_entry_to_cache_table, current_size: " << d_current_size << endl);
+    
+    increment_new_entries();
+}
+
+/** Get a pointer to a CacheEntry from the cache table.
+
+    @param url Look for this URL. */
+HTTPCacheTable::CacheEntry *
+HTTPCacheTable::get_locked_entry_from_cache_table(const string &url) /*const*/
+{
+    return get_locked_entry_from_cache_table(get_hash(url), url);
+}
+
+/** Get a pointer to a CacheEntry from the cache table. Providing a way to
+    pass the hash code into this method makes it easier to test for correct
+    behavior when two entries collide. 10/07/02 jhrg
+
+    @param hash The hash code for \c url.
+    @param url Look for this URL.
+    @return The matching CacheEntry instance or NULL if none was found. */
+HTTPCacheTable::CacheEntry *
+HTTPCacheTable::get_locked_entry_from_cache_table(int hash, const string &url) /*const*/
+{
+    DBG(cerr << "url: " << url << "; hash: " << hash << endl);
+    DBG(cerr << "d_cache_table: " << hex << d_cache_table << dec << endl);
+    if (d_cache_table[hash]) {
+	CacheEntries *cp = d_cache_table[hash];
+	for (CacheEntriesIter i = cp->begin(); i != cp->end(); ++i) {
+	    // Must test *i because perform_garbage_collection may have
+	    // removed this entry; the CacheEntry will then be null.
+	    if ((*i) && (*i)->url == url) {
+		(*i)->lock_read_response(); // Lock the response
+		return *i;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+/** Get a pointer to a CacheEntry from the cache table. Providing a way to
+    pass the hash code into this method makes it easier to test for correct
+    behavior when two entries collide. 10/07/02 jhrg
+
+    @param url Look for this URL.
+    @return The matching CacheEntry instance or NULL if none was found. */
+HTTPCacheTable::CacheEntry *
+HTTPCacheTable::get_write_locked_entry_from_cache_table(const string &url)
+{
+	int hash = get_hash(url);
+    if (d_cache_table[hash]) {
+        CacheEntries *cp = d_cache_table[hash];
+        for (CacheEntriesIter i = cp->begin(); i != cp->end(); ++i) {
+            // Must test *i because perform_garbage_collection may have
+            // removed this entry; the CacheEntry will then be null.
+            if ((*i) && (*i)->url == url) {
+            	(*i)->lock_write_response();	// Lock the response
+            	return *i;
+            }
+        }
+    }
+
+    return 0;
+}
+
+/** Remove a CacheEntry. This means delete the entry's files on disk and free
+    the CacheEntry object. The caller should null the entry's pointer in the
+    cache_table. The total size of the cache is decremented once the entry is
+    deleted.
+
+    @param entry The CacheEntry to delete.
+    @exception InternalErr Thrown if \c entry is in use. */
+void
+HTTPCacheTable::remove_cache_entry(HTTPCacheTable::CacheEntry *entry)
+{
+    // This should never happen; all calls to this method are protected by
+    // the caller, hence the InternalErr.
+    if (entry->readers)
+        throw InternalErr(__FILE__, __LINE__, "Tried to delete a cache entry that is in use.");
+
+    REMOVE(entry->cachename.c_str());
+    REMOVE(string(entry->cachename + CACHE_META).c_str());
+
+    DBG(cerr << "remove_cache_entry, current_size: " << get_current_size() << endl);
+
+    unsigned int eds = entry_disk_space(entry->size, get_block_size());
+    set_current_size((eds > get_current_size()) ? 0 : get_current_size() - eds);
+    
+    DBG(cerr << "remove_cache_entry, current_size: " << get_current_size() << endl);
+}
+
+/** Functor which deletes and nulls a CacheEntry if the given entry matches
+    the url. */
+class DeleteCacheEntry: public unary_function<HTTPCacheTable::CacheEntry *&, void>
+{
+    string d_url;
+    HTTPCacheTable *d_cache_table;
+
+public:
+    DeleteCacheEntry(HTTPCacheTable *c, const string &url)
+            : d_url(url), d_cache_table(c)
+    {}
+
+    void operator()(HTTPCacheTable::CacheEntry *&e)
+    {
+        if (e && e->url == d_url) {
+        	e->lock_write_response();
+            d_cache_table->remove_cache_entry(e);
+        	e->unlock_write_response();
+            delete e; e = 0;
+        }
+    }
+};
+
+/** Find the CacheEntry for the given url and remove both its information in
+    the persistent store and the entry in d_cache_table. If \c url is not in
+    the cache, this method does nothing.
+
+    @param url Remove this URL's entry.
+    @exception InternalErr Thrown if the CacheEntry for \c url is locked. */
+void
+HTTPCacheTable::remove_entry_from_cache_table(const string &url)
+{
+    int hash = get_hash(url);
+    if (d_cache_table[hash]) {
+        CacheEntries *cp = d_cache_table[hash];
+        for_each(cp->begin(), cp->end(), DeleteCacheEntry(this, url));
+        cp->erase(remove(cp->begin(), cp->end(), static_cast<HTTPCacheTable::CacheEntry*>(0)),
+                  cp->end());
+    }
+}
+
+/** Functor to delete and null all unlocked HTTPCacheTable::CacheEntry objects. */
+
+class DeleteUnlockedCacheEntry: public unary_function<HTTPCacheTable::CacheEntry *&, void> {
+    HTTPCacheTable &d_table;
+
+public:
+    DeleteUnlockedCacheEntry(HTTPCacheTable &t) :
+	d_table(t)
+    {
+    }
+    void operator()(HTTPCacheTable::CacheEntry *&e)
+    {
+	if (e) {
+	    d_table.remove_cache_entry(e);
+	    delete e;
+	    e = 0;
+	}
+    }
+};
+
+void HTTPCacheTable::delete_all_entries()
+{
+    // Walk through the cache table and, for every entry in the cache, delete
+    // it on disk and in the cache table.
+    for (int cnt = 0; cnt < CACHE_TABLE_SIZE; cnt++) {
+	HTTPCacheTable::CacheEntries *slot = get_cache_table()[cnt];
+	if (slot) {
+	    for_each(slot->begin(), slot->end(), DeleteUnlockedCacheEntry(*this));
+	    slot->erase(remove(slot->begin(), slot->end(), static_cast<HTTPCacheTable::CacheEntry *> (0)), slot->end());
+	}
+    }
+
+    cache_index_delete();
+}
+
+/** Calculate the corrected_initial_age of the object. We use the time when
+    this function is called as the response_time as this is when we have
+    received the complete response. This may cause a delay if the response
+    header is very big but should not cause any incorrect behavior.
+
+    A private method.
+
+    @param entry The CacheEntry object.
+    @param default_expiration The default value of the cached object's
+    expiration time.
+    @param request_time When was the request made? I think this value must be
+    passed into the method that calls this method... */
+
+void
+HTTPCacheTable::calculate_time(HTTPCacheTable::CacheEntry *entry, int default_expiration, time_t request_time)
+{
+    entry->response_time = time(NULL);
+    time_t apparent_age = max(0, static_cast<int>(entry->response_time - entry->date));
+    time_t corrected_received_age = max(apparent_age, entry->age);
+    time_t response_delay = entry->response_time - request_time;
+    entry->corrected_initial_age = corrected_received_age + response_delay;
+
+    // Estimate an expires time using the max-age and expires time. If we
+    // don't have an explicit expires time then set it to 10% of the LM date
+    // (although max 24 h). If no LM date is available then use 24 hours.
+    time_t freshness_lifetime = entry->max_age;
+    if (freshness_lifetime < 0) {
+        if (entry->expires < 0) {
+            if (entry->lm < 0) {
+                freshness_lifetime = default_expiration;
+            }
+            else {
+                freshness_lifetime = LM_EXPIRATION(entry->date - entry->lm);
+            }
+        }
+        else
+            freshness_lifetime = entry->expires - entry->date;
+    }
+
+    entry->freshness_lifetime = max(0, static_cast<int>(freshness_lifetime));
+
+    DBG2(cerr << "Cache....... Received Age " << entry->age
+         << ", corrected " << entry->corrected_initial_age
+         << ", freshness lifetime " << entry->freshness_lifetime << endl);
+}
+
+/** Parse various headers from the vector (which can be retrieved from
+    libcurl once a response is received) and load the CacheEntry object with
+    values. This method should only be called with headers from a response
+    (it should not be used to parse request headers).
+
+    A private method.
+
+    @param entry Store values from the headers here.
+    @param max_entry_size DO not cache entries larger than this.
+    @param headers A vector of header lines. */
+
+void HTTPCacheTable::parse_headers(HTTPCacheTable::CacheEntry *entry, unsigned long max_entry_size,
+	const vector<string> &headers)
+{
+    vector<string>::const_iterator i;
+    for (i = headers.begin(); i != headers.end(); ++i) {
+	// skip a blank header.
+	if ((*i).empty())
+	    continue;
+
+	string::size_type colon = (*i).find(':');
+
+	// skip a header with no colon in it.
+	if (colon == string::npos)
+	    continue;
+
+	string header = (*i).substr(0, (*i).find(':'));
+	string value = (*i).substr((*i).find(": ") + 2);
+	DBG2(cerr << "Header: " << header << endl);DBG2(cerr << "Value: " << value << endl);
+
+	if (header == "ETag") {
+	    entry->etag = value;
+	}
+	else if (header == "Last-Modified") {
+	    entry->lm = parse_time(value.c_str());
+	}
+	else if (header == "Expires") {
+	    entry->expires = parse_time(value.c_str());
+	}
+	else if (header == "Date") {
+	    entry->date = parse_time(value.c_str());
+	}
+	else if (header == "Age") {
+	    entry->age = parse_time(value.c_str());
+	}
+	else if (header == "Content-Length") {
+	    unsigned long clength = strtoul(value.c_str(), 0, 0);
+	    if (clength > max_entry_size)
+		entry->set_no_cache(true);
+	}
+	else if (header == "Cache-Control") {
+	    // Ignored Cache-Control values: public, private, no-transform,
+	    // proxy-revalidate, s-max-age. These are used by shared caches.
+	    // See section 14.9 of RFC 2612. 10/02/02 jhrg
+	    if (value == "no-cache" || value == "no-store")
+		// Note that we *can* store a 'no-store' response in volatile
+		// memory according to RFC 2616 (section 14.9.2) but those
+		// will be rare coming from DAP servers. 10/02/02 jhrg
+		entry->set_no_cache(true);
+	    else if (value == "must-revalidate")
+		entry->must_revalidate = true;
+	    else if (value.find("max-age") != string::npos) {
+		string max_age = value.substr(value.find("=" + 1));
+		entry->max_age = parse_time(max_age.c_str());
+	    }
+	}
+    }
+}
+
+//@} End of the CacheEntry methods.
+
+// @TODO Change name to record locked response
+void HTTPCacheTable::bind_entry_to_data(HTTPCacheTable::CacheEntry *entry, FILE *body) {
+	entry->hits++;  // Mark hit
+    d_locked_entries[body] = entry; // record lock, see release_cached_r...
+}
+
+void HTTPCacheTable::uncouple_entry_from_data(FILE *body) {
+
+    HTTPCacheTable::CacheEntry *entry = d_locked_entries[body];
+    if (!entry)
+        throw InternalErr("There is no cache entry for the response given.");
+
+    d_locked_entries.erase(body);
+    entry->unlock_read_response();
+
+    if (entry->readers < 0)
+        throw InternalErr("An unlocked entry was released");
+}
+
+bool HTTPCacheTable::is_locked_read_responses() {
+	return !d_locked_entries.empty();
+}
+
+} // namespace libdap
diff --git a/HTTPCacheTable.h b/HTTPCacheTable.h
new file mode 100644
index 0000000..4d6fb95
--- /dev/null
+++ b/HTTPCacheTable.h
@@ -0,0 +1,378 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2008 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _http_cache_table_h
+#define _http_cache_table_h
+
+//#define DODS_DEBUG
+
+#include <pthread.h>
+
+#ifdef WIN32
+#include <io.h>   // stat for win32? 09/05/02 jhrg
+#endif
+
+#include <string>
+#include <vector>
+#include <map>
+
+#ifndef _http_cache_h
+#include "HTTPCache.h"
+#endif
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+#ifndef _internalerr_h
+#include "InternalErr.h"
+#endif
+
+#ifndef _util_h
+#include "util.h"
+#endif
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+#define LOCK(m) do { \
+	int code = pthread_mutex_lock((m)); \
+	if (code != 0) \
+		throw InternalErr(__FILE__, __LINE__, "Mutex lock: " + long_to_string(code)); \
+    } while(0);
+
+#define UNLOCK(m) do { \
+	int code = pthread_mutex_unlock((m)); \
+	if (code != 0) \
+		throw InternalErr(__FILE__, __LINE__, "Mutex unlock: " + long_to_string(code)); \
+    } while(0);
+
+#define TRYLOCK(m) pthread_mutex_trylock((m))
+#define INIT(m) pthread_mutex_init((m), 0)
+#define DESTROY(m) pthread_mutex_destroy((m))
+
+
+using namespace std;
+
+namespace libdap
+{
+
+int get_hash(const string &url);
+
+/** The table of entries in the client-side cache. This class maintains a table
+    of CacheEntries, where one instance of CacheEntry is made for
+    each item in the cache. When an item is accessed it is either
+    locked for reading or writing. When locked for reading the entry is 
+    recorded on a list of read-locked entries. The caller must explicitly 
+    free the entry for it to be removed from this list (which is the only
+    way it can be opened for writing). An entry can be accessed by multiple
+    readers but only one writer.
+    
+    @note The CacheEntry class used to contain a lock that was used to ensure
+    that the entry was locked during any changes to any of its fields. That
+    has been removed - its now the responsibility of the caller. This change
+    was made because it's likely the caller will need to lock all of the methods
+    that operate on a CacheEntry anyway, so the CacheEntry-specific lock was
+    redundant. */
+class HTTPCacheTable {
+public:
+    /** A struct used to store information about responses in the
+     cache's volatile memory.
+
+     About entry locking: An entry is locked using both a mutex and a
+     counter. The counter keeps track of how many clients are accessing a
+     given entry while the mutex provides a guarantee that updates to the
+     counter are MT-safe. In addition, the HTTPCacheTable object maintains a
+     map which binds the FILE* returned to a client with a given entry.
+     This way the client can tell the HTTPCacheTable object that it is done
+     with <code>FILE *response</code> and the class can arrange to update
+     the lock counter and mutex. */
+    struct CacheEntry {
+    private:
+	string url; // Location
+	int hash;
+	int hits; // Hit counts
+	string cachename;
+
+	string etag;
+	time_t lm; // Last modified
+	time_t expires;
+	time_t date; // From the response header.
+	time_t age;
+	time_t max_age; // From Cache-Control
+
+	unsigned long size; // Size of cached entity body
+	bool range; // Range is not currently supported. 10/02/02 jhrg
+
+	time_t freshness_lifetime;
+	time_t response_time;
+	time_t corrected_initial_age;
+
+	bool must_revalidate;
+	bool no_cache; // This field is not saved in the index.
+
+	int readers;
+	pthread_mutex_t d_response_lock; // set if being read
+	pthread_mutex_t d_response_write_lock; // set if being written
+
+	// Allow HTTPCacheTable methods access and the test class, too
+	friend class HTTPCacheTable;
+	friend class HTTPCacheTest;
+
+	// Allow access by the functors used in HTTPCacheTable
+	friend class DeleteCacheEntry;
+	friend class WriteOneCacheEntry;
+	friend class DeleteExpired;
+	friend class DeleteByHits;
+	friend class DeleteBySize;
+
+    public:
+	string get_cachename()
+	{
+	    return cachename;
+	}
+	string get_etag()
+	{
+	    return etag;
+	}
+	time_t get_lm()
+	{
+	    return lm;
+	}
+	time_t get_expires()
+	{
+	    return expires;
+	}
+	time_t get_max_age()
+	{
+	    return max_age;
+	}
+	void set_size(unsigned long sz)
+	{
+	    size = sz;
+	}
+	time_t get_freshness_lifetime()
+	{
+	    return freshness_lifetime;
+	}
+	time_t get_response_time()
+	{
+	    return response_time;
+	}
+	time_t get_corrected_initial_age()
+	{
+	    return corrected_initial_age;
+	}
+	bool get_must_revalidate()
+	{
+	    return must_revalidate;
+	}
+	void set_no_cache(bool state)
+	{
+	    no_cache = state;
+	}
+	bool is_no_cache()
+	{
+	    return no_cache;
+	}
+
+	void lock_read_response()
+	{
+	    DBG(cerr << "Try locking read response... (" << hex << &d_response_lock << dec << ") ");
+	    int status = TRYLOCK(&d_response_lock);
+	    if (status != 0 /*&& status == EBUSY*/) {
+		// If locked, wait for any writers
+		LOCK(&d_response_write_lock);
+		UNLOCK(&d_response_write_lock);
+	    };
+	    DBGN(cerr << "Done" << endl);
+	    readers++; // REcord number of readers
+	}
+
+	void unlock_read_response()
+	{
+	    readers--;
+	    if (readers == 0) {
+		DBG(cerr << "Unlocking read response... (" << hex << &d_response_lock << dec << ") ");
+		UNLOCK(&d_response_lock);
+		DBGN(cerr << "Done" << endl);
+	    }
+	}
+
+	void lock_write_response()
+	{
+	    DBG(cerr << "locking write response... (" << hex << &d_response_lock << dec << ") ");
+	    LOCK(&d_response_lock);
+	    LOCK(&d_response_write_lock);
+	    DBGN(cerr << "Done" << endl);
+	}
+
+	void unlock_write_response()
+	{
+	    DBG(cerr << "Unlocking write response... (" << hex << &d_response_lock << dec << ") ");
+	    UNLOCK(&d_response_write_lock);
+	    UNLOCK(&d_response_lock);
+	    DBGN(cerr << "Done" << endl);
+	}
+
+	CacheEntry() :
+	    url(""), hash(-1), hits(0), cachename(""), etag(""), lm(-1), expires(-1), date(-1), age(-1), max_age(-1),
+		    size(0), range(false), freshness_lifetime(0), response_time(0), corrected_initial_age(0),
+		    must_revalidate(false), no_cache(false), readers(0)
+	{
+	    INIT(&d_response_lock);
+	    INIT(&d_response_write_lock);
+	}
+	CacheEntry(const string &u) :
+	    url(u), hash(-1), hits(0), cachename(""), etag(""), lm(-1), expires(-1), date(-1), age(-1), max_age(-1),
+		    size(0), range(false), freshness_lifetime(0), response_time(0), corrected_initial_age(0),
+		    must_revalidate(false), no_cache(false), readers(0)
+	{
+	    INIT(&d_response_lock);
+	    INIT(&d_response_write_lock);
+	    hash = get_hash(url);
+	}
+    };
+
+    // Typedefs for CacheTable. A CacheTable is a vector of vectors of
+    // CacheEntries. The outer vector is accessed using the hash value.
+    // Entries with matching hashes occupy successive positions in the inner
+    // vector (that's how hash collisions are resolved). Search the inner
+    // vector for a specific match.
+    typedef vector<CacheEntry *> CacheEntries;
+    typedef CacheEntries::iterator CacheEntriesIter;
+
+    typedef CacheEntries **CacheTable;// Array of pointers to CacheEntries
+
+    friend class HTTPCacheTest;
+
+private:
+    CacheTable d_cache_table;
+
+    string d_cache_root;
+    unsigned int d_block_size; // File block size.
+    unsigned long d_current_size;
+
+    string d_cache_index;
+    int d_new_entries;
+    
+    map<FILE *, HTTPCacheTable::CacheEntry *> d_locked_entries;
+    
+	// Make these private to prevent use
+    HTTPCacheTable(const HTTPCacheTable &)
+    {
+	throw InternalErr(__FILE__, __LINE__, "unimplemented");
+    }
+
+    HTTPCacheTable &operator=(const HTTPCacheTable &)
+    {
+	throw InternalErr(__FILE__, __LINE__, "unimplemented");
+    }
+
+    HTTPCacheTable()
+    {
+	throw InternalErr(__FILE__, __LINE__, "unimplemented");
+    }
+
+    CacheTable &get_cache_table()
+    {
+	return d_cache_table;
+    }
+    CacheEntry *get_locked_entry_from_cache_table(int hash, const string &url); /*const*/
+
+public:
+    HTTPCacheTable(const string &cache_root, int block_size);
+    ~HTTPCacheTable();
+
+    //@{ @name Accessors/Mutators
+    unsigned long get_current_size() const
+    {
+	return d_current_size;
+    }
+    void set_current_size(unsigned long sz)
+    {
+	d_current_size = sz;
+    }
+
+    unsigned int get_block_size() const
+    {
+	return d_block_size;
+    }
+    void set_block_size(unsigned int sz)
+    {
+	d_block_size = sz;
+    }
+
+    int get_new_entries() const
+    {
+	return d_new_entries;
+    }
+    void increment_new_entries()
+    {
+	++d_new_entries;
+    }
+
+    string get_cache_root()
+    {
+	return d_cache_root;
+    }
+    void set_cache_root(const string &cr)
+    {
+	d_cache_root = cr;
+    }
+    //@}
+
+    void delete_expired_entries(time_t time = 0);
+    void delete_by_hits(int hits);
+    void delete_by_size(unsigned int size);
+    void delete_all_entries();
+
+    bool cache_index_delete();
+    bool cache_index_read();
+    CacheEntry *cache_index_parse_line(const char *line);
+    void cache_index_write();
+
+    string create_hash_directory(int hash);
+    void create_location(CacheEntry *entry);
+
+    void add_entry_to_cache_table(CacheEntry *entry);
+    void remove_cache_entry(HTTPCacheTable::CacheEntry *entry);
+
+    void remove_entry_from_cache_table(const string &url);
+    CacheEntry *get_locked_entry_from_cache_table(const string &url);
+    CacheEntry *get_write_locked_entry_from_cache_table(const string &url);
+
+    void calculate_time(HTTPCacheTable::CacheEntry *entry, int default_expiration, time_t request_time);
+    void parse_headers(HTTPCacheTable::CacheEntry *entry, unsigned long max_entry_size, const vector<string> &headers);
+
+    // These should move back to HTTPCache
+    void bind_entry_to_data(CacheEntry *entry, FILE *body);
+    void uncouple_entry_from_data(FILE *body);
+    bool is_locked_read_responses();
+};
+
+} // namespace libdap
+#endif
diff --git a/HTTPConnect.cc b/HTTPConnect.cc
new file mode 100644
index 0000000..19be390
--- /dev/null
+++ b/HTTPConnect.cc
@@ -0,0 +1,1008 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    { "$Id: HTTPConnect.cc 24380 2011-03-28 21:47:15Z jimg $"
+    };
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <sys/stat.h>
+
+#ifdef WIN32
+#include <io.h>
+#endif
+
+#include <string>
+#include <vector>
+#include <functional>
+#include <algorithm>
+#include <sstream>
+#include <iterator>
+#include <cstdlib>
+#include <cstring>
+
+// #define DODS_DEBUG
+//#define DODS_DEBUG2
+//#define HTTP_TRACE
+//#define DODS_DEBUG
+
+#undef USE_GETENV
+
+
+#include "debug.h"
+#include "mime_util.h"
+#include "GNURegex.h"
+#include "HTTPCache.h"
+#include "HTTPConnect.h"
+#include "RCReader.h"
+#include "HTTPResponse.h"
+#include "HTTPCacheResponse.h"
+
+using namespace std;
+
+namespace libdap {
+
+// These global variables are not MT-Safe, but I'm leaving them as is because
+// they are used only for debugging (set them in a debugger like gdb or ddd).
+// They are not static because I think that many debuggers cannot access
+// static variables. 08/07/02 jhrg
+
+// Set this to 1 to turn on libcurl's verbose mode (for debugging).
+int www_trace = 0;
+
+// Keep the temporary files; useful for debugging.
+int dods_keep_temps = 0;
+
+#define CLIENT_ERR_MIN 400
+#define CLIENT_ERR_MAX 417
+static const char *http_client_errors[CLIENT_ERR_MAX - CLIENT_ERR_MIN +1] =
+    {
+        "Bad Request:",
+        "Unauthorized: Contact the server administrator.",
+        "Payment Required.",
+        "Forbidden: Contact the server administrator.",
+        "Not Found: The data source or server could not be found.\n\
+        Often this means that the OPeNDAP server is missing or needs attention;\n\
+        Please contact the server administrator.",
+        "Method Not Allowed.",
+        "Not Acceptable.",
+        "Proxy Authentication Required.",
+        "Request Time-out.",
+        "Conflict.",
+        "Gone:.",
+        "Length Required.",
+        "Precondition Failed.",
+        "Request Entity Too Large.",
+        "Request URI Too Large.",
+        "Unsupported Media Type.",
+        "Requested Range Not Satisfiable.",
+        "Expectation Failed."
+    };
+
+#define SERVER_ERR_MIN 500
+#define SERVER_ERR_MAX 505
+static const char *http_server_errors[SERVER_ERR_MAX - SERVER_ERR_MIN + 1] =
+    {
+        "Internal Server Error.",
+        "Not Implemented.",
+        "Bad Gateway.",
+        "Service Unavailable.",
+        "Gateway Time-out.",
+        "HTTP Version Not Supported."
+    };
+
+/** This function translates the HTTP status codes into error messages. It
+    works for those code greater than or equal to 400. */
+static string
+http_status_to_string(int status)
+{
+    if (status >= CLIENT_ERR_MIN && status <= CLIENT_ERR_MAX)
+        return string(http_client_errors[status - CLIENT_ERR_MIN]);
+    else if (status >= SERVER_ERR_MIN && status <= SERVER_ERR_MAX)
+        return string(http_server_errors[status - SERVER_ERR_MIN]);
+    else
+        return string("Unknown Error: This indicates a problem with libdap++.\nPlease report this to support at opendap.org.");
+}
+
+/** Functor to parse the headers in the d_headers field. After the headers
+    have been read off the wire and written into the d_headers field, scan
+    them and set special fields for certain headers special to the DAP. */
+
+class ParseHeader : public unary_function<const string &, void>
+{
+    ObjectType type;  // What type of object is in the stream?
+    string server;  // Server's version string.
+    string protocol;            // Server's protocol version.
+    string location;            // Url returned by server
+
+public:
+    ParseHeader() : type(unknown_type), server("dods/0.0"), protocol("2.0")
+    { }
+
+    void operator()(const string &line)
+    {
+        string name, value;
+        parse_mime_header(line, name, value);
+        if (name == "content-description") {
+            DBG2(cerr << name << ": " << value << endl);
+            type = get_description_type(value);
+        }
+        // The second test (== "dods/0.0") tests if xopendap-server has already
+        // been seen. If so, use that header in preference to the old
+        // XDODS-Server header. jhrg 2/7/06
+        else if (name == "xdods-server" && server == "dods/0.0") {
+            DBG2(cerr << name << ": " << value << endl);
+            server = value;
+        }
+        else if (name == "xopendap-server") {
+            DBG2(cerr << name << ": " << value << endl);
+            server = value;
+        }
+        else if (name == "xdap") {
+            DBG2(cerr << name << ": " << value << endl);
+            protocol = value;
+        }
+        else if (server == "dods/0.0" && name == "server") {
+            DBG2(cerr << name << ": " << value << endl);
+            server = value;
+        }
+       	else if (name == "location") {
+       	    DBG2(cerr << name << ": " << value << endl);
+       	    location = value;
+        }
+        else if (type == unknown_type && name == "content-type"
+                 && line.find("text/html") != string::npos) {
+            DBG2(cerr << name << ": text/html..." << endl);
+            type = web_error;
+        }
+    }
+
+    ObjectType get_object_type()
+    {
+        return type;
+    }
+
+    string get_server()
+    {
+        return server;
+    }
+
+    string get_protocol()
+    {
+        return protocol;
+    }
+
+    string get_location() {
+	   return location;
+    }
+};
+
+/** A libcurl callback function used to read response headers. Read headers,
+    line by line, from ptr. The fourth param is really supposed to be a FILE
+    *, but libcurl just holds the pointer and passes it to this function
+    without using it itself. I use that to pass in a pointer to the
+    HTTPConnect that initiated the HTTP request so that there's some place to
+    dump the headers. Note that this function just saves the headers in a
+    vector of strings. Later on the code (see fetch_url()) parses the headers
+    special to the DAP.
+
+    @param ptr A pointer to one line of character data; one header.
+    @param size Size of each character (nominally one byte).
+    @param nmemb Number of bytes.
+    @param resp_hdrs A pointer to a vector<string>. Set in read_url.
+    @return The number of bytes processed. Must be equal to size * nmemb or
+    libcurl will report an error. */
+
+static size_t
+save_raw_http_headers(void *ptr, size_t size, size_t nmemb, void *resp_hdrs)
+{
+    DBG2(cerr << "Inside the header parser." << endl);
+    vector<string> *hdrs = static_cast<vector<string> * >(resp_hdrs);
+
+    // Grab the header, minus the trailing newline. Or \r\n pair.
+    string complete_line;
+    if (nmemb > 1 && *(static_cast<char*>(ptr) + size * (nmemb - 2)) == '\r')
+        complete_line.assign(static_cast<char *>(ptr), size * (nmemb - 2));
+    else
+        complete_line.assign(static_cast<char *>(ptr), size * (nmemb - 1));
+
+    // Store all non-empty headers that are not HTTP status codes
+    if (complete_line != "" && complete_line.find("HTTP") == string::npos) {
+        DBG(cerr << "Header line: " << complete_line << endl);
+        hdrs->push_back(complete_line);
+    }
+
+    return size * nmemb;
+}
+
+/** A libcurl callback for debugging protocol issues. */
+static int
+curl_debug(CURL *, curl_infotype info, char *msg, size_t size, void  *)
+{
+    string message(msg, size);
+
+    switch (info) {
+    case CURLINFO_TEXT:
+        cerr << "Text: " << message; break;
+    case CURLINFO_HEADER_IN:
+        cerr << "Header in: " << message; break;
+    case CURLINFO_HEADER_OUT:
+        cerr << "Header out: " << message; break;
+    case CURLINFO_DATA_IN:
+        cerr << "Data in: " << message; break;
+    case CURLINFO_DATA_OUT:
+        cerr << "Data out: " << message; break;
+    case CURLINFO_END:
+        cerr << "End: " << message; break;
+#ifdef CURLINFO_SSL_DATA_IN
+    case CURLINFO_SSL_DATA_IN:
+        cerr << "SSL Data in: " << message; break;
+#endif
+#ifdef CURLINFO_SSL_DATA_OUT
+    case CURLINFO_SSL_DATA_OUT:
+        cerr << "SSL Data out: " << message; break;
+#endif
+    default:
+        cerr << "Curl info: " << message; break;
+    }
+    return 0;
+}
+
+/** Initialize libcurl. Create a libcurl handle that can be used for all of
+    the HTTP requests made through this instance. */
+
+void
+HTTPConnect::www_lib_init()
+{
+    d_curl = curl_easy_init();
+    if (!d_curl)
+        throw InternalErr(__FILE__, __LINE__, "Could not initialize libcurl.");
+
+    // Now set options that will remain constant for the duration of this
+    // CURL object.
+
+    // Set the proxy host.
+    if (!d_rcr->get_proxy_server_host().empty()) {
+        DBG(cerr << "Setting up a proxy server." << endl);
+        DBG(cerr << "Proxy host: " << d_rcr->get_proxy_server_host()
+            << endl);
+        DBG(cerr << "Proxy port: " << d_rcr->get_proxy_server_port()
+            << endl);
+        DBG(cerr << "Proxy pwd : " << d_rcr->get_proxy_server_userpw()
+            << endl);
+        curl_easy_setopt(d_curl, CURLOPT_PROXY,
+                         d_rcr->get_proxy_server_host().c_str());
+        curl_easy_setopt(d_curl, CURLOPT_PROXYPORT,
+                         d_rcr->get_proxy_server_port());
+
+	// As of 4/21/08 only NTLM, Digest and Basic work.
+#ifdef CURLOPT_PROXYAUTH
+        curl_easy_setopt(d_curl, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
+#endif
+
+        // Password might not be required. 06/21/04 jhrg
+        if (!d_rcr->get_proxy_server_userpw().empty())
+            curl_easy_setopt(d_curl, CURLOPT_PROXYUSERPWD,
+                             d_rcr->get_proxy_server_userpw().c_str());
+    }
+
+    curl_easy_setopt(d_curl, CURLOPT_ERRORBUFFER, d_error_buffer);
+    // We have to set FailOnError to false for any of the non-Basic
+    // authentication schemes to work. 07/28/03 jhrg
+    curl_easy_setopt(d_curl, CURLOPT_FAILONERROR, 0);
+
+    // This means libcurl will use Basic, Digest, GSS Negotiate, or NTLM,
+    // choosing the the 'safest' one supported by the server.
+    // This requires curl 7.10.6 which is still in pre-release. 07/25/03 jhrg
+    curl_easy_setopt(d_curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_ANY);
+
+    curl_easy_setopt(d_curl, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(d_curl, CURLOPT_NOSIGNAL, 1);
+    curl_easy_setopt(d_curl, CURLOPT_HEADERFUNCTION, save_raw_http_headers);
+    // In read_url a call to CURLOPT_WRITEHEADER is used to set the fourth
+    // param of save_raw_http_headers to a vector<string> object.
+
+    // Follow 302 (redirect) responses
+    curl_easy_setopt(d_curl, CURLOPT_FOLLOWLOCATION, 1);
+    curl_easy_setopt(d_curl, CURLOPT_MAXREDIRS, 5);
+
+    // If the user turns off SSL validation...
+    if (!d_rcr->get_validate_ssl() == 0) {
+        curl_easy_setopt(d_curl, CURLOPT_SSL_VERIFYPEER, 0);
+        curl_easy_setopt(d_curl, CURLOPT_SSL_VERIFYHOST, 0);
+    }
+
+    // Look to see if cookies are turned on in the .dodsrc file. If so,
+    // activate here. We honor 'session cookies' (cookies without an
+    // expiration date) here so that session-base SSO systems will work as
+    // expected.
+    if (!d_cookie_jar.empty()) {
+	DBG(cerr << "Setting the cookie jar to: " << d_cookie_jar << endl);
+        curl_easy_setopt(d_curl, CURLOPT_COOKIEJAR, d_cookie_jar.c_str());
+        curl_easy_setopt(d_curl, CURLOPT_COOKIESESSION, 1);
+    }
+
+    if (www_trace) {
+        cerr << "Curl version: " << curl_version() << endl;
+        curl_easy_setopt(d_curl, CURLOPT_VERBOSE, 1);
+        curl_easy_setopt(d_curl, CURLOPT_DEBUGFUNCTION, curl_debug);
+    }
+}
+
+/** Functor to add a single string to a curl_slist. This is used to transfer
+    a list of headers from a vector<string> object to a curl_slist. */
+
+class BuildHeaders : public unary_function<const string &, void>
+{
+    struct curl_slist *d_cl;
+
+public:
+    BuildHeaders() : d_cl(0)
+    {}
+
+    void operator()(const string &header)
+    {
+        DBG(cerr << "Adding '" << header.c_str() << "' to the header list."
+            << endl);
+        d_cl = curl_slist_append(d_cl, header.c_str());
+    }
+
+    struct curl_slist *get_headers()
+    {
+        return d_cl;
+    }
+};
+
+/** Use libcurl to dereference a URL. Read the information referenced by \c
+    url into the file pointed to by \c stream.
+
+    @param url The URL to dereference.
+    @param stream The destination for the data; the caller can assume that
+    the body of the response can be found by reading from this pointer. A
+    value/result parameter
+    @param resp_hdrs Value/result parameter for the HTTP Response Headers.
+    @param headers A pointer to a vector of HTTP request headers. Default is
+    null. These headers will be appended to the list of default headers.
+    @return The HTTP status code.
+    @exception Error Thrown if libcurl encounters a problem; the libcurl
+    error message is stuffed into the Error object. */
+
+long
+HTTPConnect::read_url(const string &url, FILE *stream,
+                      vector<string> *resp_hdrs,
+                      const vector<string> *headers)
+{
+    curl_easy_setopt(d_curl, CURLOPT_URL, url.c_str());
+
+#ifdef WIN32
+    //  See the curl documentation for CURLOPT_FILE (aka CURLOPT_WRITEDATA)
+    //  and the CURLOPT_WRITEFUNCTION option.  Quote: "If you are using libcurl as
+    //  a win32 DLL, you MUST use the CURLOPT_WRITEFUNCTION option if you set the
+    //  CURLOPT_WRITEDATA option or you will experience crashes".  At the root of
+    //  this issue is that one should not pass a FILE * to a windows DLL.  Close
+    //  inspection of libcurl yields that their default write function when using
+    //  the CURLOPT_WRITEDATA is just "fwrite".
+    curl_easy_setopt(d_curl, CURLOPT_FILE, stream);
+    curl_easy_setopt(d_curl, CURLOPT_WRITEFUNCTION, &fwrite);
+#else
+    curl_easy_setopt(d_curl, CURLOPT_FILE, stream);
+#endif
+
+    DBG(copy(d_request_headers.begin(), d_request_headers.end(),
+             ostream_iterator<string>(cerr, "\n")));
+
+    BuildHeaders req_hdrs;
+    req_hdrs = for_each(d_request_headers.begin(), d_request_headers.end(),
+                        req_hdrs);
+    if (headers)
+        req_hdrs = for_each(headers->begin(), headers->end(), req_hdrs);
+    curl_easy_setopt(d_curl, CURLOPT_HTTPHEADER, req_hdrs.get_headers());
+
+    // Turn off the proxy for this URL?
+    bool temporary_proxy = false;
+    if ((temporary_proxy = url_uses_no_proxy_for(url))) {
+        DBG(cerr << "Suppress proxy for url: " << url << endl);
+        curl_easy_setopt(d_curl, CURLOPT_PROXY, 0);
+    }
+
+    string::size_type at_sign = url.find('@');
+    // Assume username:password present *and* assume it's an HTTP URL; it *is*
+    // HTTPConnect, after all. 7 is position after "http://"; the second arg
+    // to substr() is the sub string length.
+    if (at_sign != url.npos)
+        d_upstring = url.substr(7, at_sign - 7);
+
+    if (!d_upstring.empty())
+        curl_easy_setopt(d_curl, CURLOPT_USERPWD, d_upstring.c_str());
+
+    // Pass save_raw_http_headers() a pointer to the vector<string> where the
+    // response headers may be stored. Callers can use the resp_hdrs
+    // value/result parameter to get the raw response header information .
+    curl_easy_setopt(d_curl, CURLOPT_WRITEHEADER, resp_hdrs);
+
+    CURLcode res = curl_easy_perform(d_curl);
+
+    // Free the header list and null the value in d_curl.
+    curl_slist_free_all(req_hdrs.get_headers());
+    curl_easy_setopt(d_curl, CURLOPT_HTTPHEADER, 0);
+
+    // Reset the proxy?
+    if (temporary_proxy && !d_rcr->get_proxy_server_host().empty())
+        curl_easy_setopt(d_curl, CURLOPT_PROXY,
+                         d_rcr->get_proxy_server_host().c_str());
+
+    if (res != 0)
+        throw Error(d_error_buffer);
+
+    long status;
+    res = curl_easy_getinfo(d_curl, CURLINFO_HTTP_CODE, &status);
+    if (res != 0)
+        throw Error(d_error_buffer);
+
+    return status;
+}
+
+/** If the .dodsrc file gives a value for PROXY_FOR, return true if the
+    current URL matches the regular expression. */
+
+bool
+HTTPConnect::url_uses_proxy_for(const string &url) throw()
+{
+    if (d_rcr->is_proxy_for_used()) {
+        Regex host_regex(d_rcr->get_proxy_for_regexp().c_str());
+        int index = 0, matchlen;
+        return host_regex.search(url.c_str(), url.size(), matchlen, index) != -1;
+    }
+
+    return false;
+}
+
+/** If the NO_PROXY option is used in the dodsrc file, does this URL match
+    the no proxy URL regex? */
+
+bool
+HTTPConnect::url_uses_no_proxy_for(const string &url) throw()
+{
+    return d_rcr->is_no_proxy_for_used()
+           && url.find(d_rcr->get_no_proxy_for_host()) != string::npos;
+}
+
+// Public methods. Mostly...
+
+/** Build a virtual connection to a remote data source that will be
+    accessed using HTTP.
+
+    @param rcr A pointer to the RCReader object which holds configuration
+    file information to be used by this virtual connection. */
+
+HTTPConnect::HTTPConnect(RCReader *rcr) : d_username(""), d_password(""),
+  					  d_cookie_jar(""),
+					  d_dap_client_protocol_major(2),
+					  d_dap_client_protocol_minor(0)
+
+{
+    d_accept_deflate = rcr->get_deflate();
+    d_rcr = rcr;
+
+    // Load in the default headers to send with a request. The empty Pragma
+    // headers overrides libcurl's default Pragma: no-cache header (which
+    // will disable caching by Squid, et c.). The User-Agent header helps
+    // make server logs more readable. 05/05/03 jhrg
+    d_request_headers.push_back(string("Pragma:"));
+    string user_agent = string("User-Agent: ") + string(CNAME)
+                        + string("/") + string(CVER);
+    d_request_headers.push_back(user_agent);
+    if (d_accept_deflate)
+        d_request_headers.push_back(string("Accept-Encoding: deflate, gzip, compress"));
+
+    // HTTPCache::instance returns a valid ptr or 0.
+    if (d_rcr->get_use_cache())
+        d_http_cache = HTTPCache::instance(d_rcr->get_dods_cache_root(),
+                                           true);
+    else
+        d_http_cache = 0;
+
+    DBG2(cerr << "Cache object created (" << hex << d_http_cache << dec
+         << ")" << endl);
+
+    if (d_http_cache) {
+        d_http_cache->set_cache_enabled(d_rcr->get_use_cache());
+        d_http_cache->set_expire_ignored(d_rcr->get_ignore_expires() != 0);
+        d_http_cache->set_max_size(d_rcr->get_max_cache_size());
+        d_http_cache->set_max_entry_size(d_rcr->get_max_cached_obj());
+        d_http_cache->set_default_expiration(d_rcr->get_default_expires());
+        d_http_cache->set_always_validate(d_rcr->get_always_validate() != 0);
+    }
+
+    d_cookie_jar = rcr->get_cookie_jar();
+
+    www_lib_init();  // This may throw either Error or InternalErr
+}
+
+HTTPConnect::~HTTPConnect()
+{
+    DBG2(cerr << "Entering the HTTPConnect dtor" << endl);
+
+    curl_easy_cleanup(d_curl);
+
+    DBG2(cerr << "Leaving the HTTPConnect dtor" << endl);
+}
+
+/** Dereference a URL. This method dereferences a URL and stores the result
+    (i.e., it formulates an HTTP request and processes the HTTP server's
+    response). After this method is successfully called, the value of
+    is_response_present() will be true and the methods
+    get_response_headers(), type() and server_version() may be called.
+
+    @param url The URL to dereference.
+    @return A pointer to the stream.
+    @exception Error Thrown if the URL could not be dereferenced.
+    @exception InternalErr Thrown if a temporary file to hold the response
+    could not be opened. */
+
+HTTPResponse *
+HTTPConnect::fetch_url(const string &url)
+{
+#ifdef HTTP_TRACE
+    cout << "GET " << url << " HTTP/1.0" << endl;
+#endif
+
+    HTTPResponse *stream;
+
+    if (d_http_cache && d_http_cache->is_cache_enabled()) {
+        stream = caching_fetch_url(url);
+    }
+    else {
+        stream = plain_fetch_url(url);
+    }
+
+#ifdef HTTP_TRACE
+    stringstream ss;
+    ss << "HTTP/1.0 " << stream->get_status() << " -" << endl;
+    for (size_t i = 0; i < stream->get_headers()->size(); i++) {
+	ss << stream->get_headers()->at(i) << endl;
+    }
+    cout << ss.str();
+#endif
+
+    ParseHeader parser;
+
+    parser = for_each(stream->get_headers()->begin(),
+                      stream->get_headers()->end(), ParseHeader());
+
+#ifdef HTTP_TRACE
+    cout << endl << endl;
+#endif
+
+    // handle redirection case (2007-04-27, gaffigan at sfos.uaf.edu)
+    if (parser.get_location() != "" &&
+	    url.substr(0,url.find("?",0)).compare(parser.get_location().substr(0,url.find("?",0))) != 0) {
+	delete stream;
+        return fetch_url(parser.get_location());
+    }
+
+    stream->set_type(parser.get_object_type());
+    stream->set_version(parser.get_server());
+    stream->set_protocol(parser.get_protocol());
+
+    return stream;
+}
+
+// Look around for a reasonable place to put a temporary file. Check first
+// the value of the TMPDIR env var. If that does not yeild a path that's
+// writable (as defined by access(..., W_OK|R_OK)) then look at P_tmpdir (as
+// defined in stdio.h. If both come up empty, then use `./'.
+
+// Change this to a version that either returns a string or an open file
+// descriptor. Use information from https://buildsecurityin.us-cert.gov/
+// (see open()) to make it more secure. Ideal solution: get deserialize()
+// methods to read from a stream returned by libcurl, not from a temporary
+// file. 9/21/07 jhrg Updated to use strings, so other misc changes. 3/22/11
+static string
+get_tempfile_template(const string &file_template)
+{
+    string c;
+
+    // Windows has one idea of the standard name(s) for a temporary files dir
+#ifdef WIN32
+    // white list for a WIN32 directory
+    Regex directory("[-a-zA-Z0-9_:\\]*");
+
+    // If we're OK to use getenv(), try it.
+#ifdef USE_GETENV
+    c = getenv("TEMP");
+    if (c && directory.match(c.c_str(), c.length()) && (access(c.c_str(), 6) == 0))
+	goto valid_temp_directory;
+
+    c= getenv("TMP");
+    if (c && directory.match(c.c_str(), c.length()) && (access(c.c_str(), 6) == 0))
+	goto valid_temp_directory;
+#endif // USE_GETENV
+
+    // The windows default
+    c = "c:\tmp";
+    if (c && directory.match(c.c_str(), c.length()) && (access(c.c_str(), 6) == 0))
+	goto valid_temp_directory;
+
+#else	// Unix/Linux/OSX has another...
+    // white list for a directory
+    Regex directory("[-a-zA-Z0-9_/]*");
+#ifdef USE_GETENV
+    c = getenv("TMPDIR");
+    if (directory.match(c.c_str(), c.length()) && (access(c.c_str(), W_OK | R_OK) == 0))
+	goto valid_temp_directory;
+#endif // USE_GETENV
+
+    // Unix defines this sometimes - if present, use it.
+#ifdef P_tmpdir
+    if (access(P_tmpdir, W_OK | R_OK) == 0) {
+	c = P_tmpdir;
+	goto valid_temp_directory;
+    }
+#endif
+
+    // The Unix default
+    c = "/tmp";
+    if (directory.match(c.c_str(), c.length()) && (access(c.c_str(), W_OK | R_OK) == 0))
+	goto valid_temp_directory;
+
+#endif  // WIN32
+
+    // If we found nothing useful, use the current directory
+    c = ".";
+
+valid_temp_directory:
+
+#ifdef WIN32
+    c += "\\" + file_template;
+#else
+    c += "/" + file_template;
+#endif
+
+    return c;
+}
+
+/** Open a temporary file and return its name. This method opens a temporary
+    file using get_tempfile_template(). The FILE* \c stream is opened for
+    both reads and writes; if it already exists (highly unlikely), it is
+    truncated. If used on Unix, it's the callers responsibility to unlink the
+    named file so that when all descriptors to it are closed, it will be
+    deleted. On Win32 platforms, this method pushes the name of the temporary
+    file onto a vector which is used during object destruction to delete all
+    the temporary files.
+
+    @note Delete the returned char* using delete[].
+
+    A private method.
+
+    @param stream A value-result parameter; the open file descriptor is
+    returned via this parameter.
+    @return The name of the temporary file.
+    @exception InternalErr thrown if the FILE* could not be opened. */
+
+string
+get_temp_file(FILE *&stream) throw(InternalErr)
+{
+    string dods_temp = get_tempfile_template((string)"dodsXXXXXX");
+
+    vector<char> pathname(dods_temp.length() + 1);
+
+    strncpy(&pathname[0], dods_temp.c_str(), dods_temp.length());
+
+    DBG(cerr << "pathanme: " << &pathname[0] << " (" << dods_temp.length() + 1 << ")" << endl);
+
+    // Open truncated for update. NB: mkstemp() returns a file descriptor.
+#if defined(WIN32) || defined(TEST_WIN32_TEMPS)
+    stream = fopen(_mktemp(&pathname[0]), "w+b");
+#else
+    // Make sure that temp files are accessible only by the owner.
+    umask(077);
+    stream = fdopen(mkstemp(&pathname[0]), "w+");
+#endif
+
+    if (!stream) {
+	throw InternalErr(__FILE__, __LINE__,
+		"Failed to open a temporary file for the data values ("
+		+ dods_temp + ")");
+    }
+
+    dods_temp = &pathname[0];
+    return dods_temp;
+}
+
+/** Close the temporary file opened for read_url(). */
+void
+close_temp(FILE *s, const string &name)
+{
+    int res = fclose(s);
+    if (res)
+	throw InternalErr(__FILE__, __LINE__, "!FAIL! " + long_to_string(res));
+
+    res = unlink(name.c_str());
+    if (res != 0)
+    	throw InternalErr(__FILE__, __LINE__, "!FAIL! " + long_to_string(res));
+}
+
+/** Dereference a URL. This method looks first in the HTTP cache to see if a
+    cached response may be used. It may get the response from the cache, it
+    may validate a response in the cache and/or update the response from the
+    cache or it may get a new response from the network. In any of those
+    cases, the information returned by dereferencing the URL will be stored
+    in the cache.
+
+    Return a Response pointer to fetch_url() which, in turn, uses
+    ParseHeaders to read stuff from d_headers and fills in the Response
+    version and type fields. Thus this method and plain_fetch_url() only have
+    to get the stream pointer set, the resources to release and d_headers.
+
+    A private method.
+
+    @note This method assumes that d_http_cache is not null!
+    @param url The URL to dereference.
+    @return A pointer to the open stream.
+    @exception Error Thrown if the URL could not be dereferenced.
+    @exception InternalErr Thrown if a temporary file to hold the response
+    could not be opened. */
+
+HTTPResponse *
+HTTPConnect::caching_fetch_url(const string &url)
+{
+    DBG(cerr << "Is this URL (" << url << ") in the cache?... ");
+
+    vector<string> *headers = new vector<string>;
+    string file_name;
+    FILE *s = d_http_cache->get_cached_response(url, *headers, file_name);
+    if (!s) {
+        // url not in cache; get it and cache it
+        DBGN(cerr << "no; getting response and caching." << endl);
+        delete headers; headers = 0;
+        time_t now = time(0);
+        HTTPResponse *rs = plain_fetch_url(url);
+        d_http_cache->cache_response(url, now, *(rs->get_headers()), rs->get_stream());
+
+        return rs;
+    }
+    else { // url in cache
+        DBGN(cerr << "yes... ");
+
+        if (d_http_cache->is_url_valid(url)) { // url in cache and valid
+            DBGN(cerr << "and it's valid; using cached response." << endl);
+            HTTPCacheResponse *crs = new HTTPCacheResponse(s, 200, headers, file_name, d_http_cache);
+            return crs;
+        }
+        else { // url in cache but not valid; validate
+            DBGN(cerr << "but it's not valid; validating... ");
+
+            d_http_cache->release_cached_response(s); // This closes 's'
+            headers->clear();
+            vector<string> cond_hdrs = d_http_cache->get_conditional_request_headers(url);
+            FILE *body = 0;
+            string dods_temp = get_temp_file(body);
+            time_t now = time(0); // When was the request made (now).
+            long http_status;
+
+            try {
+                http_status = read_url(url, body, /*resp_hdrs*/headers, &cond_hdrs);
+                rewind(body);
+            }
+            catch (Error &e) {
+                close_temp(body, dods_temp);
+                delete headers;
+                throw ;
+            }
+
+            switch (http_status) {
+                case 200: { // New headers and new body
+                    DBGN(cerr << "read a new response; caching." << endl);
+
+                    d_http_cache->cache_response(url, now, /* *resp_hdrs*/*headers, body);
+                    HTTPResponse *rs = new HTTPResponse(body, http_status, /*resp_hdrs*/headers, dods_temp);
+
+                    return rs;
+                }
+
+                case 304: { // Just new headers, use cached body
+                    DBGN(cerr << "cached response valid; updating." << endl);
+
+                    close_temp(body, dods_temp);
+                    d_http_cache->update_response(url, now, /* *resp_hdrs*/ *headers);
+                    string file_name;
+                    FILE *hs = d_http_cache->get_cached_response(url, *headers, file_name);
+                    HTTPCacheResponse *crs = new HTTPCacheResponse(hs, 304, headers, file_name, d_http_cache);
+                    return crs;
+                }
+
+                default: { // Oops.
+                    close_temp(body, dods_temp);
+                    if (http_status >= 400) {
+                	delete headers; headers = 0;
+                        string msg = "Error while reading the URL: ";
+                        msg += url;
+                        msg
+                        += ".\nThe OPeNDAP server returned the following message:\n";
+                        msg += http_status_to_string(http_status);
+                        throw Error(msg);
+                    }
+                    else {
+                	delete headers; headers = 0;
+                        throw InternalErr(__FILE__, __LINE__,
+                                "Bad response from the HTTP server: " + long_to_string(http_status));
+                    }
+                }
+            }
+        }
+    }
+
+    throw InternalErr(__FILE__, __LINE__, "Should never get here");
+}
+
+/** Dereference a URL and load its body into a temporary file. This
+    method ignores the HTTP cache.
+
+    A private method.
+
+    @param url The URL to dereference.
+    @return A pointer to the open stream.
+    @exception Error Thrown if the URL could not be dereferenced.
+    @exception InternalErr Thrown if a temporary file to hold the response
+    could not be opened. */
+
+HTTPResponse *
+HTTPConnect::plain_fetch_url(const string &url)
+{
+    DBG(cerr << "Getting URL: " << url << endl);
+    FILE *stream = 0;
+    string dods_temp = get_temp_file(stream);
+    vector<string> *resp_hdrs = new vector<string>;
+
+    int status = -1;
+    try {
+        status = read_url(url, stream, resp_hdrs); // Throws Error.
+        if (status >= 400) {
+        	delete resp_hdrs;
+            string msg = "Error while reading the URL: ";
+            msg += url;
+            msg += ".\nThe OPeNDAP server returned the following message:\n";
+            msg += http_status_to_string(status);
+            throw Error(msg);
+        }
+    }
+
+    catch (Error &e) {
+    	delete resp_hdrs;
+        close_temp(stream, dods_temp);
+        throw;
+    }
+
+    rewind(stream);
+
+    return new HTTPResponse(stream, status, resp_hdrs, dods_temp);
+}
+
+/** Set the <em>accept deflate</em> property. If true, the DAP client
+    announces to a server that it can accept responses compressed using the
+    \c deflate algorithm. This property is automatically set using a value
+    from the <code>.dodsrc</code> configuration file. This method provides a
+    way to override that behavior.
+
+    @note If the configuration file is not present or does not include a
+    value for this property, it is set to \c false.
+
+    @param deflate True sets the <em>accept deflate</em> property, False clears
+    it. */
+void
+HTTPConnect::set_accept_deflate(bool deflate)
+{
+    d_accept_deflate = deflate;
+
+    if (d_accept_deflate) {
+        if (find(d_request_headers.begin(), d_request_headers.end(),
+                 "Accept-Encoding: deflate, gzip, compress") == d_request_headers.end())
+            d_request_headers.push_back(string("Accept-Encoding: deflate, gzip, compress"));
+        DBG(copy(d_request_headers.begin(), d_request_headers.end(),
+                 ostream_iterator<string>(cerr, "\n")));
+    }
+    else {
+        vector<string>::iterator i;
+        i = remove_if(d_request_headers.begin(), d_request_headers.end(),
+                      bind2nd(equal_to<string>(),
+                              string("Accept-Encoding: deflate, gzip, compress")));
+        d_request_headers.erase(i, d_request_headers.end());
+    }
+}
+
+/** Look for a certain header */
+class HeaderMatch : public unary_function<const string &, bool> {
+    const string &d_header;
+    public:
+        HeaderMatch(const string &header) : d_header(header) {}
+        bool operator()(const string &arg) { return arg.find(d_header) == 0; }
+};
+
+/** Set the <em>xdap_accept</em> property/HTTP-header. This sets the value
+    of the DAP which the client advertises to servers that it understands.
+    The information (client protocol major and minor versions) are recorded
+    in the instance and the information is sent to servers using the
+    XDAP-Accept HTTP request header.
+
+    @param major The dap client major protocol version
+    @param minor The dap client minor protocol version */
+void
+HTTPConnect::set_xdap_protocol(int major, int minor)
+{
+    // Look for, and remove if one exists, an XDAP-Accept header
+    vector<string>::iterator i;
+    i = find_if(d_request_headers.begin(), d_request_headers.end(),
+                HeaderMatch("XDAP-Accept:"));
+    if (i != d_request_headers.end())
+        d_request_headers.erase(i);
+
+    // Record and add the new header value
+    d_dap_client_protocol_major = major;
+    d_dap_client_protocol_minor = minor;
+    ostringstream xdap_accept;
+    xdap_accept << "XDAP-Accept: " << major << "." << minor;
+
+    d_request_headers.push_back(xdap_accept.str());
+
+    DBG(copy(d_request_headers.begin(), d_request_headers.end(),
+             ostream_iterator<string>(cerr, "\n")));
+}
+
+/** Set the credentials for responding to challenges while dereferencing
+    URLs. Alternatively, these can be embedded in the URL. This method
+    provides a way for clients of HTTPConnect to get credentials from users
+    (say using a pop up dialog) and to not hack the URL to pass that
+    information to libcurl. Note that the 'credentials in the URL' scheme \e
+    is part of the URL standard.
+
+    This method does nothing if \c u, the username, is empty.
+
+    @param u The username.
+    @param p The password.
+    @exception InternalErr The credentials could not be registered with
+    libcurl.
+    @see extract_auth_info() */
+
+void
+HTTPConnect::set_credentials(const string &u, const string &p)
+{
+    if (u.empty())
+        return;
+
+    // Store the credentials locally.
+    d_username = u;
+    d_password = p;
+
+    d_upstring = u + ":" + p;
+}
+
+} // namespace libdap
diff --git a/HTTPConnect.h b/HTTPConnect.h
new file mode 100644
index 0000000..01e7692
--- /dev/null
+++ b/HTTPConnect.h
@@ -0,0 +1,175 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _httpconnect_h
+#define _httpconnect_h
+
+
+#include <string>
+
+#include <curl/curl.h>
+#include <curl/types.h>
+#include <curl/easy.h>
+
+#ifndef _rc_reader_h_
+#include "RCReader.h"
+#endif
+
+#ifndef _object_type_h
+#include "ObjectType.h"
+#endif
+
+#ifndef _http_cache_h
+#include "HTTPCache.h"
+#endif
+
+#ifndef http_response_h
+#include "HTTPResponse.h"
+#endif
+
+#ifndef _util_h
+#include "util.h"
+#endif
+
+using std::string;
+using std::vector;
+
+namespace libdap
+{
+
+extern int www_trace;
+extern int dods_keep_temps;
+
+/** Use the CURL library to dereference a HTTP URL. Scan the response for
+    headers used by the DAP 2.0 and extract their values. The body of the
+    response is made available by a FILE pointer.
+
+    @todo Change the way this class returns information so that the headers
+    and the stream (aka FILE pointer) are returned using an object. Design
+    this object so that its destructor closes the stream (this will prevent
+    resource leaks). It will also obviate the need for the (now broken)
+    is_response_present() predicate.
+
+    @author jhrg */
+
+class HTTPConnect
+{
+private:
+    CURL *d_curl;
+    RCReader *d_rcr;
+    HTTPCache *d_http_cache;
+
+    char d_error_buffer[CURL_ERROR_SIZE]; // A human-readable message.
+
+    bool d_accept_deflate;
+
+    string d_username;  // extracted from URL
+    string d_password;  // extracted from URL
+    string d_upstring;  // used to pass info into curl
+
+    string d_cookie_jar;
+
+    vector<string> d_request_headers; // Request headers
+
+    int d_dap_client_protocol_major;
+    int d_dap_client_protocol_minor;
+
+    void www_lib_init();
+    long read_url(const string &url, FILE *stream, vector<string> *resp_hdrs,
+                  const vector<string> *headers = 0);
+    // string get_temp_file(FILE *&stream) throw(InternalErr);
+    HTTPResponse *plain_fetch_url(const string &url);
+    HTTPResponse *caching_fetch_url(const string &url);
+
+    bool url_uses_proxy_for(const string &url) throw();
+    bool url_uses_no_proxy_for(const string &url) throw();
+
+    void extract_auth_info(string &url);
+
+    friend size_t save_raw_http_header(void *ptr, size_t size, size_t nmemb,
+                                       void *http_connect);
+    friend class HTTPConnectTest;
+    friend class ParseHeader;
+
+protected:
+    /** @name Suppress default methods
+    These methods are not supported and are implemented here as protected
+    methods to suppress the C++-supplied default versions (which will
+    break this object). */
+    //@{
+    HTTPConnect() {
+		throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+	}
+	HTTPConnect(const HTTPConnect &) {
+		throw InternalErr(__FILE__, __LINE__, "Unimplemented method");
+	}
+	HTTPConnect &operator=(const HTTPConnect &) {
+		throw InternalErr(__FILE__, __LINE__, "Unimplemented assignment");
+	}
+    //@}
+
+public:
+    HTTPConnect(RCReader *rcr);
+
+    virtual ~HTTPConnect();
+
+    void set_credentials(const string &u, const string &p);
+    void set_accept_deflate(bool defalte);
+    void set_xdap_protocol(int major, int minor);
+
+    /** Set the cookie jar. This function sets the name of a file used to store
+    cookies returned by servers. This will help with things like single
+    sign on systems.
+
+    @param cookie_jar The pathname to the file that stores cookies. If this
+    is the empty string saving cookies is disabled. */
+    void set_cookie_jar(const string &cookie_jar)
+    {
+	d_cookie_jar = cookie_jar;
+    }
+
+    /** Set the state of the HTTP cache. By default, the HTTP cache is
+    enabled or disabled using the value of the \c USE_CACHE property in
+    the \c .dodsrc file. Use this method to set the state from within a
+    program.
+    @param enabled True to use the cache, False to disable. */
+    void set_cache_enabled(bool enabled)
+    {
+        if (d_http_cache)
+            d_http_cache->set_cache_enabled(enabled);
+    }
+
+    /** Return the current state of the HTTP cache. */
+    bool is_cache_enabled()
+    {
+        return (d_http_cache) ? d_http_cache->is_cache_enabled() : false;
+    }
+
+    HTTPResponse *fetch_url(const string &url);
+};
+
+} // namespace libdap
+
+#endif // _httpconnect_h
diff --git a/HTTPResponse.h b/HTTPResponse.h
new file mode 100644
index 0000000..6c2497c
--- /dev/null
+++ b/HTTPResponse.h
@@ -0,0 +1,150 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef http_response_h
+#define http_response_h
+
+#include <cstdio>
+#include <string>
+#include <iostream>
+#include <algorithm>
+#include <iterator>
+#include <vector>
+
+using std::vector ;
+
+#ifndef response_h
+#include "Response.h"
+#endif
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+namespace libdap
+{
+
+extern int dods_keep_temps; // defined in HTTPConnect.cc
+
+extern void close_temp(FILE *s, const string &name);
+
+/** Encapsulate an http response. Instead of directly returning the FILE
+    pointer from which a response is read and vector of headers, return an
+    instance of this object.
+
+    @todo Maybe refactor so that the header parsing code is hear and not in
+    HTTPConnect? */
+class HTTPResponse : public Response
+{
+private:
+    // TODO Make this a value, not a pointer. Fix all uses and then
+    // change code in HTTPConnect
+    vector<string> *d_headers; // Response headers
+    string d_file;  // Temp file that holds response body
+
+protected:
+    /** @name Suppressed default methods */
+    //@{
+    HTTPResponse()
+    {}
+    HTTPResponse(const HTTPResponse &rs) : Response(rs)
+    {}
+    HTTPResponse &operator=(const HTTPResponse &)
+    {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented assignment");
+    }
+    //@}
+
+public:
+    /** Build an HTTPResponse object. An instance of this class is used to
+    return an HTTP response (body and headers). If the response is really
+    from a remote server, the current HTTP code stores the body in a
+    temporary file and the headers in a vector<string> object. This class
+    will delete those resources when its destructor is called. If the
+    response does not have a temporary file that needs to be deleted (say
+    it actually comes from a local cache or was read directly into
+    memory), the temp file should be set to "".
+
+    @param s FILE * to the response. Read the response body from this
+    stream.
+    @param status The HTTP response status code.
+    @param h Response headers. This class will delete the pointer when
+    the instance that contains it is destroyed.
+    @param temp_file Name a the temporary file that holds the response
+    body; this file is deleted when this instance is deleted. */
+    HTTPResponse(FILE *s, int status, vector<string> *h, const string &temp_file)
+            : Response(s, status), d_headers(h), d_file(temp_file)
+    {
+        DBG(cerr << "Headers: " << endl);
+        DBGN(copy(d_headers->begin(), d_headers->end(),
+                  ostream_iterator<string>(cerr, "\n")));
+        DBGN(cerr << "end of headers." << endl);
+    }
+
+    /** When an instance is destroyed, free the temporary resources: the
+    temp_file and headers are deleted. If the tmp file name is "", it is
+    not deleted. */
+    virtual ~HTTPResponse()
+    {
+        DBG(cerr << "Freeing HTTPConnect resources (" + d_file + ")... ");
+
+        if (!dods_keep_temps && !d_file.empty()) {
+            close_temp(get_stream(), d_file);
+            set_stream(0);
+        }
+
+        delete d_headers; d_headers = 0;
+
+        DBGN(cerr << endl);
+    }
+    /** @name Accessors */
+    //@{
+    virtual vector<string> *get_headers() const
+    {
+        return d_headers;
+    }
+    virtual string get_file() const
+    {
+        return d_file;
+    }
+    //@}
+
+    /** @name Mutators */
+    //@{
+    virtual void set_headers(vector<string> *h)
+    {
+        d_headers = h;
+    }
+
+    virtual void set_file(const string &n)
+    {
+	d_file = n;
+    }
+    //@}
+};
+
+} // namespace libdap
+
+#endif // http_response_h
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..51d3c2b
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,175 @@
+
+	$Id: INSTALL 24504 2011-04-25 23:26:38Z jimg $
+
+Updated for version 3.11.1 of the OPeNDAP DAP 3.4 library software.
+
+Installing the DAP2/3.x library
+
+---------------------------------------------------------------------------
+
+BUILDING THE SOFTWARE
+REQUIREMENTS
+NOTES
+
+---------------------------------------------------------------------------
+
+BUILDING THE SOFTWARE
+
+  To build the OPeNDAP DAP2/3.x library and the getdap client program, follow
+  these steps:
+
+  0. Please skim REQUIREMENTS and NOTES sections of this file
+     before reporting problems. Thanks.
+
+  1. Type `./configure' at the system prompt. On some systems you may have
+     to type `sh configure'.
+
+  2. Type `make' to build the library, `make check' to run the tests.
+     You must have CppUnit to run `make check.' On a Mandrake/Mandriva
+     system, you need to copy or link conf/config.guess into the
+     'tests' directory and then run the tests.
+
+  3. Type `make install' to install the library files. The libraries
+     (libdap.a. libdapclient.a and libdapserver.a, etc.), their header
+     files and the getdap and dap-config utilities install under
+     /usr/local/ in lib, include/libdap and bin by default. Use the
+     --prefix option to specify a different root directory. For
+     example, './configure --prefix=/opt/opendap' would set the build
+     so that the library was installed in /opt/opendap/lib, ...
+
+Building from Our SVN Repository
+
+  If you are building from a SVN checkout, run 'autoreconf --install'
+  before './configure; make'. Using --verbose might be useful if there
+  are errors running configure. If you try to run autoconf, et c., by
+  hand and wind up with build files that don't work, use 'autoreconf
+  --force --verbose --install' and then './configure; make'. Also
+  included in SVN is a script which runs the auto* tools one by one
+  called autogen.sh. At one time this seemed to be a better way to do
+  things, but now autoreconf seems the most reliable tool for
+  bootstrapping the auto tools.
+
+  Make certain that you have recent versions of autoconf, automake and
+  libtool.
+
+AFTER INSTALLING
+
+  o Set the PATH environment variable to include the bin directory where
+    libdap was installed. For example, if using the default installation
+    directory, which is /usr/local, make sure that /usr/local/bin is on your
+    path. This is important because often libdap is built so that some other
+    software can then be built, but without setting PATH, those other
+    packages might not detect the newly installed libdap.
+
+  o Set the LD_LIBRARY_PATH environment variable to include the lib directory
+    where libdap was installed. For example, if using the default
+    installation directory, which is /usr/local, make sure that
+    /usr/local/lib is part of LD_LIBRARY_PATH. If you have set $prefix so
+    that the libraries are installed in a directory that's included in
+    ld.so.conf (on linux; other systems may use a slightly different name)
+    you don't have to use LD_LIBRARY_PATH but, but if you don't use
+    LD_LIBRARY_PATH, **make sure to re-run ldconfig**.
+
+REQUIREMENTS
+
+  o To build from a fresh SVN checkout, you'll need automake 1.11,
+    autoconf 2.63 and libtool 2.2.6. Earlier versions may work, but
+    may cause problems, particularly with the 'distcheck' target for
+    make. Given those requirements, use 'autoreconf --force --install
+    --verbose' and then build as described above. You also need bison
+    and flex as of version 3.7.9. If you don't have these tools, you
+    can try the copies of the generated files in the 'grammarfiles'
+    directory.
+
+  o The library uses libcurl and libxml2. You will need these libraries
+    installed on your system to successfully run configure and build the
+    library. You must have libcurl version 7.10.6 or newer and libxml2 2.6.16
+    or newer. We provide source versions of the packages on the web site; the
+    web pages for these projects are: http://curl.haxx.se/ and
+    http://xmlsoft.org/. Modern Linux and recent OS/X distributions include
+    these libraries.
+
+  o If you are concerned about introducing problems with your OS's package
+    system, build and install curl, et c., into a special directory (e.g.,
+    /opt/opendap/) and then be sure to set PATH to include the curl-config
+    and xml2-config scripts before running configure (e.g., run configure as
+    'PATH="$PATH:/opt/opendap/bin';./configure'). You probably should install
+    libdap.a under /opt/opendap as well, so set prefix to that path:
+    
+	'PATH="$PATH:/opt/opendap/bin';./configure --prefix=/opt/opendap'
+
+  o You should have gcc/g++ 2.95.x or greater (really, you should probably be
+    using gcc/++ 4.x, but you _can_ use 2.95 on our code). You'll also need
+    to get the stdc++ library that matches the compiler (whatever version).
+    NB: gcc 2.8.x and earlier *won't* build the software. We're working on
+    modifying the software so that it will build with a variety of compilers.
+    As of 01/22/03 we have built the code using Microsoft's Visual C++ 6.0
+    and GNU gcc/++ 3.2.1, 3.3, 3.4, 4.0, ..., 4.4. The library has also been
+    built using the native AIX compiler; see INSTALL.AIX.
+
+  o We ship the C++ source files generated using bison and flex so
+    these programs are no longer required to build the source code.
+    However, to build the C++ sources from the grammar files, you'll
+    need bison 1.25 and flex 2.5.4. Note, howver, that older versions
+    of bison and flex have some issues with the code they generate -
+    you should uses the newest versions of these tools if the software
+    you build is going to run on a production server.
+
+NOTES
+
+  o Check for other INSTALL.* files to see if there's information specific to
+    your OS (e.g., AIX).
+    
+  o If you are building on a new platform (one for which we don't supply
+    binaries), please run the tests and tell us about any failures. To do a
+    really complete job of this you'll need to get the GNU test system called
+    DejaGNU and the CppUnit unit testing package. It is very simple to
+    install these and we're very willing to help, so don't be shy!
+
+  o If you are developing code that uses the DAP, get autoconf and subversion
+    (SVN). We maintain a SVN-managed source tree that people outside the
+    group may access. See http://scm.opendap.org/trac/
+
+  o The gnulib software is used to provide replacement functions when
+    autoconf detects that is necessary. To update the gnulib, check it out
+    from CVS and run '$gnulib_home/gnulib-tool --lgpl --import' in this
+    directory. Macros in configure.ac supply gnulib-tool with all the
+    information it needs. Only developers working on libdap should ever have
+    to do this.
+
+  o To build a rpm file for a source or binary distribution use 'make rpm' or 
+    'make srpm'. These targets should run 'make dist' to build the required
+    tar.gz file first. You may need root privileges for these targets to work.
+    
+  o To build a Mac OS/X package, use the 'pkg' target. Read over the target
+    to get a feel for how it works. You will need PackageMaker, which should
+    already be installed on your system, and you will need DropDMG, which
+    can be obtained at http://c-command.com/dropdmg/. The target has been
+    automated to generate a ReadMe.txt file, update the Info.plist file, run
+    PackageMaker and DropDMG.
+
+  o DEBUGGING AIDS
+
+    - The DAP API includes the following debugging aids that may be of help
+      to you in developing new OPeNDAP applications.
+
+    - DBG: simple program instrumentation -- see the file debug.h.
+
+    - DBG2: more elaborate program instrumentation -- by convention this is
+      used for output that is half a page or more, while DEBUG is used for
+      single line output.
+
+    - In the past we used efence and dbnew to help debug dynamic memory
+      programming errors. We are now using valgrind and suggest you do the
+      same. On some Linux platforms you should export MALLOC_CHECK_=0 in the
+      shell before running valgrind. This is true for the unit tests and may
+      be true for other code. You'll also notice that the Makefile contains
+      CXX and C compile-time flags for debugging. These will greatly simplify
+      using valgrind and/or a debugger. To use these, don't hack up the
+      Makefile.am. Instead export CXXFLAGS with the values you want and then
+      run configure. For example:
+
+	  export CXXFLAGS="-g3 -O0 -Wall -fno-defer-pop"; ./configure
+
+    - To build with program instrumentation use `--enable-debug=<level>'
+      where <level> is 1 or 2.
diff --git a/Int16.cc b/Int16.cc
new file mode 100644
index 0000000..37c80a6
--- /dev/null
+++ b/Int16.cc
@@ -0,0 +1,288 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1996-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Int32.
+//
+// jhrg 9/7/94
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: Int16.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "dods-limits.h"
+#include "debug.h"
+#include "InternalErr.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The Int16 constructor accepts the name of the variable to be created.
+
+    @param n A string containing the name of the variable to be created.
+*/
+Int16::Int16(const string &n) : BaseType(n, dods_int16_c)
+{}
+
+/** The Int16 server-side constructor accepts the name of the variable and
+    the dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+Int16::Int16(const string &n, const string &d) : BaseType(n, d, dods_int16_c)
+{}
+
+Int16::Int16(const Int16 &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+Int16::ptr_duplicate()
+{
+    return new Int16(*this);
+}
+
+Int16 &
+Int16::operator=(const Int16 &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+Int16::width()
+{
+    return sizeof(dods_int16);
+}
+
+bool
+Int16::serialize(ConstraintEvaluator &eval, DDS &dds,
+                 Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_int16( _buf ) ;
+
+    return true;
+}
+
+bool
+Int16::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_int16( _buf ) ;
+
+    return false;
+}
+
+unsigned int
+Int16::val2buf(void *val, bool)
+{
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogated library,
+    // thus if the pointer val is NULL, is  an Internal Error.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    _buf = *(dods_int16 *)val;
+
+    return width();
+}
+
+unsigned int
+Int16::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    if (!*val)
+        *val = new dods_int16;
+
+    *(dods_int16 *)*val = _buf;
+
+    return width();
+}
+
+dods_int16
+Int16::value() const
+{
+    return _buf;
+}
+
+bool
+Int16::set_value(dods_int16 i)
+{
+    _buf = i;
+    set_read_p(true);
+
+    return true;
+}
+
+#if FILE_METHODS
+void
+Int16::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %d;\n", _buf) ;
+    }
+    else
+        fprintf(out, "%d", _buf) ;
+}
+#endif
+
+void
+Int16::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << _buf << ";\n" ;
+    }
+    else
+	out << _buf ;
+}
+
+bool
+Int16::ops(BaseType *b, int op)
+{
+
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b || !(b->read_p() || b->read())) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops<dods_int16, dods_byte, SUCmp<dods_int16, dods_byte> >
+               (_buf, dynamic_cast<Byte *>(b)->_buf, op);
+    case dods_int16_c:
+        return rops<dods_int16, dods_int16, Cmp<dods_int16, dods_int16> >
+               (_buf, dynamic_cast<Int16 *>(b)->_buf, op);
+    case dods_uint16_c:
+        return rops<dods_int16, dods_uint16, SUCmp<dods_int16, dods_uint16> >
+               (_buf, dynamic_cast<UInt16 *>(b)->_buf, op);
+    case dods_int32_c:
+        return rops<dods_int16, dods_int32, Cmp<dods_int16, dods_int32> >
+               (_buf, dynamic_cast<Int32 *>(b)->_buf, op);
+    case dods_uint32_c:
+        return rops<dods_int16, dods_uint32, SUCmp<dods_int16, dods_uint32> >
+               (_buf, dynamic_cast<UInt32 *>(b)->_buf, op);
+    case dods_float32_c:
+        return rops<dods_int16, dods_float32, Cmp<dods_int16, dods_float32> >
+               (_buf, dynamic_cast<Float32 *>(b)->_buf, op);
+    case dods_float64_c:
+        return rops<dods_int16, dods_float64, Cmp<dods_int16, dods_float64> >
+               (_buf, dynamic_cast<Float64 *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Int16::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Int16::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Int16.h b/Int16.h
new file mode 100644
index 0000000..9c2b505
--- /dev/null
+++ b/Int16.h
@@ -0,0 +1,114 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Int16 type.
+//
+// jhrg 9/7/94
+
+#ifndef _int16_h
+#define _int16_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** @brief Holds a 16-bit signed integer value. */
+
+class Int16: public BaseType
+{
+    /** This class allows Byte, ..., Float64 access to <tt>_buf</tt> to
+    simplify and speed up the relational operators.
+
+    NB: According to Stroustrup it does not matter where (public, private
+    or protected) friend classes are declared. */
+    friend class Byte;
+    friend class UInt16;
+    friend class Int32;
+    friend class UInt32;
+    friend class Float32;
+    friend class Float64;
+
+protected:
+    dods_int16 _buf;
+
+public:
+    Int16(const string &n);
+    Int16(const string &n, const string &d);
+    virtual ~Int16()
+    {}
+
+    Int16(const Int16 &copy_from);
+
+    Int16 &operator=(const Int16 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual unsigned int width();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual dods_int16 value() const;
+    virtual bool set_value(dods_int16 val);
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _int16_h
+
diff --git a/Int32.cc b/Int32.cc
new file mode 100644
index 0000000..8140a24
--- /dev/null
+++ b/Int32.cc
@@ -0,0 +1,299 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Int32.
+//
+// jhrg 9/7/94
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: Int32.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "dods-limits.h"
+#include "debug.h"
+#include "InternalErr.h"
+
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The Int32 constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+*/
+Int32::Int32(const string &n)
+        : BaseType(n, dods_int32_c)
+{}
+
+/** The Int32 server-side constructor accepts the name of the variable and
+    the dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+Int32::Int32(const string &n, const string &d)
+        : BaseType(n, d, dods_int32_c)
+{}
+
+Int32::Int32(const Int32 &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+Int32::ptr_duplicate()
+{
+    return new Int32(*this);
+}
+
+Int32::~Int32()
+{
+    DBG(cerr << "~Int32" << endl);
+}
+
+Int32 &
+Int32::operator=(const Int32 &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+Int32::width()
+{
+    return sizeof(dods_int32);
+}
+
+bool
+Int32::serialize(ConstraintEvaluator &eval, DDS &dds,
+                 Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_int32( _buf ) ;
+
+    return true;
+}
+
+bool
+Int32::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_int32( _buf ) ;
+
+    return false;
+}
+
+unsigned int
+Int32::val2buf(void *val, bool)
+{
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogated library,
+    // thus if the pointer val is NULL, is an Internal Error.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    _buf = *(dods_int32 *)val;
+
+    return width();
+}
+
+unsigned int
+Int32::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    if (!*val)
+        *val = new dods_int32;
+
+    *(dods_int32 *)*val = _buf;
+
+    return width();
+}
+
+dods_int32
+Int32::value() const
+{
+    return _buf;
+}
+
+bool
+Int32::set_value(dods_int32 i)
+{
+    _buf = i;
+    set_read_p(true);
+
+    return true;
+}
+
+#if FILE_METHODS
+void
+Int32::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %d;\n", (int)_buf) ;
+    }
+    else
+        fprintf(out, "%d", (int)_buf) ;
+}
+#endif
+
+void
+Int32::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << (int)_buf << ";\n" ;
+    }
+    else
+	out << (int)_buf ;
+}
+
+bool
+Int32::ops(BaseType *b, int op)
+{
+
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b->read_p() && !b->read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops<dods_int32, dods_byte, SUCmp<dods_int32, dods_byte> >
+               (_buf, dynamic_cast<Byte *>(b)->_buf, op);
+    case dods_int16_c:
+        return rops<dods_int32, dods_int16, Cmp<dods_int32, dods_int16> >
+               (_buf, dynamic_cast<Int16 *>(b)->_buf, op);
+    case dods_uint16_c:
+        return rops<dods_int32, dods_uint16, SUCmp<dods_int32, dods_uint16> >
+               (_buf, dynamic_cast<UInt16 *>(b)->_buf, op);
+    case dods_int32_c:
+        return rops<dods_int32, dods_int32, Cmp<dods_int32, dods_int32> >
+               (_buf, dynamic_cast<Int32 *>(b)->_buf, op);
+    case dods_uint32_c:
+        return rops<dods_int32, dods_uint32, SUCmp<dods_int32, dods_uint32> >
+               (_buf, dynamic_cast<UInt32 *>(b)->_buf, op);
+    case dods_float32_c:
+        return rops<dods_int32, dods_float32, Cmp<dods_int32, dods_float32> >
+               (_buf, dynamic_cast<Float32 *>(b)->_buf, op);
+    case dods_float64_c:
+        return rops<dods_int32, dods_float64, Cmp<dods_int32, dods_float64> >
+               (_buf, dynamic_cast<Float64 *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Int32::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Int32::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Int32.h b/Int32.h
new file mode 100644
index 0000000..13d32d7
--- /dev/null
+++ b/Int32.h
@@ -0,0 +1,117 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Int32 type.
+//
+// jhrg 9/7/94
+
+#ifndef _int32_h
+#define _int32_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** @brief Holds a 32-bit signed integer.
+
+    @see BaseType
+    */
+
+class Int32: public BaseType
+{
+    /** This class allows Byte, ..., Float64 access to <tt>_buf</tt> to
+    simplify and speed up the relational operators.
+
+    NB: According to Stroustrup it does not matter where (public, private
+    or protected) friend classes are declared. */
+    friend class Byte;
+    friend class Int16;
+    friend class UInt16;
+    friend class UInt32;
+    friend class Float32;
+    friend class Float64;
+
+protected:
+    dods_int32 _buf;
+
+public:
+    Int32(const string &n);
+    Int32(const string &n, const string &d);
+
+    Int32(const Int32 &copy_from);
+
+    Int32 &operator=(const Int32 &rhs);
+
+    virtual ~Int32();
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual unsigned int width();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual bool set_value(dods_int32 i);
+    virtual dods_int32 value() const;
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _int32_h
+
diff --git a/InternalErr.cc b/InternalErr.cc
new file mode 100644
index 0000000..f816a66
--- /dev/null
+++ b/InternalErr.cc
@@ -0,0 +1,98 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the InternalErr class.
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: InternalErr.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include <string>
+#include <sstream>
+
+#include "InternalErr.h"
+#include "util.h"
+
+using std::endl;
+using std::ostringstream;
+
+namespace libdap {
+
+InternalErr::InternalErr() : Error()
+{
+    _error_code = internal_error;
+}
+
+InternalErr::InternalErr(const string &msg) : Error()
+{
+    _error_code = internal_error;
+    _error_message = "";
+    _error_message += "An internal error was encountered:\n";
+    _error_message += msg + "\n";
+    _error_message += "Please report this to support at opendap.org\n";
+}
+
+
+//InternalErr::InternalErr(string msg, string file, int line)
+//    : Error(unknown_error, msg)
+InternalErr::InternalErr(const string &file, const int &line, const string &msg) : Error()
+{
+    _error_code = internal_error;
+    _error_message = "";
+    _error_message += "An internal error was encountered in " + file + " at line ";
+    // Jose Garcia. Next we append line to the string _error_code.
+    // This function is defined in util.h
+    append_long_to_string(line, 10, _error_message);
+    _error_message += ":\n";
+    _error_message += msg + "\n";
+    _error_message += "Please report this to support at opendap.org\n";
+}
+
+InternalErr::InternalErr(const InternalErr &copy_from)
+        : Error(copy_from)
+{}
+
+InternalErr::~InternalErr()
+{}
+
+/**
+    @brief Is the InternalErr object valid?
+    @return TRUE if the object is valid, FALSE otherwise. */
+bool
+InternalErr::OK()
+{
+    return Error::OK();
+}
+
+} // namespace libdap
diff --git a/InternalErr.h b/InternalErr.h
new file mode 100644
index 0000000..5baefd9
--- /dev/null
+++ b/InternalErr.h
@@ -0,0 +1,93 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the InternalErr class
+//
+// 5/3/99 jhrg
+
+#ifndef _internalerr_h
+#define _internalerr_h 1
+
+
+#include <string>
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+namespace libdap
+{
+
+
+/** The InternalErr class is used to signal that somewhere inside libdap a
+    software fault was found. This class wraps the message text in some
+    boiler plate that asks the error be reported to us (tech support).
+
+    NB: This class Adds some text to the message and might, in the future,
+    hold information not also held in Error. However, all Error objects
+    thrown on the server-side of libdap that cannot be resolved (and that's all
+    of them for now, 5/3/99 jhrg) will be sent to the client-side <i>using
+    Error objects</i>. That is, the information recorded in an InternalErr
+    object will be sent by calling the <tt>print(...)</tt> mfunc of Error.
+
+    @brief A class for software fault reporting.
+    @author jhrg */
+
+class InternalErr: public Error
+{
+
+public:
+    /** These constructors always set the error code to <tt>internal_error</tt>.
+
+    Note that there is no way to specify an error correction program for
+    an internal error.
+
+    @brief Constructors for the Error object
+    @name Constructors */
+    //@{
+    ///
+    InternalErr(const string &msg);
+    ///
+    InternalErr(const string &file, const int &line, const string &msg);
+    ///
+    InternalErr();
+    ///
+    InternalErr(const InternalErr &copy_from);
+    //@}
+
+    virtual ~InternalErr();
+
+    bool OK();
+};
+
+} // namespace libdap
+
+#endif // _internalerr_h
diff --git a/Keywords2.cc b/Keywords2.cc
new file mode 100644
index 0000000..3366f26
--- /dev/null
+++ b/Keywords2.cc
@@ -0,0 +1,211 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2011 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+#include "config.h"
+
+static char rcsid[] not_used = { "$Id: ResponseBuilder.cc 23477 2010-09-02 21:02:59Z jimg $" };
+
+#include <iostream>
+#include <vector>
+
+//#define DODS_DEBUG
+
+#include "Keywords2.h"
+#include "Error.h"
+#include "escaping.h"
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+Keywords::Keywords()
+{
+    // Load known keywords and their allowed values
+    vector<string> v1(7);
+    v1[0] = "2"; v1[1] = "2.0"; v1[2] = "3.2"; v1[3] = "3.3"; v1[4] = "3.4";
+    v1[5] = "4"; v1[6] = "4.0";
+    value_set_t vs = value_set_t(v1.begin(), v1.end());
+    d_known_keywords["dap"] = vs;
+
+    vector<string> v2(4);
+    v2[0] = "md5"; v2[1] = "MD5"; v2[2] = "sha1"; v2[3] = "SHA1";
+    value_set_t vs2 = value_set_t(v2.begin(), v2.end());
+    d_known_keywords["checksum"] = vs2;
+}
+
+Keywords::~Keywords()
+{
+}
+
+/** Static function to parse the curly-brace keyword notation.
+ * @param kw the keyword clause '<word> ( <value> )'
+ * @param word (result) the word
+ * @param value (result) the value
+ * @return True if the parse was successful (word and value contain useful
+ * results) and False otherwise.
+ */
+static bool f_parse_keyword(const string &kw, string &word, string &value)
+{
+    word = "";
+    value = "";
+    string::size_type i = kw.find('(');
+    if (i == string::npos)
+	return false;
+    word = kw.substr(0, i);
+    string::size_type j = kw.find(')');
+    if (j == string::npos)
+	return false;
+    ++i; // Move past the opening brace
+    value = kw.substr(i, j-i);
+
+    return (!word.empty() && !value.empty());
+}
+
+/**
+ * Add the keyword to the set of keywords that apply to this request.
+ * @note Should call m_is_valid_keyword first.
+ * @param word The keyword/function name
+ * @param value The keyword/function value
+ */
+void Keywords::m_add_keyword(const keyword &word, const keyword_value &value)
+{
+    d_parsed_keywords[word] = value;
+}
+
+/** Is the string a valid keyword clause? Assumption: the word and value have
+ * already been successfully parsed.
+ * @param word The keyword/function name
+ * @param value The keyword/function value
+ * @return True if the string is valid keyword and the value is one of the
+ * allowed values.
+ */
+bool Keywords::m_is_valid_keyword(const keyword &word, const keyword_value &value) const
+{
+    map<keyword, value_set_t>::const_iterator ci = d_known_keywords.find(word);
+    if (ci == d_known_keywords.end())
+	return false;
+    else {
+	value_set_t vs = ci->second;
+
+	if (vs.find(value) == vs.end())
+	    throw Error("Bad value passed to the keyword/function: " + word);
+    }
+
+    return true;
+}
+
+/**
+ * Is the word one of the known keywords for this version of libdap?
+ * @param s As a string, including the value
+ * @return true if the keyword is known
+ */
+bool Keywords::is_known_keyword(const string &word) const
+{
+	return d_known_keywords.count(word) == 1;
+}
+
+/**
+ * Get a list of the strings that make up the set of current keywords for
+ * this request.
+ * @return The list of keywords as a list of string objects.
+ */
+list<Keywords::keyword> Keywords::get_keywords() const
+{
+    list<keyword> kws;
+    map<keyword, keyword_value>::const_iterator i;
+    for (i = d_parsed_keywords.begin(); i != d_parsed_keywords.end(); ++i)
+    	kws.push_front((*i).first);
+
+    return kws;
+}
+
+
+/**
+ * Lookup a keyword_kind and return true if it has been set for this request,
+ * otherwise return false.
+ * @param kw Keyword
+ * @return true if the keyword is set.
+ */
+bool Keywords::has_keyword(const keyword &kw) const
+{
+    return d_parsed_keywords.count(kw) == 1;
+}
+
+/** Look at the parsed keywords for the value associated with a given keyword.
+ *
+ * @param k
+ * @return The value
+ */
+Keywords::keyword_value Keywords::get_keyword_value(const keyword &kw) const
+{
+    if (d_known_keywords.find(kw) == d_known_keywords.end())
+    	throw Error("Keyword not known (" + kw + ")");
+
+    return d_parsed_keywords.find(kw)->second;
+}
+
+/** Parse the constraint expression, removing all keywords. As a side effect,
+ * return the remaining CE.
+ * @param ce
+ * @return The CE stripped of all recognized keywords.
+ */
+string Keywords::parse_keywords(const string &ce)
+{
+    // Get the whole CE
+    string projection = www2id(ce, "%", "%20");
+    string selection = "";
+
+    // Separate the selection part (which follows/includes the first '&')
+    string::size_type amp = projection.find('&');
+    if (amp != string::npos) {
+	selection = projection.substr(amp);
+	projection = projection.substr(0, amp);
+    }
+
+    // Extract keywords; add to the Keywords keywords. For this, scan for
+    // a known set of keywords and assume that anything else is part of the
+    // projection and should be left alone. Keywords must come before variables
+    // The 'projection' string will look like: '' or 'dap4.0' or 'dap4.0,u,v'
+    while (!projection.empty()) {
+	string::size_type i = projection.find(',');
+	string next_word = projection.substr(0, i);
+	string word, value;
+	if (f_parse_keyword(next_word, word, value)
+	    && m_is_valid_keyword(word, value)) {
+	    m_add_keyword(word, value);
+	    if (i != string::npos)
+		projection = projection.substr(i + 1);
+	    else
+		projection = "";
+	}
+	else {
+	    break; // exit on first non-keyword
+	}
+    }
+
+    // The CE is whatever is left after removing the keywords
+    return projection + selection;
+}
+
+}
diff --git a/Keywords2.h b/Keywords2.h
new file mode 100644
index 0000000..d61a398
--- /dev/null
+++ b/Keywords2.h
@@ -0,0 +1,86 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2011 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef KEYWORDS_H_
+#define KEYWORDS_H_
+
+#include <string>
+#include <set>
+#include <map>
+#include <list>
+
+using namespace std;
+
+namespace libdap {
+
+/**
+ * Manage keywords for libdap. These are passed in to the library using the
+ * constraint expression - in fact they are an extension of the CE and this
+ * class implements the parsing needed to remove them from the CE so that
+ * the ConstraintExpression evaluator can parse it (because the keywords are
+ * not identifiers in the DDS, they will cause a parse error.
+ *
+ * @note If pointers are added to this code, modify DDS so copying still works!
+ *
+ * @note The keywords are used to specify the DAP version(s) that the client
+ * can understand.
+ */
+class Keywords {
+public:
+    // convenience types
+    typedef string keyword;
+    typedef string keyword_value;
+    typedef set<keyword_value> value_set_t;
+
+private:
+    /// Holds the keywords and value of the keywords passed in the CE
+    map<keyword, keyword_value> d_parsed_keywords;
+
+    /// Holds all of the keywords
+    map<keyword, value_set_t> d_known_keywords;
+
+    virtual void m_add_keyword(const keyword &word, const keyword_value &value);
+    virtual bool m_is_valid_keyword(const keyword &word, const keyword_value &value) const;
+
+public:
+    Keywords();
+    virtual ~Keywords();
+
+    virtual string parse_keywords(const string &ce);
+
+    // Is this keyword in the dictionary?
+    virtual bool is_known_keyword(const string &s) const;
+
+    // Get a list of all of the keywords parsed
+    virtual list<keyword> get_keywords() const;
+    // Has a particular keyword been parsed
+    virtual bool has_keyword(const keyword &kw) const;
+
+    // Get the parsed keyword (and it's dictionary value) of a particular kind
+    virtual keyword_value get_keyword_value(const keyword &kw) const;
+};
+
+}
+
+#endif /* KEYWORDS_H_ */
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..2dc64dc
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,326 @@
+# Build libdap, libtest-types.a, getdap
+
+AUTOMAKE_OPTIONS = foreign check-news
+ACLOCAL_AMFLAGS = -I conf -I gl/m4
+
+aclocaldir=$(datadir)/aclocal
+pkgconfigdir=$(libdir)/pkgconfig
+
+# Arrange to build with the backward compatibility mode enabled.
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/GNU 
+# -I$(top_srcdir)/xstream
+AM_CXXFLAGS = 
+if COMPILER_IS_GCC
+AM_CXXFLAGS += -Wall -W -Wcast-align
+endif
+
+AM_YFLAGS = -d -v
+AM_LFLAGS = -8
+
+# These are not used by automake but are often useful for certain types of
+# debugging. The best way to use these is to run configure as:
+#     export CXXFLAGS='...'; ./configure --disable-shared
+# the --disable-shared is not required, but it seems to help with debuggers.
+CXXFLAGS_DEBUG = -g3 -O0 -fno-defer-pop -Wall -W -Wcast-align -Werror
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+
+SUBDIRS = gl . tests unit-tests
+DIST_SUBDIRS = unit-tests gl tests
+
+noinst_LTLIBRARIES = libparsers.la
+lib_LTLIBRARIES = libdap.la libdapclient.la libdapserver.la
+
+bin_SCRIPTS = dap-config dap-config-pkgconfig
+
+bin_PROGRAMS = getdap
+# fdiostream_test
+
+# sbin_PROGRAMS = deflate
+
+BUILT_SOURCES = $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h
+
+libparsers_la_SOURCES = $(GRAM_SRC) 
+
+libdap_la_SOURCES = $(DAP_SRC) $(GNU_SRC) 
+libdap_la_LDFLAGS = -version-info $(LIBDAP_VERSION)
+libdap_la_CPPFLAGS = $(AM_CPPFLAGS) $(XML2_CFLAGS)
+libdap_la_LIBADD = $(XML2_LIBS) $(PTHREAD_LIBS) gl/libgnu.la libparsers.la
+
+libdapclient_la_SOURCES = $(CLIENT_SRC) 
+libdapclient_la_LDFLAGS = -version-info $(CLIENTLIB_VERSION)
+libdapclient_la_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS) $(XML2_CFLAGS)
+libdapclient_la_LIBADD = $(CURL_LIBS) libdap.la $(PTHREAD_LIBS)
+
+libdapserver_la_SOURCES = $(SERVER_SRC)
+libdapserver_la_LDFLAGS = -version-info $(SERVERLIB_VERSION)
+libdapserver_la_LIBADD = libdap.la $(UUID_LIBS)
+
+pkginclude_HEADERS = $(DAP_HDR) $(GNU_HDR) $(CLIENT_HDR) $(SERVER_HDR) 
+
+noinst_HEADERS = config_dap.h
+
+# fdiostream_test_SOURCES = GNU/fdiostream_test.cc
+
+getdap_SOURCES = getdap.cc
+getdap_LDADD = libdapclient.la libdap.la
+getdap_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
+
+LEX_YACC_EXTRA = das.lex das.y dds.lex dds.y ce_expr.lex ce_expr.y gse.lex \
+	gse.y Error.lex Error.y
+
+EXTRA_DIST = ChangeLog COPYING README.dodsrc COPYRIGHT_URI	 \
+	COPYRIGHT_W3C GNU/README doxy.conf doxy_private.conf libdap.spec \
+	VCPP dods-datatypes-static.h xdr-datatypes-static.h \
+	dap-config-pkgconfig $(LEX_YACC_EXTRA) $(GRAM_SRC) OSX_Resources
+
+# README.AIS xstream/README 
+
+dist_aclocal_DATA = conf/libdap.m4
+pkgconfig_DATA = libdap.pc libdapclient.pc libdapserver.pc
+
+CLEANFILES = *.log *.output *.gcda *.gcno $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h
+
+# Not nearly as clean as it could be, but this removes .svn directories
+# in subdirs.
+dist-hook:
+	rm -rf `find $(distdir) -name .svn`
+
+# MAINTAINERCLEANFILES = $(GRAM_SRC)
+
+# Copy the generated grammar files to the 'grammarfiles' directory.
+.PHONY: grammarfiles
+grammarfiles: $(GRAM_SRC)
+	for f in $(GRAM_SRC); do cp $$f grammarfiles; done
+
+.PHONY: docs
+docs:
+	doxygen $(srcdir)/doxy.conf
+	(cd docs && tar -czf html.tar.gz html)
+
+# cccc computes metrics like Lines of code and McCabe. It'a available
+# on the web...
+.PHONY: cccc
+cccc:
+	-mkdir cccc
+	cccc --outdir=cccc $(DAP_SRC) $(SERVER_SRC) $(CLIENT_SRC) \
+	$(DAP_HDR) $(SERVER_HDR) $(CLIENT_HDR)
+
+###########################################################################
+
+# Fortify targets.
+# dods-datatypes.h xdr-datatypes.h
+.PHONY: fortify
+fortify: $(BUILT_SOURCES)
+	(cd gl && sourceanalyzer -b @PACKAGE at -gl $(MAKE) )
+	sourceanalyzer -b @PACKAGE at -parsers $(MAKE) libparsers.la
+	sourceanalyzer -b @PACKAGE@ $(MAKE) libdap.la libdapserver.la libdapclient.la
+	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
+
+# run fortify on only our code, not the gnulib code or the flex/bison code.
+# This does skip testing some of the functions we wrote in the *.lex/*.y
+# files but should eliminate the false positives from flex and bison, too.
+.PHONY: fortify-lite
+fortify-lite: dods-datatypes.h xdr-datatypes.h
+	( cd gl && $(MAKE) )
+	$(MAKE) libparsers.la
+	sourceanalyzer -b @PACKAGE@ $(MAKE) libdap.la libdapserver.la libdapclient.la
+	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
+
+grammar_objects = lex.das.o das.tab.o lex.dds.o dds.tab.o lex.ce_expr.o \
+ce_expr.tab.o lex.gse_.o gse.tab.o lex.Error.o Error.tab.o
+
+# Use this to clean the fortify project.
+.PHONY: fortifyclean
+fortifyclean:
+	(cd gl && sourceanalyzer -b @PACKAGE at -gl -clean )
+	sourceanalyzer -b @PACKAGE@ -clean
+
+###########################################################################
+
+# Build linux RPMs. Use the environment variable 'RPM_OPTIONS' to pass in
+# extra options like --nodeps and --macros
+
+srpm: dist
+	rpmbuild -ts --clean $(RPM_OPTIONS) @PACKAGE at -@PACKAGE_VERSION at .tar.gz
+
+rpm: dist
+	rpmbuild -tb --clean $(RPM_OPTIONS) @PACKAGE at -@PACKAGE_VERSION at .tar.gz
+
+###########################################################################
+
+# Build OS/X Packages. The strange operations with configure and make
+# are there so that the values built into dap-config will match the mac
+# osx install dirs and not the temp directory used to build the packages
+
+# PACKAGEMAKER=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker*
+
+PACKAGEMAKER=/Developer/usr/bin/packagemaker
+PKG_CONF_FLAGS=
+
+clean-pkg:
+	-rm -rf mac_osx @PACKAGE at -@PACKAGE_VERSION at .pkg
+
+pkg-build: clean-pkg
+	./configure --prefix=$(prefix) --disable-dependency-tracking $(PKG_CONF_FLAGS)
+	make clean all
+	DESTDIR=`pwd`/mac_osx make install
+
+pkg-main: pkg-build
+	./OSX_Resources/update_mac_package_contents.pl README
+	cat ./OSX_Resources/Info.plist.proto | \
+	   sed -e "s^_PREFIX_^$(prefix)^g" \
+	       -e "s^_FULL_VERSION_^@PACKAGE_VERSION@^g" \
+	       -e "s^_MAJOR_VERSION_^@PACKAGE_MAJOR_VERSION@^g" \
+	       -e "s^_MINOR_VERSION_^@PACKAGE_MINOR_VERSION@^g" \
+	       > foo
+	mv foo ./OSX_Resources/Info.plist
+	${PACKAGEMAKER} --root mac_osx --id org.opendap. at PACKAGE@ \
+	    --title "@PACKAGE@ @PACKAGE_VERSION@" --version @PACKAGE_VERSION@ \
+	    --out @PACKAGE at -@PACKAGE_VERSION at .pkg --resources OSX_Resources
+
+pkg-dmg: pkg-main
+	-rm -rf @PACKAGE at -@PACKAGE_VERSION@
+	-rm -rf @PACKAGE at -@PACKAGE_VERSION at .dmg
+	mkdir @PACKAGE at -@PACKAGE_VERSION@
+	cp -r @PACKAGE at -@PACKAGE_VERSION at .pkg @PACKAGE at -@PACKAGE_VERSION@
+	cp README README.* NEWS @PACKAGE at -@PACKAGE_VERSION@
+	dropdmg -i --sanitize-for-servers --format zlib @PACKAGE at -@PACKAGE_VERSION@
+	-rm -rf @PACKAGE at -@PACKAGE_VERSION@
+
+pkg: pkg-main 
+
+# Note that the gcov options -f and -b are useful but sometimes make looking
+# at the results of coverage analysis a little taxing. -b reports on all
+# branched and -f reports on all functions. The -l -o options summarize on a
+# per-file basis. 3/27/98 jhrg
+collect-coverage-data:
+	(cd test-coverage; \
+         cov_dat="coverage-data-`date +%m.%d.%y`"; \
+         touch $$cov_dat; \
+         for f in $(ALLSRCS); do \
+            echo "\n*** Coverage data for $$f ***\n" >> $$cov_dat; \
+            gcov -l -o ../ $$f >> $$cov_dat; \
+         done)
+
+#############################################################################
+# Library sources
+# 
+
+GNU_SRC = GNU/GetOpt.cc GNU/GNURegex.cc
+
+GNU_HDR = GNU/GetOpt.h GNU/GNURegex.h
+
+GRAM_SRC = lex.das.cc das.tab.cc das.tab.hh lex.dds.cc dds.tab.cc	\
+	dds.tab.hh lex.ce_expr.cc ce_expr.tab.cc ce_expr.tab.hh		\
+	lex.Error.cc Error.tab.cc Error.tab.hh gse.tab.hh gse.tab.cc	\
+	lex.gse_.cc
+
+DAP_SRC = AttrTable.cc DAS.cc DDS.cc DataDDS.cc DDXParserSAX2.cc	\
+	BaseType.cc Byte.cc Int32.cc Float64.cc Str.cc Url.cc		\
+	Vector.cc Array.cc Structure.cc Sequence.cc Grid.cc UInt32.cc	\
+	Int16.cc UInt16.cc Float32.cc Constructor.cc			\
+	BaseTypeFactory.cc SignalHandler.cc Error.cc InternalErr.cc	\
+	util.cc xdrutil_ppc.c parser-util.cc escaping.cc		\
+	ce_functions.cc GSEClause.cc GeoConstraint.cc			\
+	GridGeoConstraint.cc Clause.cc RValue.cc			\
+	ConstraintEvaluator.cc ArrayGeoConstraint.cc DapIndent.cc	\
+	Operators.h XDRUtils.cc XDRFileMarshaller.cc			\
+	XDRFileUnMarshaller.cc XDRStreamMarshaller.cc			\
+	XDRStreamUnMarshaller.cc mime_util.cc Keywords2.cc
+
+Operators.h: ce_expr.tab.hh
+
+# Operators.h is included in with the source to prevent it from bing installed
+# with the other headers. It includes one of the built grammar file headers.
+
+CLIENT_SRC = RCReader.cc Connect.cc HTTPConnect.cc HTTPCache.cc	\
+	util_mit.cc ResponseTooBigErr.cc HTTPCacheTable.cc
+
+SERVER_SRC = DODSFilter.cc Ancillary.cc ResponseBuilder.cc
+
+DAP_HDR = AttrTable.h DAS.h DDS.h DataDDS.h DDXParserSAX2.h		\
+	DDXExceptions.h BaseType.h Byte.h Int32.h Float64.h Str.h	\
+	Url.h Vector.h Array.h Constructor.h Structure.h Sequence.h	\
+	Grid.h UInt32.h Int16.h UInt16.h Float32.h BaseTypeFactory.h	\
+	ObjectType.h EncodingType.h SignalHandler.h Error.h		\
+	InternalErr.h util.h escaping.h parser.h debug.h dods-limits.h	\
+	dods-datatypes.h GeoConstraint.h GridGeoConstraint.h		\
+	ArrayGeoConstraint.h ce_functions.h gse_parser.h GSEClause.h	\
+	util_mit.h expr.h Clause.h RValue.h ConstraintEvaluator.h	\
+	ce_parser.h DapIndent.h DapObj.h XDRFileMarshaller.h		\
+	Marshaller.h XDRFileUnMarshaller.h UnMarshaller.h		\
+	XDRStreamMarshaller.h XDRUtils.h xdr-datatypes.h mime_util.h	\
+	cgi_util.h XDRStreamUnMarshaller.h Keywords2.h
+
+if USE_C99_TYPES
+dods-datatypes.h: dods-datatypes-static.h
+else
+dods-datatypes.h: dods-datatypes-config.h
+endif
+	cp -p $< dods-datatypes.h
+
+xdr-datatypes.h: xdr-datatypes-config.h
+	cp -p $< xdr-datatypes.h
+
+CLIENT_HDR = RCReader.h Connect.h HTTPConnect.h HTTPCache.h		\
+	HTTPCacheDisconnectedMode.h HTTPCacheInterruptHandler.h		\
+	Response.h HTTPResponse.h HTTPCacheResponse.h PipeResponse.h	\
+	StdinResponse.h SignalHandlerRegisteredErr.h			\
+	ResponseTooBigErr.h Resource.h HTTPCacheTable.h
+
+SERVER_HDR = DODSFilter.h AlarmHandler.h EventHandler.h Ancillary.h	\
+	ResponseBuilder.h
+
+############################################################################
+# Special rules for the grammars. I tried to use the automake grammar support
+# but these grammars are so hacked that it was taking too much time. Maybe if
+# each grammar was converted one by one... jhrg 6/22/05
+# 
+# I switched to using flex options instead of sed and mv. jhrg 02/28/08
+#
+# Build the DAS scanner and parser
+
+lex.das.cc: das.lex das.tab.cc das.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+# The funny if statment accommodates older versions of bison that treats
+# -o differently than the 2.x versions. jhrg 3/2/08
+das.tab.cc das.tab.hh: das.y DAS.h
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p das -o das.tab.cc $<
+	if test -e das.tab.cc.h; then mv das.tab.cc.h das.tab.hh; fi
+
+# DDS
+
+lex.dds.cc: dds.lex dds.tab.cc dds.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+dds.tab.cc dds.tab.hh: dds.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p dds -o dds.tab.cc $<
+	if test -e dds.tab.cc.h; then mv dds.tab.cc.h dds.tab.hh; fi
+
+# CE
+
+lex.ce_expr.cc: ce_expr.lex ce_expr.tab.cc ce_expr.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+ce_expr.tab.cc ce_expr.tab.hh: ce_expr.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p ce_expr -o ce_expr.tab.cc $<
+	if test -e ce_expr.tab.cc.h; then mv ce_expr.tab.cc.h ce_expr.tab.hh; fi
+
+# Build the grid selection sub_expression scanner and parser
+
+lex.gse_.cc: gse.lex gse.tab.cc gse.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+gse.tab.cc gse.tab.hh: gse.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p gse_ -o gse.tab.cc $<
+	if test -e gse.tab.cc.h; then mv gse.tab.cc.h gse.tab.hh; fi
+
+# Errors
+
+lex.Error.cc: Error.lex Error.tab.cc Error.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+Error.tab.cc Error.tab.hh: Error.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p Error -o Error.tab.cc $<
+	if test -e Error.tab.cc.h; then mv Error.tab.cc.h Error.tab.hh; fi
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..e599f18
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,2257 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# Build libdap, libtest-types.a, getdap
+
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at COMPILER_IS_GCC_TRUE@am__append_1 = -Wall -W -Wcast-align
+bin_PROGRAMS = getdap$(EXEEXT)
+subdir = .
+DIST_COMMON = README $(am__configure_deps) $(dist_aclocal_DATA) \
+	$(noinst_HEADERS) $(pkginclude_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/config.h.in \
+	$(srcdir)/dap-config.in $(srcdir)/dods-datatypes-config.h.in \
+	$(srcdir)/libdap.pc.in $(srcdir)/libdapclient.pc.in \
+	$(srcdir)/libdapserver.pc.in \
+	$(srcdir)/xdr-datatypes-config.h.in $(top_srcdir)/configure \
+	COPYING ChangeLog INSTALL NEWS conf/config.guess \
+	conf/config.sub conf/depcomp conf/install-sh conf/ltmain.sh \
+	conf/missing
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
+	$(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/btowc.m4 \
+	$(top_srcdir)/gl/m4/codeset.m4 \
+	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/fcntl-o.m4 $(top_srcdir)/gl/m4/glibc21.m4 \
+	$(top_srcdir)/gl/m4/gnulib-common.m4 \
+	$(top_srcdir)/gl/m4/gnulib-comp.m4 \
+	$(top_srcdir)/gl/m4/gnulib-tool.m4 \
+	$(top_srcdir)/gl/m4/include_next.m4 \
+	$(top_srcdir)/gl/m4/langinfo_h.m4 \
+	$(top_srcdir)/gl/m4/localcharset.m4 \
+	$(top_srcdir)/gl/m4/locale-fr.m4 \
+	$(top_srcdir)/gl/m4/locale-ja.m4 \
+	$(top_srcdir)/gl/m4/locale-zh.m4 \
+	$(top_srcdir)/gl/m4/longlong.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+	$(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+	$(top_srcdir)/gl/m4/mbstate_t.m4 \
+	$(top_srcdir)/gl/m4/multiarch.m4 \
+	$(top_srcdir)/gl/m4/nl_langinfo.m4 \
+	$(top_srcdir)/gl/m4/regex.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+	$(top_srcdir)/gl/m4/stdbool.m4 $(top_srcdir)/gl/m4/stddef_h.m4 \
+	$(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/stdlib_h.m4 \
+	$(top_srcdir)/gl/m4/unistd_h.m4 \
+	$(top_srcdir)/gl/m4/warn-on-use.m4 \
+	$(top_srcdir)/gl/m4/wchar_h.m4 $(top_srcdir)/gl/m4/wchar_t.m4 \
+	$(top_srcdir)/gl/m4/wcrtomb.m4 $(top_srcdir)/gl/m4/wctype_h.m4 \
+	$(top_srcdir)/gl/m4/wint_t.m4 $(top_srcdir)/conf/acinclude.m4 \
+	$(top_srcdir)/conf/check_zlib.m4 $(top_srcdir)/conf/cppunit.m4 \
+	$(top_srcdir)/conf/libtool.m4 $(top_srcdir)/conf/ltoptions.m4 \
+	$(top_srcdir)/conf/ltsugar.m4 $(top_srcdir)/conf/ltversion.m4 \
+	$(top_srcdir)/conf/lt~obsolete.m4 $(top_srcdir)/conf/pkg.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = config.h dods-datatypes-config.h \
+	xdr-datatypes-config.h
+CONFIG_CLEAN_FILES = libdap.pc libdapclient.pc libdapserver.pc \
+	dap-config
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+    $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+    *) f=$$p;; \
+  esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+  srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+  for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+  for p in $$list; do echo "$$p $$p"; done | \
+  sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+  $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+    if (++n[$$2] == $(am__install_max)) \
+      { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+    END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+  sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+  sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
+	"$(DESTDIR)$(bindir)" "$(DESTDIR)$(aclocaldir)" \
+	"$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)"
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libdap_la_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	gl/libgnu.la libparsers.la
+am__objects_1 = libdap_la-AttrTable.lo libdap_la-DAS.lo \
+	libdap_la-DDS.lo libdap_la-DataDDS.lo \
+	libdap_la-DDXParserSAX2.lo libdap_la-BaseType.lo \
+	libdap_la-Byte.lo libdap_la-Int32.lo libdap_la-Float64.lo \
+	libdap_la-Str.lo libdap_la-Url.lo libdap_la-Vector.lo \
+	libdap_la-Array.lo libdap_la-Structure.lo \
+	libdap_la-Sequence.lo libdap_la-Grid.lo libdap_la-UInt32.lo \
+	libdap_la-Int16.lo libdap_la-UInt16.lo libdap_la-Float32.lo \
+	libdap_la-Constructor.lo libdap_la-BaseTypeFactory.lo \
+	libdap_la-SignalHandler.lo libdap_la-Error.lo \
+	libdap_la-InternalErr.lo libdap_la-util.lo \
+	libdap_la-xdrutil_ppc.lo libdap_la-parser-util.lo \
+	libdap_la-escaping.lo libdap_la-ce_functions.lo \
+	libdap_la-GSEClause.lo libdap_la-GeoConstraint.lo \
+	libdap_la-GridGeoConstraint.lo libdap_la-Clause.lo \
+	libdap_la-RValue.lo libdap_la-ConstraintEvaluator.lo \
+	libdap_la-ArrayGeoConstraint.lo libdap_la-DapIndent.lo \
+	libdap_la-XDRUtils.lo libdap_la-XDRFileMarshaller.lo \
+	libdap_la-XDRFileUnMarshaller.lo \
+	libdap_la-XDRStreamMarshaller.lo \
+	libdap_la-XDRStreamUnMarshaller.lo libdap_la-mime_util.lo \
+	libdap_la-Keywords2.lo
+am__objects_2 = libdap_la-GetOpt.lo libdap_la-GNURegex.lo
+am_libdap_la_OBJECTS = $(am__objects_1) $(am__objects_2)
+libdap_la_OBJECTS = $(am_libdap_la_OBJECTS)
+libdap_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libdap_la_LDFLAGS) $(LDFLAGS) -o $@
+libdapclient_la_DEPENDENCIES = $(am__DEPENDENCIES_1) libdap.la \
+	$(am__DEPENDENCIES_1)
+am__objects_3 = libdapclient_la-RCReader.lo libdapclient_la-Connect.lo \
+	libdapclient_la-HTTPConnect.lo libdapclient_la-HTTPCache.lo \
+	libdapclient_la-util_mit.lo \
+	libdapclient_la-ResponseTooBigErr.lo \
+	libdapclient_la-HTTPCacheTable.lo
+am_libdapclient_la_OBJECTS = $(am__objects_3)
+libdapclient_la_OBJECTS = $(am_libdapclient_la_OBJECTS)
+libdapclient_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libdapclient_la_LDFLAGS) $(LDFLAGS) -o $@
+libdapserver_la_DEPENDENCIES = libdap.la $(am__DEPENDENCIES_1)
+am__objects_4 = DODSFilter.lo Ancillary.lo ResponseBuilder.lo
+am_libdapserver_la_OBJECTS = $(am__objects_4)
+libdapserver_la_OBJECTS = $(am_libdapserver_la_OBJECTS)
+libdapserver_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+	$(CXXFLAGS) $(libdapserver_la_LDFLAGS) $(LDFLAGS) -o $@
+libparsers_la_LIBADD =
+am__objects_5 = lex.das.lo das.tab.lo lex.dds.lo dds.tab.lo \
+	lex.ce_expr.lo ce_expr.tab.lo lex.Error.lo Error.tab.lo \
+	gse.tab.lo lex.gse_.lo
+am_libparsers_la_OBJECTS = $(am__objects_5)
+libparsers_la_OBJECTS = $(am_libparsers_la_OBJECTS)
+PROGRAMS = $(bin_PROGRAMS)
+am_getdap_OBJECTS = getdap-getdap.$(OBJEXT)
+getdap_OBJECTS = $(am_getdap_OBJECTS)
+getdap_DEPENDENCIES = libdapclient.la libdap.la
+SCRIPTS = $(bin_SCRIPTS)
+DEFAULT_INCLUDES = -I. at am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/conf/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libdap_la_SOURCES) $(libdapclient_la_SOURCES) \
+	$(libdapserver_la_SOURCES) $(libparsers_la_SOURCES) \
+	$(getdap_SOURCES)
+DIST_SOURCES = $(libdap_la_SOURCES) $(libdapclient_la_SOURCES) \
+	$(libdapserver_la_SOURCES) $(libparsers_la_SOURCES) \
+	$(getdap_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+DATA = $(dist_aclocal_DATA) $(pkgconfig_DATA)
+HEADERS = $(noinst_HEADERS) $(pkginclude_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir dist dist-all distcheck
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+am__remove_distdir = \
+  { test ! -d "$(distdir)" \
+    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+         && rm -fr "$(distdir)"; }; }
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+DIST_ARCHIVES = $(distdir).tar.gz
+GZIP_ENV = --best
+distuninstallcheck_listfiles = find . -type f -print
+distcleancheck_listfiles = find . -type f -print
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLIENTLIB_AGE = @CLIENTLIB_AGE@
+CLIENTLIB_CURRENT = @CLIENTLIB_CURRENT@
+CLIENTLIB_REVISION = @CLIENTLIB_REVISION@
+CLIENTLIB_VERSION = @CLIENTLIB_VERSION@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
+CPPUNIT_CONFIG = @CPPUNIT_CONFIG@
+CPPUNIT_LIBS = @CPPUNIT_LIBS@
+CURL_CFLAGS = @CURL_CFLAGS@
+CURL_LIBS = @CURL_LIBS@
+CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DAPLIB_AGE = @DAPLIB_AGE@
+DAPLIB_CURRENT = @DAPLIB_CURRENT@
+DAPLIB_REVISION = @DAPLIB_REVISION@
+DAP_PROTOCOL_VERSION = @DAP_PROTOCOL_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVR = @DVR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EVAL = @EVAL@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIBC21 = @GLIBC21@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDAP_VERSION = @LIBDAP_VERSION@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_MAJOR_VERSION = @PACKAGE_MAJOR_VERSION@
+PACKAGE_MINOR_VERSION = @PACKAGE_MINOR_VERSION@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_SUBMINOR_VERSION = @PACKAGE_SUBMINOR_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVERLIB_AGE = @SERVERLIB_AGE@
+SERVERLIB_CURRENT = @SERVERLIB_CURRENT@
+SERVERLIB_REVISION = @SERVERLIB_REVISION@
+SERVERLIB_VERSION = @SERVERLIB_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+XML2_STATIC_LIBS = @XML2_STATIC_LIBS@
+YACC = @YACC@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+curlprivatelibs = @curlprivatelibs@
+curlprivatereq = @curlprivatereq@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xmlprivatelibs = @xmlprivatelibs@
+xmlprivatereq = @xmlprivatereq@
+AUTOMAKE_OPTIONS = foreign check-news
+ACLOCAL_AMFLAGS = -I conf -I gl/m4
+aclocaldir = $(datadir)/aclocal
+pkgconfigdir = $(libdir)/pkgconfig
+
+# Arrange to build with the backward compatibility mode enabled.
+AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/GNU 
+# -I$(top_srcdir)/xstream
+AM_CXXFLAGS = $(am__append_1)
+AM_YFLAGS = -d -v
+AM_LFLAGS = -8
+
+# These are not used by automake but are often useful for certain types of
+# debugging. The best way to use these is to run configure as:
+#     export CXXFLAGS='...'; ./configure --disable-shared
+# the --disable-shared is not required, but it seems to help with debuggers.
+CXXFLAGS_DEBUG = -g3 -O0 -fno-defer-pop -Wall -W -Wcast-align -Werror
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+SUBDIRS = gl . tests unit-tests
+DIST_SUBDIRS = unit-tests gl tests
+noinst_LTLIBRARIES = libparsers.la
+lib_LTLIBRARIES = libdap.la libdapclient.la libdapserver.la
+bin_SCRIPTS = dap-config dap-config-pkgconfig
+# fdiostream_test
+
+# sbin_PROGRAMS = deflate
+BUILT_SOURCES = $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h
+libparsers_la_SOURCES = $(GRAM_SRC) 
+libdap_la_SOURCES = $(DAP_SRC) $(GNU_SRC) 
+libdap_la_LDFLAGS = -version-info $(LIBDAP_VERSION)
+libdap_la_CPPFLAGS = $(AM_CPPFLAGS) $(XML2_CFLAGS)
+libdap_la_LIBADD = $(XML2_LIBS) $(PTHREAD_LIBS) gl/libgnu.la libparsers.la
+libdapclient_la_SOURCES = $(CLIENT_SRC) 
+libdapclient_la_LDFLAGS = -version-info $(CLIENTLIB_VERSION)
+libdapclient_la_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS) $(XML2_CFLAGS)
+libdapclient_la_LIBADD = $(CURL_LIBS) libdap.la $(PTHREAD_LIBS)
+libdapserver_la_SOURCES = $(SERVER_SRC)
+libdapserver_la_LDFLAGS = -version-info $(SERVERLIB_VERSION)
+libdapserver_la_LIBADD = libdap.la $(UUID_LIBS)
+pkginclude_HEADERS = $(DAP_HDR) $(GNU_HDR) $(CLIENT_HDR) $(SERVER_HDR) 
+noinst_HEADERS = config_dap.h
+
+# fdiostream_test_SOURCES = GNU/fdiostream_test.cc
+getdap_SOURCES = getdap.cc
+getdap_LDADD = libdapclient.la libdap.la
+getdap_CPPFLAGS = $(AM_CPPFLAGS) $(CURL_CFLAGS)
+LEX_YACC_EXTRA = das.lex das.y dds.lex dds.y ce_expr.lex ce_expr.y gse.lex \
+	gse.y Error.lex Error.y
+
+EXTRA_DIST = ChangeLog COPYING README.dodsrc COPYRIGHT_URI	 \
+	COPYRIGHT_W3C GNU/README doxy.conf doxy_private.conf libdap.spec \
+	VCPP dods-datatypes-static.h xdr-datatypes-static.h \
+	dap-config-pkgconfig $(LEX_YACC_EXTRA) $(GRAM_SRC) OSX_Resources
+
+
+# README.AIS xstream/README 
+dist_aclocal_DATA = conf/libdap.m4
+pkgconfig_DATA = libdap.pc libdapclient.pc libdapserver.pc
+CLEANFILES = *.log *.output *.gcda *.gcno $(GRAM_SRC) dods-datatypes.h xdr-datatypes.h
+grammar_objects = lex.das.o das.tab.o lex.dds.o dds.tab.o lex.ce_expr.o \
+ce_expr.tab.o lex.gse_.o gse.tab.o lex.Error.o Error.tab.o
+
+
+###########################################################################
+
+# Build OS/X Packages. The strange operations with configure and make
+# are there so that the values built into dap-config will match the mac
+# osx install dirs and not the temp directory used to build the packages
+
+# PACKAGEMAKER=/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker*
+PACKAGEMAKER = /Developer/usr/bin/packagemaker
+PKG_CONF_FLAGS = 
+
+#############################################################################
+# Library sources
+# 
+GNU_SRC = GNU/GetOpt.cc GNU/GNURegex.cc
+GNU_HDR = GNU/GetOpt.h GNU/GNURegex.h
+GRAM_SRC = lex.das.cc das.tab.cc das.tab.hh lex.dds.cc dds.tab.cc	\
+	dds.tab.hh lex.ce_expr.cc ce_expr.tab.cc ce_expr.tab.hh		\
+	lex.Error.cc Error.tab.cc Error.tab.hh gse.tab.hh gse.tab.cc	\
+	lex.gse_.cc
+
+DAP_SRC = AttrTable.cc DAS.cc DDS.cc DataDDS.cc DDXParserSAX2.cc	\
+	BaseType.cc Byte.cc Int32.cc Float64.cc Str.cc Url.cc		\
+	Vector.cc Array.cc Structure.cc Sequence.cc Grid.cc UInt32.cc	\
+	Int16.cc UInt16.cc Float32.cc Constructor.cc			\
+	BaseTypeFactory.cc SignalHandler.cc Error.cc InternalErr.cc	\
+	util.cc xdrutil_ppc.c parser-util.cc escaping.cc		\
+	ce_functions.cc GSEClause.cc GeoConstraint.cc			\
+	GridGeoConstraint.cc Clause.cc RValue.cc			\
+	ConstraintEvaluator.cc ArrayGeoConstraint.cc DapIndent.cc	\
+	Operators.h XDRUtils.cc XDRFileMarshaller.cc			\
+	XDRFileUnMarshaller.cc XDRStreamMarshaller.cc			\
+	XDRStreamUnMarshaller.cc mime_util.cc Keywords2.cc
+
+
+# Operators.h is included in with the source to prevent it from bing installed
+# with the other headers. It includes one of the built grammar file headers.
+CLIENT_SRC = RCReader.cc Connect.cc HTTPConnect.cc HTTPCache.cc	\
+	util_mit.cc ResponseTooBigErr.cc HTTPCacheTable.cc
+
+SERVER_SRC = DODSFilter.cc Ancillary.cc ResponseBuilder.cc
+DAP_HDR = AttrTable.h DAS.h DDS.h DataDDS.h DDXParserSAX2.h		\
+	DDXExceptions.h BaseType.h Byte.h Int32.h Float64.h Str.h	\
+	Url.h Vector.h Array.h Constructor.h Structure.h Sequence.h	\
+	Grid.h UInt32.h Int16.h UInt16.h Float32.h BaseTypeFactory.h	\
+	ObjectType.h EncodingType.h SignalHandler.h Error.h		\
+	InternalErr.h util.h escaping.h parser.h debug.h dods-limits.h	\
+	dods-datatypes.h GeoConstraint.h GridGeoConstraint.h		\
+	ArrayGeoConstraint.h ce_functions.h gse_parser.h GSEClause.h	\
+	util_mit.h expr.h Clause.h RValue.h ConstraintEvaluator.h	\
+	ce_parser.h DapIndent.h DapObj.h XDRFileMarshaller.h		\
+	Marshaller.h XDRFileUnMarshaller.h UnMarshaller.h		\
+	XDRStreamMarshaller.h XDRUtils.h xdr-datatypes.h mime_util.h	\
+	cgi_util.h XDRStreamUnMarshaller.h Keywords2.h
+
+CLIENT_HDR = RCReader.h Connect.h HTTPConnect.h HTTPCache.h		\
+	HTTPCacheDisconnectedMode.h HTTPCacheInterruptHandler.h		\
+	Response.h HTTPResponse.h HTTPCacheResponse.h PipeResponse.h	\
+	StdinResponse.h SignalHandlerRegisteredErr.h			\
+	ResponseTooBigErr.h Resource.h HTTPCacheTable.h
+
+SERVER_HDR = DODSFilter.h AlarmHandler.h EventHandler.h Ancillary.h	\
+	ResponseBuilder.h
+
+all: $(BUILT_SOURCES) config.h dods-datatypes-config.h xdr-datatypes-config.h
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+am--refresh:
+	@:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+	      $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+		&& exit 0; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    echo ' $(SHELL) ./config.status'; \
+	    $(SHELL) ./config.status;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	$(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	$(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+
+config.h: stamp-h1
+	@if test ! -f $@; then \
+	  rm -f stamp-h1; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
+	else :; fi
+
+stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h1
+	cd $(top_builddir) && $(SHELL) ./config.status config.h
+$(srcdir)/config.h.in:  $(am__configure_deps) 
+	($(am__cd) $(top_srcdir) && $(AUTOHEADER))
+	rm -f stamp-h1
+	touch $@
+
+dods-datatypes-config.h: stamp-h2
+	@if test ! -f $@; then \
+	  rm -f stamp-h2; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h2; \
+	else :; fi
+
+stamp-h2: $(srcdir)/dods-datatypes-config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h2
+	cd $(top_builddir) && $(SHELL) ./config.status dods-datatypes-config.h
+
+xdr-datatypes-config.h: stamp-h3
+	@if test ! -f $@; then \
+	  rm -f stamp-h3; \
+	  $(MAKE) $(AM_MAKEFLAGS) stamp-h3; \
+	else :; fi
+
+stamp-h3: $(srcdir)/xdr-datatypes-config.h.in $(top_builddir)/config.status
+	@rm -f stamp-h3
+	cd $(top_builddir) && $(SHELL) ./config.status xdr-datatypes-config.h
+
+distclean-hdr:
+	-rm -f config.h stamp-h1 dods-datatypes-config.h stamp-h2 xdr-datatypes-config.h stamp-h3
+libdap.pc: $(top_builddir)/config.status $(srcdir)/libdap.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+libdapclient.pc: $(top_builddir)/config.status $(srcdir)/libdapclient.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+libdapserver.pc: $(top_builddir)/config.status $(srcdir)/libdapserver.pc.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+dap-config: $(top_builddir)/config.status $(srcdir)/dap-config.in
+	cd $(top_builddir) && $(SHELL) ./config.status $@
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+	@$(NORMAL_INSTALL)
+	test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	list2=; for p in $$list; do \
+	  if test -f $$p; then \
+	    list2="$$list2 $$p"; \
+	  else :; fi; \
+	done; \
+	test -z "$$list2" || { \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
+	}
+
+uninstall-libLTLIBRARIES:
+	@$(NORMAL_UNINSTALL)
+	@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
+	for p in $$list; do \
+	  $(am__strip_dir) \
+	  echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
+	  $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
+	done
+
+clean-libLTLIBRARIES:
+	-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+	@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libdap.la: $(libdap_la_OBJECTS) $(libdap_la_DEPENDENCIES) 
+	$(libdap_la_LINK) -rpath $(libdir) $(libdap_la_OBJECTS) $(libdap_la_LIBADD) $(LIBS)
+libdapclient.la: $(libdapclient_la_OBJECTS) $(libdapclient_la_DEPENDENCIES) 
+	$(libdapclient_la_LINK) -rpath $(libdir) $(libdapclient_la_OBJECTS) $(libdapclient_la_LIBADD) $(LIBS)
+libdapserver.la: $(libdapserver_la_OBJECTS) $(libdapserver_la_DEPENDENCIES) 
+	$(libdapserver_la_LINK) -rpath $(libdir) $(libdapserver_la_OBJECTS) $(libdapserver_la_LIBADD) $(LIBS)
+libparsers.la: $(libparsers_la_OBJECTS) $(libparsers_la_DEPENDENCIES) 
+	$(CXXLINK)  $(libparsers_la_OBJECTS) $(libparsers_la_LIBADD) $(LIBS)
+install-binPROGRAMS: $(bin_PROGRAMS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do echo "$$p $$p"; done | \
+	sed 's/$(EXEEXT)$$//' | \
+	while read p p1; do if test -f $$p || test -f $$p1; \
+	  then echo "$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
+	    -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
+	sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) files[d] = files[d] " " $$1; \
+	    else { print "f", $$3 "/" $$4, $$1; } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	    if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	    test -z "$$files" || { \
+	    echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	    $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	    } \
+	; done
+
+uninstall-binPROGRAMS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	  sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
+	      -e 's/$$/$(EXEEXT)/' `; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+clean-binPROGRAMS:
+	@list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+getdap$(EXEEXT): $(getdap_OBJECTS) $(getdap_DEPENDENCIES) 
+	@rm -f getdap$(EXEEXT)
+	$(CXXLINK) $(getdap_OBJECTS) $(getdap_LDADD) $(LIBS)
+install-binSCRIPTS: $(bin_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
+	done | \
+	sed -e 'p;s,.*/,,;n' \
+	    -e 'h;s|.*|.|' \
+	    -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
+	$(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
+	  { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
+	    if ($$2 == $$4) { files[d] = files[d] " " $$1; \
+	      if (++n[d] == $(am__install_max)) { \
+		print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
+	    else { print "f", d "/" $$4, $$1 } } \
+	  END { for (d in files) print "f", d, files[d] }' | \
+	while read type dir files; do \
+	     if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
+	     test -z "$$files" || { \
+	       echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
+	       $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
+	     } \
+	; done
+
+uninstall-binSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
+	files=`for p in $$list; do echo "$$p"; done | \
+	       sed -e 's,.*/,,;$(transform)'`; \
+	test -n "$$list" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(bindir)" && rm -f $$files
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Ancillary.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DODSFilter.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Error.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ResponseBuilder.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ce_expr.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/das.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dds.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/getdap-getdap.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gse.tab.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lex.Error.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lex.ce_expr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lex.das.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lex.dds.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/lex.gse_.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Array.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-ArrayGeoConstraint.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-AttrTable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-BaseType.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-BaseTypeFactory.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Byte.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Clause.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-ConstraintEvaluator.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Constructor.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DAS.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DDS.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DDXParserSAX2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DapIndent.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-DataDDS.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Error.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Float32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Float64.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-GNURegex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-GSEClause.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-GeoConstraint.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-GetOpt.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Grid.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-GridGeoConstraint.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Int16.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Int32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-InternalErr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Keywords2.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-RValue.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Sequence.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-SignalHandler.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Str.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Structure.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-UInt16.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-UInt32.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Url.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-Vector.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRFileMarshaller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRFileUnMarshaller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRStreamMarshaller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRStreamUnMarshaller.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-XDRUtils.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-ce_functions.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-escaping.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-mime_util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-parser-util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-util.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdap_la-xdrutil_ppc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-Connect.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-HTTPCache.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-HTTPCacheTable.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-HTTPConnect.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-RCReader.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-ResponseTooBigErr.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/libdapclient_la-util_mit.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+libdap_la-xdrutil_ppc.lo: xdrutil_ppc.c
+ at am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libdap_la-xdrutil_ppc.lo -MD -MP -MF $(DEPDIR)/libdap_la-xdrutil_ppc.Tpo -c -o libdap_la-xdrutil_ppc.lo `test -f 'xdrutil_ppc.c' || echo '$(srcdir)/'`xdrutil_ppc.c
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-xdrutil_ppc.Tpo $(DEPDIR)/libdap_la-xdrutil_ppc.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='xdrutil_ppc.c' object='libdap_la-xdrutil_ppc.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libdap_la-xdrutil_ppc.lo `test -f 'xdrutil_ppc.c' || echo '$(srcdir)/'`xdrutil_ppc.c
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
+
+libdap_la-AttrTable.lo: AttrTable.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-AttrTable.lo -MD -MP -MF $(DEPDIR)/libdap_la-AttrTable.Tpo -c -o libdap_la-AttrTable.lo `test -f 'AttrTable.cc' || echo '$(srcdir)/'`AttrTable.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-AttrTable.Tpo $(DEPDIR)/libdap_la-AttrTable.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='AttrTable.cc' object='libdap_la-AttrTable.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-AttrTable.lo `test -f 'AttrTable.cc' || echo '$(srcdir)/'`AttrTable.cc
+
+libdap_la-DAS.lo: DAS.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-DAS.lo -MD -MP -MF $(DEPDIR)/libdap_la-DAS.Tpo -c -o libdap_la-DAS.lo `test -f 'DAS.cc' || echo '$(srcdir)/'`DAS.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DAS.Tpo $(DEPDIR)/libdap_la-DAS.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DAS.cc' object='libdap_la-DAS.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-DAS.lo `test -f 'DAS.cc' || echo '$(srcdir)/'`DAS.cc
+
+libdap_la-DDS.lo: DDS.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-DDS.lo -MD -MP -MF $(DEPDIR)/libdap_la-DDS.Tpo -c -o libdap_la-DDS.lo `test -f 'DDS.cc' || echo '$(srcdir)/'`DDS.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DDS.Tpo $(DEPDIR)/libdap_la-DDS.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DDS.cc' object='libdap_la-DDS.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-DDS.lo `test -f 'DDS.cc' || echo '$(srcdir)/'`DDS.cc
+
+libdap_la-DataDDS.lo: DataDDS.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-DataDDS.lo -MD -MP -MF $(DEPDIR)/libdap_la-DataDDS.Tpo -c -o libdap_la-DataDDS.lo `test -f 'DataDDS.cc' || echo '$(srcdir)/'`DataDDS.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DataDDS.Tpo $(DEPDIR)/libdap_la-DataDDS.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DataDDS.cc' object='libdap_la-DataDDS.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-DataDDS.lo `test -f 'DataDDS.cc' || echo '$(srcdir)/'`DataDDS.cc
+
+libdap_la-DDXParserSAX2.lo: DDXParserSAX2.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-DDXParserSAX2.lo -MD -MP -MF $(DEPDIR)/libdap_la-DDXParserSAX2.Tpo -c -o libdap_la-DDXParserSAX2.lo `test -f 'DDXParserSAX2.cc' || echo '$(srcdir)/'`DDXParserSAX2.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DDXParserSAX2.Tpo $(DEPDIR)/libdap_la-DDXParserSAX2.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DDXParserSAX2.cc' object='libdap_la-DDXParserSAX2.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-DDXParserSAX2.lo `test -f 'DDXParserSAX2.cc' || echo '$(srcdir)/'`DDXParserSAX2.cc
+
+libdap_la-BaseType.lo: BaseType.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-BaseType.lo -MD -MP -MF $(DEPDIR)/libdap_la-BaseType.Tpo -c -o libdap_la-BaseType.lo `test -f 'BaseType.cc' || echo '$(srcdir)/'`BaseType.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-BaseType.Tpo $(DEPDIR)/libdap_la-BaseType.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='BaseType.cc' object='libdap_la-BaseType.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-BaseType.lo `test -f 'BaseType.cc' || echo '$(srcdir)/'`BaseType.cc
+
+libdap_la-Byte.lo: Byte.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Byte.lo -MD -MP -MF $(DEPDIR)/libdap_la-Byte.Tpo -c -o libdap_la-Byte.lo `test -f 'Byte.cc' || echo '$(srcdir)/'`Byte.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Byte.Tpo $(DEPDIR)/libdap_la-Byte.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Byte.cc' object='libdap_la-Byte.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Byte.lo `test -f 'Byte.cc' || echo '$(srcdir)/'`Byte.cc
+
+libdap_la-Int32.lo: Int32.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Int32.lo -MD -MP -MF $(DEPDIR)/libdap_la-Int32.Tpo -c -o libdap_la-Int32.lo `test -f 'Int32.cc' || echo '$(srcdir)/'`Int32.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Int32.Tpo $(DEPDIR)/libdap_la-Int32.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Int32.cc' object='libdap_la-Int32.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Int32.lo `test -f 'Int32.cc' || echo '$(srcdir)/'`Int32.cc
+
+libdap_la-Float64.lo: Float64.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Float64.lo -MD -MP -MF $(DEPDIR)/libdap_la-Float64.Tpo -c -o libdap_la-Float64.lo `test -f 'Float64.cc' || echo '$(srcdir)/'`Float64.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Float64.Tpo $(DEPDIR)/libdap_la-Float64.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Float64.cc' object='libdap_la-Float64.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Float64.lo `test -f 'Float64.cc' || echo '$(srcdir)/'`Float64.cc
+
+libdap_la-Str.lo: Str.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Str.lo -MD -MP -MF $(DEPDIR)/libdap_la-Str.Tpo -c -o libdap_la-Str.lo `test -f 'Str.cc' || echo '$(srcdir)/'`Str.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Str.Tpo $(DEPDIR)/libdap_la-Str.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Str.cc' object='libdap_la-Str.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Str.lo `test -f 'Str.cc' || echo '$(srcdir)/'`Str.cc
+
+libdap_la-Url.lo: Url.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Url.lo -MD -MP -MF $(DEPDIR)/libdap_la-Url.Tpo -c -o libdap_la-Url.lo `test -f 'Url.cc' || echo '$(srcdir)/'`Url.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Url.Tpo $(DEPDIR)/libdap_la-Url.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Url.cc' object='libdap_la-Url.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Url.lo `test -f 'Url.cc' || echo '$(srcdir)/'`Url.cc
+
+libdap_la-Vector.lo: Vector.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Vector.lo -MD -MP -MF $(DEPDIR)/libdap_la-Vector.Tpo -c -o libdap_la-Vector.lo `test -f 'Vector.cc' || echo '$(srcdir)/'`Vector.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Vector.Tpo $(DEPDIR)/libdap_la-Vector.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Vector.cc' object='libdap_la-Vector.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Vector.lo `test -f 'Vector.cc' || echo '$(srcdir)/'`Vector.cc
+
+libdap_la-Array.lo: Array.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Array.lo -MD -MP -MF $(DEPDIR)/libdap_la-Array.Tpo -c -o libdap_la-Array.lo `test -f 'Array.cc' || echo '$(srcdir)/'`Array.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Array.Tpo $(DEPDIR)/libdap_la-Array.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Array.cc' object='libdap_la-Array.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Array.lo `test -f 'Array.cc' || echo '$(srcdir)/'`Array.cc
+
+libdap_la-Structure.lo: Structure.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Structure.lo -MD -MP -MF $(DEPDIR)/libdap_la-Structure.Tpo -c -o libdap_la-Structure.lo `test -f 'Structure.cc' || echo '$(srcdir)/'`Structure.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Structure.Tpo $(DEPDIR)/libdap_la-Structure.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Structure.cc' object='libdap_la-Structure.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Structure.lo `test -f 'Structure.cc' || echo '$(srcdir)/'`Structure.cc
+
+libdap_la-Sequence.lo: Sequence.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Sequence.lo -MD -MP -MF $(DEPDIR)/libdap_la-Sequence.Tpo -c -o libdap_la-Sequence.lo `test -f 'Sequence.cc' || echo '$(srcdir)/'`Sequence.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Sequence.Tpo $(DEPDIR)/libdap_la-Sequence.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Sequence.cc' object='libdap_la-Sequence.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Sequence.lo `test -f 'Sequence.cc' || echo '$(srcdir)/'`Sequence.cc
+
+libdap_la-Grid.lo: Grid.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Grid.lo -MD -MP -MF $(DEPDIR)/libdap_la-Grid.Tpo -c -o libdap_la-Grid.lo `test -f 'Grid.cc' || echo '$(srcdir)/'`Grid.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Grid.Tpo $(DEPDIR)/libdap_la-Grid.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Grid.cc' object='libdap_la-Grid.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Grid.lo `test -f 'Grid.cc' || echo '$(srcdir)/'`Grid.cc
+
+libdap_la-UInt32.lo: UInt32.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-UInt32.lo -MD -MP -MF $(DEPDIR)/libdap_la-UInt32.Tpo -c -o libdap_la-UInt32.lo `test -f 'UInt32.cc' || echo '$(srcdir)/'`UInt32.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-UInt32.Tpo $(DEPDIR)/libdap_la-UInt32.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='UInt32.cc' object='libdap_la-UInt32.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-UInt32.lo `test -f 'UInt32.cc' || echo '$(srcdir)/'`UInt32.cc
+
+libdap_la-Int16.lo: Int16.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Int16.lo -MD -MP -MF $(DEPDIR)/libdap_la-Int16.Tpo -c -o libdap_la-Int16.lo `test -f 'Int16.cc' || echo '$(srcdir)/'`Int16.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Int16.Tpo $(DEPDIR)/libdap_la-Int16.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Int16.cc' object='libdap_la-Int16.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Int16.lo `test -f 'Int16.cc' || echo '$(srcdir)/'`Int16.cc
+
+libdap_la-UInt16.lo: UInt16.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-UInt16.lo -MD -MP -MF $(DEPDIR)/libdap_la-UInt16.Tpo -c -o libdap_la-UInt16.lo `test -f 'UInt16.cc' || echo '$(srcdir)/'`UInt16.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-UInt16.Tpo $(DEPDIR)/libdap_la-UInt16.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='UInt16.cc' object='libdap_la-UInt16.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-UInt16.lo `test -f 'UInt16.cc' || echo '$(srcdir)/'`UInt16.cc
+
+libdap_la-Float32.lo: Float32.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Float32.lo -MD -MP -MF $(DEPDIR)/libdap_la-Float32.Tpo -c -o libdap_la-Float32.lo `test -f 'Float32.cc' || echo '$(srcdir)/'`Float32.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Float32.Tpo $(DEPDIR)/libdap_la-Float32.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Float32.cc' object='libdap_la-Float32.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Float32.lo `test -f 'Float32.cc' || echo '$(srcdir)/'`Float32.cc
+
+libdap_la-Constructor.lo: Constructor.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Constructor.lo -MD -MP -MF $(DEPDIR)/libdap_la-Constructor.Tpo -c -o libdap_la-Constructor.lo `test -f 'Constructor.cc' || echo '$(srcdir)/'`Constructor.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Constructor.Tpo $(DEPDIR)/libdap_la-Constructor.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Constructor.cc' object='libdap_la-Constructor.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Constructor.lo `test -f 'Constructor.cc' || echo '$(srcdir)/'`Constructor.cc
+
+libdap_la-BaseTypeFactory.lo: BaseTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-BaseTypeFactory.lo -MD -MP -MF $(DEPDIR)/libdap_la-BaseTypeFactory.Tpo -c -o libdap_la-BaseTypeFactory.lo `test -f 'BaseTypeFactory.cc' || echo '$(srcdir)/'`BaseTypeFactory.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-BaseTypeFactory.Tpo $(DEPDIR)/libdap_la-BaseTypeFactory.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='BaseTypeFactory.cc' object='libdap_la-BaseTypeFactory.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-BaseTypeFactory.lo `test -f 'BaseTypeFactory.cc' || echo '$(srcdir)/'`BaseTypeFactory.cc
+
+libdap_la-SignalHandler.lo: SignalHandler.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-SignalHandler.lo -MD -MP -MF $(DEPDIR)/libdap_la-SignalHandler.Tpo -c -o libdap_la-SignalHandler.lo `test -f 'SignalHandler.cc' || echo '$(srcdir)/'`SignalHandler.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-SignalHandler.Tpo $(DEPDIR)/libdap_la-SignalHandler.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='SignalHandler.cc' object='libdap_la-SignalHandler.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-SignalHandler.lo `test -f 'SignalHandler.cc' || echo '$(srcdir)/'`SignalHandler.cc
+
+libdap_la-Error.lo: Error.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Error.lo -MD -MP -MF $(DEPDIR)/libdap_la-Error.Tpo -c -o libdap_la-Error.lo `test -f 'Error.cc' || echo '$(srcdir)/'`Error.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Error.Tpo $(DEPDIR)/libdap_la-Error.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Error.cc' object='libdap_la-Error.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Error.lo `test -f 'Error.cc' || echo '$(srcdir)/'`Error.cc
+
+libdap_la-InternalErr.lo: InternalErr.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-InternalErr.lo -MD -MP -MF $(DEPDIR)/libdap_la-InternalErr.Tpo -c -o libdap_la-InternalErr.lo `test -f 'InternalErr.cc' || echo '$(srcdir)/'`InternalErr.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-InternalErr.Tpo $(DEPDIR)/libdap_la-InternalErr.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='InternalErr.cc' object='libdap_la-InternalErr.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-InternalErr.lo `test -f 'InternalErr.cc' || echo '$(srcdir)/'`InternalErr.cc
+
+libdap_la-util.lo: util.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-util.lo -MD -MP -MF $(DEPDIR)/libdap_la-util.Tpo -c -o libdap_la-util.lo `test -f 'util.cc' || echo '$(srcdir)/'`util.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-util.Tpo $(DEPDIR)/libdap_la-util.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='util.cc' object='libdap_la-util.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-util.lo `test -f 'util.cc' || echo '$(srcdir)/'`util.cc
+
+libdap_la-parser-util.lo: parser-util.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-parser-util.lo -MD -MP -MF $(DEPDIR)/libdap_la-parser-util.Tpo -c -o libdap_la-parser-util.lo `test -f 'parser-util.cc' || echo '$(srcdir)/'`parser-util.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-parser-util.Tpo $(DEPDIR)/libdap_la-parser-util.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='parser-util.cc' object='libdap_la-parser-util.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-parser-util.lo `test -f 'parser-util.cc' || echo '$(srcdir)/'`parser-util.cc
+
+libdap_la-escaping.lo: escaping.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-escaping.lo -MD -MP -MF $(DEPDIR)/libdap_la-escaping.Tpo -c -o libdap_la-escaping.lo `test -f 'escaping.cc' || echo '$(srcdir)/'`escaping.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-escaping.Tpo $(DEPDIR)/libdap_la-escaping.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='escaping.cc' object='libdap_la-escaping.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-escaping.lo `test -f 'escaping.cc' || echo '$(srcdir)/'`escaping.cc
+
+libdap_la-ce_functions.lo: ce_functions.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-ce_functions.lo -MD -MP -MF $(DEPDIR)/libdap_la-ce_functions.Tpo -c -o libdap_la-ce_functions.lo `test -f 'ce_functions.cc' || echo '$(srcdir)/'`ce_functions.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-ce_functions.Tpo $(DEPDIR)/libdap_la-ce_functions.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='ce_functions.cc' object='libdap_la-ce_functions.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-ce_functions.lo `test -f 'ce_functions.cc' || echo '$(srcdir)/'`ce_functions.cc
+
+libdap_la-GSEClause.lo: GSEClause.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-GSEClause.lo -MD -MP -MF $(DEPDIR)/libdap_la-GSEClause.Tpo -c -o libdap_la-GSEClause.lo `test -f 'GSEClause.cc' || echo '$(srcdir)/'`GSEClause.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-GSEClause.Tpo $(DEPDIR)/libdap_la-GSEClause.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GSEClause.cc' object='libdap_la-GSEClause.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-GSEClause.lo `test -f 'GSEClause.cc' || echo '$(srcdir)/'`GSEClause.cc
+
+libdap_la-GeoConstraint.lo: GeoConstraint.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-GeoConstraint.lo -MD -MP -MF $(DEPDIR)/libdap_la-GeoConstraint.Tpo -c -o libdap_la-GeoConstraint.lo `test -f 'GeoConstraint.cc' || echo '$(srcdir)/'`GeoConstraint.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-GeoConstraint.Tpo $(DEPDIR)/libdap_la-GeoConstraint.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GeoConstraint.cc' object='libdap_la-GeoConstraint.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-GeoConstraint.lo `test -f 'GeoConstraint.cc' || echo '$(srcdir)/'`GeoConstraint.cc
+
+libdap_la-GridGeoConstraint.lo: GridGeoConstraint.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-GridGeoConstraint.lo -MD -MP -MF $(DEPDIR)/libdap_la-GridGeoConstraint.Tpo -c -o libdap_la-GridGeoConstraint.lo `test -f 'GridGeoConstraint.cc' || echo '$(srcdir)/'`GridGeoConstraint.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-GridGeoConstraint.Tpo $(DEPDIR)/libdap_la-GridGeoConstraint.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GridGeoConstraint.cc' object='libdap_la-GridGeoConstraint.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-GridGeoConstraint.lo `test -f 'GridGeoConstraint.cc' || echo '$(srcdir)/'`GridGeoConstraint.cc
+
+libdap_la-Clause.lo: Clause.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Clause.lo -MD -MP -MF $(DEPDIR)/libdap_la-Clause.Tpo -c -o libdap_la-Clause.lo `test -f 'Clause.cc' || echo '$(srcdir)/'`Clause.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Clause.Tpo $(DEPDIR)/libdap_la-Clause.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Clause.cc' object='libdap_la-Clause.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Clause.lo `test -f 'Clause.cc' || echo '$(srcdir)/'`Clause.cc
+
+libdap_la-RValue.lo: RValue.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-RValue.lo -MD -MP -MF $(DEPDIR)/libdap_la-RValue.Tpo -c -o libdap_la-RValue.lo `test -f 'RValue.cc' || echo '$(srcdir)/'`RValue.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-RValue.Tpo $(DEPDIR)/libdap_la-RValue.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='RValue.cc' object='libdap_la-RValue.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-RValue.lo `test -f 'RValue.cc' || echo '$(srcdir)/'`RValue.cc
+
+libdap_la-ConstraintEvaluator.lo: ConstraintEvaluator.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-ConstraintEvaluator.lo -MD -MP -MF $(DEPDIR)/libdap_la-ConstraintEvaluator.Tpo -c -o libdap_la-ConstraintEvaluator.lo `test -f 'ConstraintEvaluator.cc' || echo '$(srcdir)/'`ConstraintEvaluator.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-ConstraintEvaluator.Tpo $(DEPDIR)/libdap_la-ConstraintEvaluator.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='ConstraintEvaluator.cc' object='libdap_la-ConstraintEvaluator.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-ConstraintEvaluator.lo `test -f 'ConstraintEvaluator.cc' || echo '$(srcdir)/'`ConstraintEvaluator.cc
+
+libdap_la-ArrayGeoConstraint.lo: ArrayGeoConstraint.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-ArrayGeoConstraint.lo -MD -MP -MF $(DEPDIR)/libdap_la-ArrayGeoConstraint.Tpo -c -o libdap_la-ArrayGeoConstraint.lo `test -f 'ArrayGeoConstraint.cc' || echo '$(srcdir)/'`ArrayGeoConstraint.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-ArrayGeoConstraint.Tpo $(DEPDIR)/libdap_la-ArrayGeoConstraint.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='ArrayGeoConstraint.cc' object='libdap_la-ArrayGeoConstraint.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-ArrayGeoConstraint.lo `test -f 'ArrayGeoConstraint.cc' || echo '$(srcdir)/'`ArrayGeoConstraint.cc
+
+libdap_la-DapIndent.lo: DapIndent.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-DapIndent.lo -MD -MP -MF $(DEPDIR)/libdap_la-DapIndent.Tpo -c -o libdap_la-DapIndent.lo `test -f 'DapIndent.cc' || echo '$(srcdir)/'`DapIndent.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-DapIndent.Tpo $(DEPDIR)/libdap_la-DapIndent.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DapIndent.cc' object='libdap_la-DapIndent.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-DapIndent.lo `test -f 'DapIndent.cc' || echo '$(srcdir)/'`DapIndent.cc
+
+libdap_la-XDRUtils.lo: XDRUtils.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-XDRUtils.lo -MD -MP -MF $(DEPDIR)/libdap_la-XDRUtils.Tpo -c -o libdap_la-XDRUtils.lo `test -f 'XDRUtils.cc' || echo '$(srcdir)/'`XDRUtils.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-XDRUtils.Tpo $(DEPDIR)/libdap_la-XDRUtils.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='XDRUtils.cc' object='libdap_la-XDRUtils.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-XDRUtils.lo `test -f 'XDRUtils.cc' || echo '$(srcdir)/'`XDRUtils.cc
+
+libdap_la-XDRFileMarshaller.lo: XDRFileMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-XDRFileMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-XDRFileMarshaller.Tpo -c -o libdap_la-XDRFileMarshaller.lo `test -f 'XDRFileMarshaller.cc' || echo '$(srcdir)/'`XDRFileMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-XDRFileMarshaller.Tpo $(DEPDIR)/libdap_la-XDRFileMarshaller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='XDRFileMarshaller.cc' object='libdap_la-XDRFileMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-XDRFileMarshaller.lo `test -f 'XDRFileMarshaller.cc' || echo '$(srcdir)/'`XDRFileMarshaller.cc
+
+libdap_la-XDRFileUnMarshaller.lo: XDRFileUnMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-XDRFileUnMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-XDRFileUnMarshaller.Tpo -c -o libdap_la-XDRFileUnMarshaller.lo `test -f 'XDRFileUnMarshaller.cc' || echo '$(srcdir)/'`XDRFileUnMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-XDRFileUnMarshaller.Tpo $(DEPDIR)/libdap_la-XDRFileUnMarshaller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='XDRFileUnMarshaller.cc' object='libdap_la-XDRFileUnMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-XDRFileUnMarshaller.lo `test -f 'XDRFileUnMarshaller.cc' || echo '$(srcdir)/'`XDRFileUnMarshaller.cc
+
+libdap_la-XDRStreamMarshaller.lo: XDRStreamMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-XDRStreamMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-XDRStreamMarshaller.Tpo -c -o libdap_la-XDRStreamMarshaller.lo `test -f 'XDRStreamMarshaller.cc' || echo '$(srcdir)/'`XDRStreamMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-XDRStreamMarshaller.Tpo $(DEPDIR)/libdap_la-XDRStreamMarshaller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='XDRStreamMarshaller.cc' object='libdap_la-XDRStreamMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-XDRStreamMarshaller.lo `test -f 'XDRStreamMarshaller.cc' || echo '$(srcdir)/'`XDRStreamMarshaller.cc
+
+libdap_la-XDRStreamUnMarshaller.lo: XDRStreamUnMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-XDRStreamUnMarshaller.lo -MD -MP -MF $(DEPDIR)/libdap_la-XDRStreamUnMarshaller.Tpo -c -o libdap_la-XDRStreamUnMarshaller.lo `test -f 'XDRStreamUnMarshaller.cc' || echo '$(srcdir)/'`XDRStreamUnMarshaller.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-XDRStreamUnMarshaller.Tpo $(DEPDIR)/libdap_la-XDRStreamUnMarshaller.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='XDRStreamUnMarshaller.cc' object='libdap_la-XDRStreamUnMarshaller.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-XDRStreamUnMarshaller.lo `test -f 'XDRStreamUnMarshaller.cc' || echo '$(srcdir)/'`XDRStreamUnMarshaller.cc
+
+libdap_la-mime_util.lo: mime_util.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-mime_util.lo -MD -MP -MF $(DEPDIR)/libdap_la-mime_util.Tpo -c -o libdap_la-mime_util.lo `test -f 'mime_util.cc' || echo '$(srcdir)/'`mime_util.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-mime_util.Tpo $(DEPDIR)/libdap_la-mime_util.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='mime_util.cc' object='libdap_la-mime_util.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-mime_util.lo `test -f 'mime_util.cc' || echo '$(srcdir)/'`mime_util.cc
+
+libdap_la-Keywords2.lo: Keywords2.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-Keywords2.lo -MD -MP -MF $(DEPDIR)/libdap_la-Keywords2.Tpo -c -o libdap_la-Keywords2.lo `test -f 'Keywords2.cc' || echo '$(srcdir)/'`Keywords2.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-Keywords2.Tpo $(DEPDIR)/libdap_la-Keywords2.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Keywords2.cc' object='libdap_la-Keywords2.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-Keywords2.lo `test -f 'Keywords2.cc' || echo '$(srcdir)/'`Keywords2.cc
+
+libdap_la-GetOpt.lo: GNU/GetOpt.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-GetOpt.lo -MD -MP -MF $(DEPDIR)/libdap_la-GetOpt.Tpo -c -o libdap_la-GetOpt.lo `test -f 'GNU/GetOpt.cc' || echo '$(srcdir)/'`GNU/GetOpt.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-GetOpt.Tpo $(DEPDIR)/libdap_la-GetOpt.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GNU/GetOpt.cc' object='libdap_la-GetOpt.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-GetOpt.lo `test -f 'GNU/GetOpt.cc' || echo '$(srcdir)/'`GNU/GetOpt.cc
+
+libdap_la-GNURegex.lo: GNU/GNURegex.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdap_la-GNURegex.lo -MD -MP -MF $(DEPDIR)/libdap_la-GNURegex.Tpo -c -o libdap_la-GNURegex.lo `test -f 'GNU/GNURegex.cc' || echo '$(srcdir)/'`GNU/GNURegex.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdap_la-GNURegex.Tpo $(DEPDIR)/libdap_la-GNURegex.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='GNU/GNURegex.cc' object='libdap_la-GNURegex.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdap_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdap_la-GNURegex.lo `test -f 'GNU/GNURegex.cc' || echo '$(srcdir)/'`GNU/GNURegex.cc
+
+libdapclient_la-RCReader.lo: RCReader.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-RCReader.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-RCReader.Tpo -c -o libdapclient_la-RCReader.lo `test -f 'RCReader.cc' || echo '$(srcdir)/'`RCReader.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-RCReader.Tpo $(DEPDIR)/libdapclient_la-RCReader.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='RCReader.cc' object='libdapclient_la-RCReader.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-RCReader.lo `test -f 'RCReader.cc' || echo '$(srcdir)/'`RCReader.cc
+
+libdapclient_la-Connect.lo: Connect.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-Connect.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-Connect.Tpo -c -o libdapclient_la-Connect.lo `test -f 'Connect.cc' || echo '$(srcdir)/'`Connect.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-Connect.Tpo $(DEPDIR)/libdapclient_la-Connect.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='Connect.cc' object='libdapclient_la-Connect.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-Connect.lo `test -f 'Connect.cc' || echo '$(srcdir)/'`Connect.cc
+
+libdapclient_la-HTTPConnect.lo: HTTPConnect.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-HTTPConnect.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-HTTPConnect.Tpo -c -o libdapclient_la-HTTPConnect.lo `test -f 'HTTPConnect.cc' || echo '$(srcdir)/'`HTTPConnect.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-HTTPConnect.Tpo $(DEPDIR)/libdapclient_la-HTTPConnect.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='HTTPConnect.cc' object='libdapclient_la-HTTPConnect.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-HTTPConnect.lo `test -f 'HTTPConnect.cc' || echo '$(srcdir)/'`HTTPConnect.cc
+
+libdapclient_la-HTTPCache.lo: HTTPCache.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-HTTPCache.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-HTTPCache.Tpo -c -o libdapclient_la-HTTPCache.lo `test -f 'HTTPCache.cc' || echo '$(srcdir)/'`HTTPCache.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-HTTPCache.Tpo $(DEPDIR)/libdapclient_la-HTTPCache.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='HTTPCache.cc' object='libdapclient_la-HTTPCache.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-HTTPCache.lo `test -f 'HTTPCache.cc' || echo '$(srcdir)/'`HTTPCache.cc
+
+libdapclient_la-util_mit.lo: util_mit.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-util_mit.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-util_mit.Tpo -c -o libdapclient_la-util_mit.lo `test -f 'util_mit.cc' || echo '$(srcdir)/'`util_mit.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-util_mit.Tpo $(DEPDIR)/libdapclient_la-util_mit.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='util_mit.cc' object='libdapclient_la-util_mit.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-util_mit.lo `test -f 'util_mit.cc' || echo '$(srcdir)/'`util_mit.cc
+
+libdapclient_la-ResponseTooBigErr.lo: ResponseTooBigErr.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-ResponseTooBigErr.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-ResponseTooBigErr.Tpo -c -o libdapclient_la-ResponseTooBigErr.lo `test -f 'ResponseTooBigErr.cc' || echo '$(srcdir)/'`ResponseTooBigErr.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-ResponseTooBigErr.Tpo $(DEPDIR)/libdapclient_la-ResponseTooBigErr.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='ResponseTooBigErr.cc' object='libdapclient_la-ResponseTooBigErr.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-ResponseTooBigErr.lo `test -f 'ResponseTooBigErr.cc' || echo '$(srcdir)/'`ResponseTooBigErr.cc
+
+libdapclient_la-HTTPCacheTable.lo: HTTPCacheTable.cc
+ at am__fastdepCXX_TRUE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libdapclient_la-HTTPCacheTable.lo -MD -MP -MF $(DEPDIR)/libdapclient_la-HTTPCacheTable.Tpo -c -o libdapclient_la-HTTPCacheTable.lo `test -f 'HTTPCacheTable.cc' || echo '$(srcdir)/'`HTTPCacheTable.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/libdapclient_la-HTTPCacheTable.Tpo $(DEPDIR)/libdapclient_la-HTTPCacheTable.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='HTTPCacheTable.cc' object='libdapclient_la-HTTPCacheTable.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LIBTOOL)  --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdapclient_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libdapclient_la-HTTPCacheTable.lo `test -f 'HTTPCacheTable.cc' || echo '$(srcdir)/'`HTTPCacheTable.cc
+
+getdap-getdap.o: getdap.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT getdap-getdap.o -MD -MP -MF $(DEPDIR)/getdap-getdap.Tpo -c -o getdap-getdap.o `test -f 'getdap.cc' || echo '$(srcdir)/'`getdap.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/getdap-getdap.Tpo $(DEPDIR)/getdap-getdap.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='getdap.cc' object='getdap-getdap.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o getdap-getdap.o `test -f 'getdap.cc' || echo '$(srcdir)/'`getdap.cc
+
+getdap-getdap.obj: getdap.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT getdap-getdap.obj -MD -MP -MF $(DEPDIR)/getdap-getdap.Tpo -c -o getdap-getdap.obj `if test -f 'getdap.cc'; then $(CYGPATH_W) 'getdap.cc'; else $(CYGPATH_W) '$(srcdir)/getdap.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/getdap-getdap.Tpo $(DEPDIR)/getdap-getdap.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='getdap.cc' object='getdap-getdap.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(getdap_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o getdap-getdap.obj `if test -f 'getdap.cc'; then $(CYGPATH_W) 'getdap.cc'; else $(CYGPATH_W) '$(srcdir)/getdap.cc'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+distclean-libtool:
+	-rm -f libtool config.lt
+install-dist_aclocalDATA: $(dist_aclocal_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(aclocaldir)" || $(MKDIR_P) "$(DESTDIR)$(aclocaldir)"
+	@list='$(dist_aclocal_DATA)'; test -n "$(aclocaldir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(aclocaldir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(aclocaldir)" || exit $$?; \
+	done
+
+uninstall-dist_aclocalDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(dist_aclocal_DATA)'; test -n "$(aclocaldir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(aclocaldir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(aclocaldir)" && rm -f $$files
+install-pkgconfigDATA: $(pkgconfig_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgconfigdir)" || $(MKDIR_P) "$(DESTDIR)$(pkgconfigdir)"
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(pkgconfigdir)'"; \
+	  $(INSTALL_DATA) $$files "$(DESTDIR)$(pkgconfigdir)" || exit $$?; \
+	done
+
+uninstall-pkgconfigDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgconfigdir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgconfigdir)" && rm -f $$files
+install-pkgincludeHEADERS: $(pkginclude_HEADERS)
+	@$(NORMAL_INSTALL)
+	test -z "$(pkgincludedir)" || $(MKDIR_P) "$(DESTDIR)$(pkgincludedir)"
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  echo "$$d$$p"; \
+	done | $(am__base_list) | \
+	while read files; do \
+	  echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(pkgincludedir)'"; \
+	  $(INSTALL_HEADER) $$files "$(DESTDIR)$(pkgincludedir)" || exit $$?; \
+	done
+
+uninstall-pkgincludeHEADERS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(pkginclude_HEADERS)'; test -n "$(pkgincludedir)" || list=; \
+	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+	test -n "$$files" || exit 0; \
+	echo " ( cd '$(DESTDIR)$(pkgincludedir)' && rm -f" $$files ")"; \
+	cd "$(DESTDIR)$(pkgincludedir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in dods-datatypes-config.h.in xdr-datatypes-config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS) config.h.in dods-datatypes-config.h.in xdr-datatypes-config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in dods-datatypes-config.h.in xdr-datatypes-config.h.in $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS) config.h.in dods-datatypes-config.h.in xdr-datatypes-config.h.in $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@case `sed 15q $(srcdir)/NEWS` in \
+	*"$(VERSION)"*) : ;; \
+	*) \
+	  echo "NEWS not updated; not releasing" 1>&2; \
+	  exit 1;; \
+	esac
+	$(am__remove_distdir)
+	test -d "$(distdir)" || mkdir "$(distdir)"
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+	$(MAKE) $(AM_MAKEFLAGS) \
+	  top_distdir="$(top_distdir)" distdir="$(distdir)" \
+	  dist-hook
+	-test -n "$(am__skip_mode_fix)" \
+	|| find "$(distdir)" -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
+	  ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
+	  ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
+	|| chmod -R a+r "$(distdir)"
+dist-gzip: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+dist-bzip2: distdir
+	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-lzma: distdir
+	tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
+	$(am__remove_distdir)
+
+dist-xz: distdir
+	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+	$(am__remove_distdir)
+
+dist-tarZ: distdir
+	tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
+	$(am__remove_distdir)
+
+dist-shar: distdir
+	shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
+	$(am__remove_distdir)
+
+dist-zip: distdir
+	-rm -f $(distdir).zip
+	zip -rq $(distdir).zip $(distdir)
+	$(am__remove_distdir)
+
+dist dist-all: distdir
+	tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
+	$(am__remove_distdir)
+
+# This target untars the dist file and tries a VPATH configuration.  Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+	case '$(DIST_ARCHIVES)' in \
+	*.tar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
+	*.tar.bz2*) \
+	  bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
+	*.tar.lzma*) \
+	  unlzma -c $(distdir).tar.lzma | $(am__untar) ;;\
+	*.tar.xz*) \
+	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
+	*.tar.Z*) \
+	  uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
+	*.shar.gz*) \
+	  GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
+	*.zip*) \
+	  unzip $(distdir).zip ;;\
+	esac
+	chmod -R a-w $(distdir); chmod a+w $(distdir)
+	mkdir $(distdir)/_build
+	mkdir $(distdir)/_inst
+	chmod a-w $(distdir)
+	test -d $(distdir)/_build || exit 0; \
+	dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
+	  && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
+	  && am__cwd=`pwd` \
+	  && $(am__cd) $(distdir)/_build \
+	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(DISTCHECK_CONFIGURE_FLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) \
+	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
+	  && $(MAKE) $(AM_MAKEFLAGS) check \
+	  && $(MAKE) $(AM_MAKEFLAGS) install \
+	  && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+	  && $(MAKE) $(AM_MAKEFLAGS) uninstall \
+	  && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
+	        distuninstallcheck \
+	  && chmod -R a-w "$$dc_install_base" \
+	  && ({ \
+	       (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
+	       && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
+	            distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
+	      } || { rm -rf "$$dc_destdir"; exit 1; }) \
+	  && rm -rf "$$dc_destdir" \
+	  && $(MAKE) $(AM_MAKEFLAGS) dist \
+	  && rm -rf $(DIST_ARCHIVES) \
+	  && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
+	  && cd "$$am__cwd" \
+	  || exit 1
+	$(am__remove_distdir)
+	@(echo "$(distdir) archives ready for distribution: "; \
+	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
+	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
+distuninstallcheck:
+	@$(am__cd) '$(distuninstallcheck_dir)' \
+	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	   || { echo "ERROR: files left after uninstall:" ; \
+	        if test -n "$(DESTDIR)"; then \
+	          echo "  (check DESTDIR support)"; \
+	        fi ; \
+	        $(distuninstallcheck_listfiles) ; \
+	        exit 1; } >&2
+distcleancheck: distclean
+	@if test '$(srcdir)' = . ; then \
+	  echo "ERROR: distcleancheck can only run from a VPATH build" ; \
+	  exit 1 ; \
+	fi
+	@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
+	  || { echo "ERROR: files left in build directory after distclean:" ; \
+	       $(distcleancheck_listfiles) ; \
+	       exit 1; } >&2
+check-am: all-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) $(DATA) \
+		$(HEADERS) config.h dods-datatypes-config.h \
+		xdr-datatypes-config.h
+install-binPROGRAMS: install-libLTLIBRARIES
+
+installdirs: installdirs-recursive
+installdirs-am:
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(aclocaldir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(pkgincludedir)"; do \
+	  test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+	done
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-recursive
+
+clean-am: clean-binPROGRAMS clean-generic clean-libLTLIBRARIES \
+	clean-libtool clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-hdr distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-dist_aclocalDATA install-pkgconfigDATA \
+	install-pkgincludeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-binPROGRAMS install-binSCRIPTS \
+	install-libLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -f $(am__CONFIG_DISTCLEAN_FILES)
+	-rm -rf $(top_srcdir)/autom4te.cache
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
+	uninstall-dist_aclocalDATA uninstall-libLTLIBRARIES \
+	uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+	ctags-recursive install install-am install-strip \
+	tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am am--refresh check check-am clean clean-binPROGRAMS \
+	clean-generic clean-libLTLIBRARIES clean-libtool \
+	clean-noinstLTLIBRARIES ctags ctags-recursive dist dist-all \
+	dist-bzip2 dist-gzip dist-hook dist-lzma dist-shar dist-tarZ \
+	dist-xz dist-zip distcheck distclean distclean-compile \
+	distclean-generic distclean-hdr distclean-libtool \
+	distclean-tags distcleancheck distdir distuninstallcheck dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-binPROGRAMS install-binSCRIPTS install-data \
+	install-data-am install-dist_aclocalDATA install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am \
+	install-libLTLIBRARIES install-man install-pdf install-pdf-am \
+	install-pkgconfigDATA install-pkgincludeHEADERS install-ps \
+	install-ps-am install-strip installcheck installcheck-am \
+	installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am \
+	uninstall-binPROGRAMS uninstall-binSCRIPTS \
+	uninstall-dist_aclocalDATA uninstall-libLTLIBRARIES \
+	uninstall-pkgconfigDATA uninstall-pkgincludeHEADERS
+
+
+# Not nearly as clean as it could be, but this removes .svn directories
+# in subdirs.
+dist-hook:
+	rm -rf `find $(distdir) -name .svn`
+
+# MAINTAINERCLEANFILES = $(GRAM_SRC)
+
+# Copy the generated grammar files to the 'grammarfiles' directory.
+.PHONY: grammarfiles
+grammarfiles: $(GRAM_SRC)
+	for f in $(GRAM_SRC); do cp $$f grammarfiles; done
+
+.PHONY: docs
+docs:
+	doxygen $(srcdir)/doxy.conf
+	(cd docs && tar -czf html.tar.gz html)
+
+# cccc computes metrics like Lines of code and McCabe. It'a available
+# on the web...
+.PHONY: cccc
+cccc:
+	-mkdir cccc
+	cccc --outdir=cccc $(DAP_SRC) $(SERVER_SRC) $(CLIENT_SRC) \
+	$(DAP_HDR) $(SERVER_HDR) $(CLIENT_HDR)
+
+###########################################################################
+
+# Fortify targets.
+# dods-datatypes.h xdr-datatypes.h
+.PHONY: fortify
+fortify: $(BUILT_SOURCES)
+	(cd gl && sourceanalyzer -b @PACKAGE at -gl $(MAKE) )
+	sourceanalyzer -b @PACKAGE at -parsers $(MAKE) libparsers.la
+	sourceanalyzer -b @PACKAGE@ $(MAKE) libdap.la libdapserver.la libdapclient.la
+	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
+
+# run fortify on only our code, not the gnulib code or the flex/bison code.
+# This does skip testing some of the functions we wrote in the *.lex/*.y
+# files but should eliminate the false positives from flex and bison, too.
+.PHONY: fortify-lite
+fortify-lite: dods-datatypes.h xdr-datatypes.h
+	( cd gl && $(MAKE) )
+	$(MAKE) libparsers.la
+	sourceanalyzer -b @PACKAGE@ $(MAKE) libdap.la libdapserver.la libdapclient.la
+	sourceanalyzer -b @PACKAGE@ -scan -f @PACKAGE at -@PACKAGE_VERSION at .fpr
+
+# Use this to clean the fortify project.
+.PHONY: fortifyclean
+fortifyclean:
+	(cd gl && sourceanalyzer -b @PACKAGE at -gl -clean )
+	sourceanalyzer -b @PACKAGE@ -clean
+
+###########################################################################
+
+# Build linux RPMs. Use the environment variable 'RPM_OPTIONS' to pass in
+# extra options like --nodeps and --macros
+
+srpm: dist
+	rpmbuild -ts --clean $(RPM_OPTIONS) @PACKAGE at -@PACKAGE_VERSION at .tar.gz
+
+rpm: dist
+	rpmbuild -tb --clean $(RPM_OPTIONS) @PACKAGE at -@PACKAGE_VERSION at .tar.gz
+
+clean-pkg:
+	-rm -rf mac_osx @PACKAGE at -@PACKAGE_VERSION at .pkg
+
+pkg-build: clean-pkg
+	./configure --prefix=$(prefix) --disable-dependency-tracking $(PKG_CONF_FLAGS)
+	make clean all
+	DESTDIR=`pwd`/mac_osx make install
+
+pkg-main: pkg-build
+	./OSX_Resources/update_mac_package_contents.pl README
+	cat ./OSX_Resources/Info.plist.proto | \
+	   sed -e "s^_PREFIX_^$(prefix)^g" \
+	       -e "s^_FULL_VERSION_^@PACKAGE_VERSION@^g" \
+	       -e "s^_MAJOR_VERSION_^@PACKAGE_MAJOR_VERSION@^g" \
+	       -e "s^_MINOR_VERSION_^@PACKAGE_MINOR_VERSION@^g" \
+	       > foo
+	mv foo ./OSX_Resources/Info.plist
+	${PACKAGEMAKER} --root mac_osx --id org.opendap. at PACKAGE@ \
+	    --title "@PACKAGE@ @PACKAGE_VERSION@" --version @PACKAGE_VERSION@ \
+	    --out @PACKAGE at -@PACKAGE_VERSION at .pkg --resources OSX_Resources
+
+pkg-dmg: pkg-main
+	-rm -rf @PACKAGE at -@PACKAGE_VERSION@
+	-rm -rf @PACKAGE at -@PACKAGE_VERSION at .dmg
+	mkdir @PACKAGE at -@PACKAGE_VERSION@
+	cp -r @PACKAGE at -@PACKAGE_VERSION at .pkg @PACKAGE at -@PACKAGE_VERSION@
+	cp README README.* NEWS @PACKAGE at -@PACKAGE_VERSION@
+	dropdmg -i --sanitize-for-servers --format zlib @PACKAGE at -@PACKAGE_VERSION@
+	-rm -rf @PACKAGE at -@PACKAGE_VERSION@
+
+pkg: pkg-main 
+
+# Note that the gcov options -f and -b are useful but sometimes make looking
+# at the results of coverage analysis a little taxing. -b reports on all
+# branched and -f reports on all functions. The -l -o options summarize on a
+# per-file basis. 3/27/98 jhrg
+collect-coverage-data:
+	(cd test-coverage; \
+         cov_dat="coverage-data-`date +%m.%d.%y`"; \
+         touch $$cov_dat; \
+         for f in $(ALLSRCS); do \
+            echo "\n*** Coverage data for $$f ***\n" >> $$cov_dat; \
+            gcov -l -o ../ $$f >> $$cov_dat; \
+         done)
+
+Operators.h: ce_expr.tab.hh
+
+ at USE_C99_TYPES_TRUE@dods-datatypes.h: dods-datatypes-static.h
+ at USE_C99_TYPES_FALSE@dods-datatypes.h: dods-datatypes-config.h
+	cp -p $< dods-datatypes.h
+
+xdr-datatypes.h: xdr-datatypes-config.h
+	cp -p $< xdr-datatypes.h
+
+############################################################################
+# Special rules for the grammars. I tried to use the automake grammar support
+# but these grammars are so hacked that it was taking too much time. Maybe if
+# each grammar was converted one by one... jhrg 6/22/05
+# 
+# I switched to using flex options instead of sed and mv. jhrg 02/28/08
+#
+# Build the DAS scanner and parser
+
+lex.das.cc: das.lex das.tab.cc das.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+# The funny if statment accommodates older versions of bison that treats
+# -o differently than the 2.x versions. jhrg 3/2/08
+das.tab.cc das.tab.hh: das.y DAS.h
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p das -o das.tab.cc $<
+	if test -e das.tab.cc.h; then mv das.tab.cc.h das.tab.hh; fi
+
+# DDS
+
+lex.dds.cc: dds.lex dds.tab.cc dds.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+dds.tab.cc dds.tab.hh: dds.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p dds -o dds.tab.cc $<
+	if test -e dds.tab.cc.h; then mv dds.tab.cc.h dds.tab.hh; fi
+
+# CE
+
+lex.ce_expr.cc: ce_expr.lex ce_expr.tab.cc ce_expr.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+ce_expr.tab.cc ce_expr.tab.hh: ce_expr.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p ce_expr -o ce_expr.tab.cc $<
+	if test -e ce_expr.tab.cc.h; then mv ce_expr.tab.cc.h ce_expr.tab.hh; fi
+
+# Build the grid selection sub_expression scanner and parser
+
+lex.gse_.cc: gse.lex gse.tab.cc gse.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+gse.tab.cc gse.tab.hh: gse.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p gse_ -o gse.tab.cc $<
+	if test -e gse.tab.cc.h; then mv gse.tab.cc.h gse.tab.hh; fi
+
+# Errors
+
+lex.Error.cc: Error.lex Error.tab.cc Error.tab.hh
+	$(LEX) $(LFLAGS) $(AM_LFLAGS) $<
+
+Error.tab.cc Error.tab.hh: Error.y
+	$(YACC) $(YFLAGS) $(AM_YFLAGS) -p Error -o Error.tab.cc $<
+	if test -e Error.tab.cc.h; then mv Error.tab.cc.h Error.tab.hh; fi
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Marshaller.h b/Marshaller.h
new file mode 100644
index 0000000..45af73d
--- /dev/null
+++ b/Marshaller.h
@@ -0,0 +1,84 @@
+// Marshaller.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef A_Marshaller_h
+#define A_Marshaller_h 1
+
+#include <string>
+#include <vector>
+
+using std::string ;
+using std::vector ;
+
+#include "DapObj.h"
+
+#include "dods-datatypes.h"
+
+namespace libdap
+{
+
+class Vector ;
+
+/** @brief abstract base class used to marshal/serialize dap data objects
+ */
+class Marshaller : public DapObj
+{
+public:
+    virtual void		put_byte( dods_byte val ) = 0 ;
+
+    virtual void		put_int16( dods_int16 val ) = 0 ;
+    virtual void		put_int32( dods_int32 val ) = 0 ;
+
+    virtual void		put_float32( dods_float32 val ) = 0 ;
+    virtual void		put_float64( dods_float64 val ) = 0 ;
+
+    virtual void		put_uint16( dods_uint16 val ) = 0 ;
+    virtual void		put_uint32( dods_uint32 val ) = 0 ;
+
+    virtual void		put_str( const string &val ) = 0 ;
+    virtual void		put_url( const string &val ) = 0 ;
+
+    virtual void		put_opaque( char *val, unsigned int len ) = 0 ;
+    virtual void		put_int( int val ) = 0 ;
+
+    virtual void		put_vector( char *val, int num,
+                                            Vector &vec ) = 0 ;
+    virtual void		put_vector( char *val, int num, int width,
+                                            Vector &vec ) = 0 ;
+
+    virtual void		dump(ostream &strm) const = 0 ;
+} ;
+
+} // namespace libdap
+
+#endif // A_Marshaller_h
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..f502aa3
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,653 @@
+News for version 3.11.1
+
+The new DAP3.3 Keywords are supported by the library.
+
+Merge of the Hyrax 3.6.2 fixes.
+
+A race condition in the HTTP cache was fixed.
+
+Fixes for the OS/X package.
+
+News for version 3.11.0
+
+Constraint expressions can now include multiple function calls.
+Previously, when a function was used in the projection part of the CE
+and it was not a 'projection function,' but a function that returns
+data, only function could be called in the CE. Now the evaluator
+supports calling a series of functions. The results are returned in a
+Dataset object as before. Because this is a new behavior for the
+library I have bumped up the minor revision. This version is backward
+compatible with the previous version of the library.
+
+Grid now prints the XML declaration correctly when a constrained Grid
+variable's type decays to a Structure. The expr-test program now has
+an XML option (-x) for use with constrained DDS/DDX output. This bug
+affected the usefulness of the DDX response.
+
+the geogrid() function now takes both (grid, <box points>) and (grid,
+lat array, lon array <box points>). This includes some minimal testing
+of the new code.
+
+Bug fixes.
+
+News for version 3.10.2
+
+Changed the way the DAS object's attributes are merged into a DDS
+object, which did two things. First, the process of merging the
+attributes has a default behavior that will work if the DAS and DDS
+are built according to the DAp 2.0 specification, and second, the
+handlers can specialize the process to suite their own needs. This
+means that new handlers that build odd DAS objects will need to
+specialize the transfer_attributes() method defined by BaseType,
+Constructor and Grid. I've already done this for the current handlers
+we're distributing as part of Hyrax. This means that attributes from
+the netCDF handler appear correctly in Grid maps.
+
+Speaking of the netCDF handler, it now builds with netcdf 4.1.
+
+Build fixes galore, including new Requires: lines in the rpm spec
+files which should make it easier to short circuit installation
+problems with the handlers.
+
+The DDX no longer contains attributes with &0xdd; escape codes. When
+an XML document declares that it is UTF-8 codes < 0x20 are not
+allowed. We're using octal escapes again.
+
+The preceding fix, along with the corrected processing of the DAS
+object mean that two major issues with the DDX that hindered the use
+of that response in semantic web applications are gone.
+
+News for version 3.10.1b
+
+We have removed the Server 3 (CGI) software from the dap-server
+package and, with that change, we have removed the deflate program
+from this library/package.
+
+The geogrid() function has been much improved. It will now answer
+requests where the latitude is upside down in the dataset and flip the
+result so that the north pole is 'up'. It will also handle requests
+that 'wrap around' the date line. Error messages are also improved.
+
+This library now implements DAP 3.3 including the OtherXML DAP
+attribute type (which will become AnyXML in DAP 4). The library now
+implements simple version negotiation and a DDX response that is DAP
+version sensitive. See the online DAP4 design documentation for more
+information (docs.opendap.org).
+
+Many, many fixes and extensions for DAP4 and NcML support. (NB: the
+NcML handler is a separate project).
+
+News for version 3.9.2
+
+Memory leak fixed when using DDS::transfer_attributes on a DAS that uses the
+ALias keyword.
+
+News for version 3.9.1
+
+The CE parser now returns an error if an array of structures that contains
+arrays is imporperly constrained (the enclosing structure array _may_ be
+subsampled, but that subsampling must be the same for each of its fields. The
+fields can be independently subsampled.
+
+A problem with the client-side cache has been fixed.
+
+Variable names can now be quoted! That is, in a CE you can say:
+
+  "my odd name"."% H2O"[10:13] 
+
+and it will parse. Must clients and all web browsers will encode all of this
+using the web's URL escape syntax, whic his hard to read, but this means that
+any character can now appear in a variable name (double quotes can be escaped
+using a backslash and backslashes can be includes using '\\'). The quotes are
+optional, of course, so all CEs that work now will continue to work.
+
+News for version 3.9.0
+
+libdap now supports DAP 3.2. The evolving DAP 3.x protocol is described at
+http://docs.opendap.org/index.php/DAP3/4. The most important change from DAP
+3.1 to 3.2 is:
+
+  DAP 3.2 introduces the notion of protocol negotiation, similar to HTTP's
+  response type or encoding negotiation. The client MAY send an XDAP-Accept
+  header to tell the server the highest version of the protocol that the
+  client can understand. The server MUST then respond using only responses at
+  or below that version number of the protocol. Note that an Error response
+  (e.g., "The response you requested cannot be returned using the protocol
+  version you understand") can be understood by any client. If a client does
+  not send the XDAP-Accept header, then the server MUST assume a DAP 2.0/3.1
+  client. The only functional difference between DAP 2.0, 3.0 and 3.1 is
+  form/content of the version information returned in the HTTP response
+  header.
+
+  By allowing the server to respond with a lower version the protocol can
+  support old servers (since that's how they will respond) and enable newer
+  clients to treat the lower version responses as errors (because the newer
+  servers can be expected to discriminate between different server versions).
+
+  New servers SHOULD always return a response that conforms to the version
+  sent from the client in the XDAP-Accept header.
+
+  In addition to returning the DAP protocol version using the XDAP header
+  (which is a mechanism specific to HTTP), the protocol version will also be
+  returned in the DDX Dataset element using the XML attribute dap-version.
+  See DDX.
+
+With this version of libdap the DDX is slightly different for DAP 3.2 - it
+now includes DAP protocol version information and an xmlbase element.
+
+There was ambiguity regarding how an array of structures would be constrained.
+The web page of DAP 2 Errata has been updated with a clarification of this and
+the constraint expression parser has been updated to reflect that fix. See
+the DAP3/4 page and ticket 975 for the complete info. Short version: Suppose
+'s' is an array of structures and 'm' is an array that is a member of 's'.
+You can constraint 'm' like this: s2[0:4].m[2:7]
+
+Now the notion that a dataset identifier (e.g., a file name) is bound to the
+DDS has been  dropped and that identifier is bound to a variable. This lets
+the library be used in contexts where a DDS holds variables from several
+different places (e.g., files).
+
+String attribute values were always quoted (quotes were added if not present
+in the data set) and while this was OK for the DAS response, it broke the
+DDX. Now quotes are added to DAS response but not the values themselves. See
+ticket 1163.
+
+Nested Sequences were failing when the constraint forced one or more rows of
+the inner Sequence to be empty. Fixed.
+
+A number of build issues have been fixed in this version, see the ChangeLog
+file.
+
+News for version 3.8.2
+
+Significant improvements to the HTTP cache. The cache software could return
+erroneous responses in some rare cases when using multi-threaded code. Fixed.
+Also the entire caching system is now much more robust since the 'table' that
+contains information about individual entries is encapsulated in it's own
+class. The HTTP cache is still both thread-safe and _not_ multi-process safe.
+However, it should be possible to modify the HTTPCacheTable class to use a
+database system like MySQL or SQLite to make it MP-safe.
+
+The 'ancillary information' functions have been moved to their own class
+(from DODSFilter and the file cgi_util.cc).
+
+I fixed the libdap win32 installer so that it does not install stuff in the
+win32 system directories anymore.
+
+News for version 3.8.1
+
+The syntax for PROXY_SERVER and NO_PROXY_FOR have been fixed so that they are
+easier to use. PROXY_SERVER now takes a value like
+'http://user:pw@squid.proxy.edu:3128' and uses it correctly. In that value,
+all parts but the host name (squid.proxy.edu) are optional and the old syntax,
+as well as several comman variants, are accepted. For the NO_PROXY_FOR entry,
+the '<protocol>,' is now optional. Only the HTTP protocol is supported or the
+proxy server.
+
+News for version 3.8.0, 29 February 2008
+
+The libdap classes and code are now inside of the libdap namespace. In order
+to access any of the classes, for example, you will need to do one of the
+following. After including the libdap headers you can:
+
+1. add a using statement for the entire libdap namespace:
+
+using namespace libdap ;
+
+2. add a using statement for the classes that you will be using:
+
+using libdap::DAS ;
+
+3. inside your code scope the use of libdap classes.
+
+libdap::DAS *das = code_to_get_das() ;
+
+HTTPCache updated to cache an entry, returning not only the FILE pointer but
+also the name of the file in the cache. This way, the cached item could be
+passed to a data handler, such as the netcdf_handler, and read.
+
+The pkg build for Mac OSX was updated to automate the creation of the
+ReadMe.txt file, add a README and NEWS file to the dmg and automatically
+create the dmg using DropDMG.
+
+News for version 3.7.10, 28 November 2007
+
+Fixed XDRStreamMarshaller so that it no longer allocates a huge buffer. This
+fixes a bug where the BES fails to start on smaller machines.
+
+News for version 3.7.9, 21 November 2007
+
+Bumped up the soname version numbers for libdaoclient and libdapserver due
+to changes in the HTTPResponse and AlarmHandler interfaces.
+
+The transfer_data() method defined for Sequence and Structure has been
+generalized and implemented for all classes. In the process, so issues with
+the way nested sequences were handled have been fixed. I renamed the method
+to intern_data() since it is now a part of libdap (and not just two classes).
+The method uses the read() methods defined for the type classes (Byte, ...,
+Grid) to read data into variables in a DDS as if they were read in using
+deserialize(). This is used by the ASCII response generator and might be used
+by other 'formatted output' generators.
+
+Generated files (like the grammar files) are now shipped with the source
+distributions. (From Patrice Dumas)
+
+Methods which write output using the C++ iostream system have been added back
+into the library and are going to replace the FILE* versions of those
+methods. We have also added an 'Un/Marshaller' set of classes so that we can
+release a version of Hyrax (slated to be 1.4) that will improve BES/OLFS
+communication efficiency.
+
+The functionality of the Passive* type classes was subsumed by their parent
+classes and they were removed from the library to cut down on 'hierarchy
+clutter.' Some other unneeded files were also removed.
+
+The maximum size of a Str object was changes to 65535 (DODS_USHORT_INT-1) to
+accommodate HDF5 strings. 
+
+Checkouts from subversion now have no (?) generated files. We are keeping a
+copy of the grammars in subdirectory named 'grammarfiles.'
+
+HTTP response codes are now available in libdap HTTPResponse objects. From
+Darren Hardy.
+
+News for version 3.7.8, 26 June 2007
+
+Updated the email address for support to support at opendap.org and changed
+the tech email list address to opendap-tech at opendap.org. This is part of
+the plan to shift support services to OPeNDAP and to use the tech email list
+as part of that plan.
+
+Updated to the latest gnulib software.
+
+Memory errors fixed: 
+
+    In the HTTP processing code for clients which was triggered when a client
+    read from an older server (older servers had malformed HTTP headers).
+
+    An error in the regular expression class (Regex) where the build
+    generated flawed code on a 64-bit machine.
+
+OSX Build improvements.
+
+Patrice Dumas' changes to dods-datatypes.h - Now the header uses the C99
+types unless the stdint.h header is not present.
+
+pkg-config support. From a patch by Patrice Dumas.
+
+General improvements to comments, strings and error messages throughout the
+libraries. 
+
+News for version 3.7.7, 2 May 2007
+
+Fixed a bug where the build was not installing the dapserver and dapclient
+libraries. 
+
+Fixed a handful of platform-specific build issues.
+
+There are some minor performance improvements to the constraint evaluator.
+
+Repaired some problems with the server-side functions.
+
+News for version 3.7.6, 12 March 2007
+
+Fixed a bug in the linear_scale() Constraint Expression function when that
+function was used with plain arrays.
+
+I fixed a build issue on linux for ml-structs caused by a bad/missing
+#include in GnuRegex.h.
+
+News for version 3.7.5, 7 Feb 2007
+
+Many bug fixes for the Server-Side functions linear_scale(), grid(),
+geogrid() and geoarray().
+
+Added dump method to the BaseType classes, DAS, DDS, DataDDS. To do
+this, created a DapObj base class for all of these to inherit from
+(directly or indirectly) and in the DapObj class is the operator<<
+method. This will aid in debugging. Created an indentation classes to
+help with dumping objects.
+
+Win32 port fixes. The Win32 build is closer to the Unix build. Our
+hope is to get the two to be almost identical so that we can all build
+on Win32 and thus get away from having the win32 releases lag behind the
+Unix releases.
+
+Fix in Vector for gcc 4.1
+
+News for version 3.7.4, 02 Jan 2007
+
+Build enhancements and bug fixes. See ChangeLog for specifics.
+
+News for version 3.7.3, 24 Nov 2006
+
+Fixed unescattr() so that it works!
+
+Rob added improvements to the win32 build.
+
+Fixed a number of bugs including: Problems with the DDS::transfer_attributes()
+method which broke libnc-dap; Added a new configuration parameter to .dodsrc
+so that SSL validation can be suppressed; Fixed problems with the change from
+\n to \r\n line terminators for MIME headers which slipped through the cracks
+the first time; and add gzip and compress to the set of accepted compression
+types supported by the client side.
+
+Added Connect::request_ddx() which asks a server for the DDX response. 
+Previously, it was possible to use getdap to print the DDX, but that object
+was actually built using the DAS and DDS from a server. Now the server is asked
+for the DDX. Servers should support this response to be compliant with DAP 3.1.
+
+In the ConstraintEvaluator class, the add_function() method now allows a server
+to override a function from libdap with a new definition of the same name.
+
+I added a new interface for the scalar types: value() and set_value() can be
+used to get and set values. These are much simple to use than the older
+val2buf() and buf2val() methods. This idea was copied from copied from the 
+PassiveByte, ..., classes.
+
+New server-side functions for geographical constraints have been added. These
+functions provide a way to select parts of Grid or Array variables using
+Latitude and Longitude. Also added is a version() function which can be used
+by clients to figure out which version of functions is present. The version
+function has two forms, one which returns the information as plain text and
+one which returns the information in a small XML document. libdap 3.7.3 is a
+beta release of these functions. Note that these are _server-side_ functions
+so before they can be used, servers need to be built using this library and
+installed.
+
+The dap-config script has been fixed so that it behaves more like other 
+such scripts.
+
+News for version 3.7.2
+
+Fixed a persistent bug in the GNURegex code. (ticket 389)
+
+Fixed a problem in HTTPConnect where the change from newline to cr/nl line
+terminators was not accommodated (no ticket, but part of the issues behind
+ticket 552).
+
+Added Sequence::transfer_data(). This method uses the read() method to read
+data and follows the same logic used by serialize to determine which data is
+'sent' but instead records the data in the d_values field. Thus a Sequence
+can transfer data to itself. The locally stored data apes the ability of the
+other classes to store a complete response and is the basis for the new ASCII
+response code (in dap-server/asciival) which Server4 uses.
+
+There's a fair amount of the geogrid() code now in place, although the
+function does not work, I have added a GeoConstraint class which is close to
+complete. The CEFunctionsTest unit tests fail.
+
+News for version 3.7.1
+
+Fixed bug #480. Attributes from the HDF4 server were not being handled in a
+way that made sense to netCDF clients.
+
+Added a new method to AttrTable so that a vector of strings can be used to
+set a vector of attribute values in one call. No more need to build a loop
+every time you want to set values.
+
+The grid() CE function now conforms to the design submitted to URI as part of
+the REASoN award.
+
+Fixed a bug when % signs were not handled correctly by the code in
+escaping.cc. 
+
+News for version 3.7.0
+
+The big change: The first of the DAP3/4 features was added to the libdap
+library; the library now includes the DAP protocol version number in all
+responses. A savvy client can test for this and process accordingly. 
+
+A second feature, representation of the data source metadata in XML, is
+supported in alpha form. Expect the 'DDX' response to change slightly in the
+next release. The DDX returned now contains an obsolete element named 'Blob'
+which we won't be using. Other than the Blob element, the current DDX
+probably will not change much except for the addition of new datatypes,
+something that will take place only after other changes are made to the
+protocol. Many of the handlers now support returning the DDX, so developers
+can begin to play with it's capabilities. 
+
+What's really nice about the DDX: It's cool that the DDX now encode the
+metadata in XML, but the really nice feature is that it combines information
+from the DDS and DAS, making the association of attributes to variables much
+easier. 
+
+Updated the reference guide (HTML pages in docs).
+
+Fixed a pernicious bug in GNURegex.cc
+
+Added the class ConstraintEvaluator. The DDS class now takes the constraint
+evaluator as a parameter, so it's possible to replace ours with your own.
+
+The single library libdap has been split into three libraries: libdap for the 
+DAP functionality, libdapclient for the client-side classes and libdapserver
+for the server-side classes.
+
+Added INSTALL.AIX which contains information about building libdap on AIX
+using the _native compiler_. 
+
+News for version 3.6.2
+
+This version includes two bug fixes. 
+
+1. The library can now correctly reads binary data objects saved using the web
+interface. Before, this was very hard to do. The utility getdap has been
+modified so that it can decode these saved '.dods' files.
+
+2. The DODSFilter class used to build all of our data handlers no longer 
+blocks when returning a data object to a web browser. This fixes a problem
+where the 'Get Binary' button on the data server's web interface would hang
+seemingly forever. In fact it did return the data blob, but only after the 
+blocked handler had timed out.
+
+News for version 3.6.1
+
+Fixed a bug in deflate.c: Some comments used the C++ style comments and gcc
+rejected that.
+
+Data server filters built with the 3.6.0 library were not compatible with the
+dap-server 3.6.0 software because the DODSFilter class did not recognize the
+-t option (which is used to pass the handler a timeout value).
+
+News for version 3.6.0
+
+Added patches for RPM spec files from Patrice Dumas.
+
+Fixed a problem where Grids with two or more dimensions with the same name 
+were flagged as broken (by Grid::check_semantics). Now they are allowed as per
+the specification.
+
+Added a new method get_parent() to AttrTable. This returns the parent 
+container for this AttrTable.
+
+I removed the old iostream methods from the library. These methods should not
+be used because in many cases since other parts of the library use the C/stdio 
+functions for I/O. In older versions of gcc, it was possible to mix the
+two types of I/O systems, but not now (and not in other compilers). To change
+your code, look in the file Removed_functions.txt to see the functions/methods
+that have been removed. In all cases there is a version that takes a FILE *
+in place of the ostream &. Use the FILE* version. If you're performing I/O
+that relies on operator<<() to do type conversions, use an ostringstream 
+in your code and then write the string to stdout (or wherever) using fprintf
+like: fprintf(stdout, "%s", oss.str().c_str()). Ugly, but easier in some
+cases than replacing lots of tested C++ I/O with fprintf calls.
+
+I removed old methods in Connect that have been deprecated for more than
+a year. See Removed_functions.txt
+
+I removed the old Pix methods. See removed_functions.txt.
+
+I removed the const char * overloads added to prevent collisions between
+the Pix and String (not string, but GNU's old libg String class) methods.
+
+Added protocol version number header to responses which use the set_mime...()
+functions. The new header is called "XDAP-Protocol" and its value is the 
+two digit DAP protocol version number. This is now used by the client-side
+deserialize() methods; I assume that a server that does not announce its
+protocol version is a 2.0 server.
+
+Removed the set_mime...() functions which take an iostream; use the ones 
+which take the FILE* instead. We replaced the iostream versions with FILE*
+versions a long time ago because the parsers all use FILE* I/O functions
+and mixing the C++ and C I/O is not predictable. The old functions were
+deprecated. To fix your code, just change the iostream variable to a FILE*.
+In most cases this will mean changing 'cout' to 'stdout.' 
+
+News for Release 3.5.3
+
+Changes to the Regex software. I've reimplemented the GNURegex code to 
+use the only the POSIX functions. Because of this there are some subtle
+changes in the way the class Regex works. These changes address bugs that
+show up on Mac OS/X 10.4 (Tiger).
+
+1) Meta characters like '{' now have to be escaped like '\\{'
+2) See the docs for the Regex::match and Regex::serach methods. Regex:match 
+   returns the number of characters that match or -1 if there's no match.
+   Regex::serach returns the position of the _first_ match (not the longest
+   as with POSIX) and the length of that first match in the value-result
+   parameter 'matchlen'.
+3) The Regex constructor now takes only one argument, the regular expression
+   to compile. There's a second ctor that takes a second parameter (an int)
+   but it is a dummy.
+   
+As a result of these changes, a small portion of the interface for libdap
+has changed.
+   
+Build improvements from Patrice Dumas.
+
+Added a Mac OS/X package and RedHat rpm/srpm targets. There's also a pmsp
+file for use with Mac's PackageMaker.
+
+News for Release 3.5.2
+
+Fixed a bug where malformed Error objects from servers caused an exception.
+This caused the original error message to be lost, not very helpful.
+
+The library used a compile-time switch to control use of the factory class for
+creation of objects at run-time. This was causing more trouble than it was
+preventing, so I removed it. Code should switch from the 'virtual
+constructors' to the factory class now.
+
+The Test classes in the subdir 'test' should now produce the same values on
+64- and 32-bit machines.
+
+Unit tests should all work (although one of the tests for util.cc is known to
+fail on FC4).
+
+Revamped the build to use automake. 
+
+Regression tests and the test classes are now in the subdir 'tests.'
+
+The unit tests are now in the subdir 'unit-tests' and are not built or run by
+default. Some of these tests require access to the Internet to work and I
+decided to make then not run using the make check target from the top level
+(the regression tests in 'tests' do run using the top-level check target) so
+that the build would work w/o access to the net.
+
+The rpm spec file has been updated. See INSTALL for information about
+building rpm distributions.
+
+Thanks to Patrice Dumas for help on the autoconf/make, with gnulib and the
+rpm spec file.
+
+News for Release 3.5.1 beta 2005/05/13
+
+I changed some of the build parameters; the utility script is now named
+dap-config, the headers now install into $prefix/include/dap and the static
+library no longer has a version number appended. I've also written a rpm spec
+file which can be used to build a rpm file of/for a binary distribution. At
+this stage you'll need to be pretty savvy with RPM to get it to work; I'll
+write up instructions soon.
+
+News for Release 3.5.0 beta 2005/05/05
+
+Changes in the way the software is organized:
+
+* First, the old 'DODS' CVS module is being broken up to facilitate more
+  frequent releases of software. libdap++ has a new CVS module named
+  'libdap.' To access the software using CVS, use 'cvs co libdap' (where in
+  the past you used 'cvs co DODS/src/dap' or 'cvs co DODS' and then changed
+  into the DODS/src/dap directory).
+
+* The autoconf scripts have been updated; still no libtool or Makefile.am,
+  but the scripts are much more robust.
+
+* The third-party packages are no longer bundled with the library. In a sense
+  they never were, but they _were_ a part of the DODS CVS module. Now it's up
+  to you to get and install the required packages. Look on the web site (or
+  Google) for libxml2 and curl. We build using curl version 7.12.3 and libxml
+  version 2.6.16; curl 7.12.0 and libxml2 2.5.7 should work.
+
+* The libdap software now installs in $prefix/{lib,include,bin} instead of
+  inside the 'DODS tree.' By default $prefix is /usr/local; use the --prefix
+  option of configure to specify a different directory than /usr/local. The
+  library itself installs in $prefix/lib as libdap++.a.3.5; libdap++.a is
+  symbolically linked to that file. The header files now install in
+  $prefix/include/libdap-3.5; $prefix/include/libdap is symbolically linked
+  to that directory. The utilities geturl and opendap-config have been
+  renamed getdap and dap-config, respectively (the name geturl corresponds to
+  another utility). The getdap utility is, except for the name change,
+  exactly the same as geturl. The dap-config script provides a way to
+  determine which libraries should be included when linking with a particular
+  build of libdap++. It also provides information about the version of the
+  library linked to $prefix/lib/libdap++.a and some other stuff. Use
+  dap-config --help for a listing of all the options. Finally, the deflate
+  program, which is used by some servers to provide compressed responses and
+  is called by the library is not stored in $prefix/sbin (except on win32
+  where it's stored in $prefix/bin).
+
+  The usage program is not currently installed; once we complete the
+  reorganization process it will find a good home.
+
+Other changes to libdap++:
+
+* The library now uses a factory class to determine how to instantiate
+  specializations of Byte, Int32, et cetera. The class BaseTypeFactory
+  defines the interface for the factory and provides a default implementation
+  of the class. This implementation instantiates Byte, ..., Grid. Also
+  supplied with the library is TestTypeFactory which instantiates the Test
+  type classes (TestByte, ..., TestGrid). If your use of the library requires
+  that the type classes be specialized, then you must modify your software so
+  that it includes a factory class that specializes BaseTypeFactory. Then,
+  when you create a DDS (or DataDDS) pass a pointer to an instance of your
+  factory to the DDS constructor (or use the new DDS::set_factory() method).
+  Look at BaseTypeFactory and the example specialization TestTypeFactory.
+  It's very straightforward to make the change.
+
+  For applications which don't specialize the type classes, the default
+  factory should be fine. To avoid using the new DDS constructor (which
+  requires that a pointer to an instance of BaseTypeFactory be supplied), your
+  code must #define the symbol DEFAULT_BASETYPE_FACTORY. If this symbol is
+  not defined (at compile time) then various compile-time errors will occur
+  (the idea being this will prevent software from building and silently
+  ignoring specializations of the type classes). If defined, this use the
+  default factory class.
+
+  The documentation for the DDS constructor has some more information.
+
+* The library contains support for the DDX object. The DDX will become the
+  foundation of the DAP3 protocol. It uses XML to describe the information
+  currently represented using our 'curly-brace' notation and also bundles
+  the attributes along with the variables they describe. This will simplify
+  many processing tasks for clients. The software provided simplifies
+  generating the DDX by building it from existing DAS and DDS objects.
+
+* There has also been some significant re-factoring in DDS and DAS: The
+  DDS:send() method has been copied over to DODSFilter and the version in DDS
+  has been deprecated and will be removed in a future version of the library.
+  The library uses STL iterators almost exclusively and the next version will
+  eliminate the ancient Pix class.
+
+* The function dods_root() is now called libdap_root() and tests the
+  environment variable LIBDAP_ROOT. If that variable is not set,
+  libdap_root() returns the value passed to the --prefix option of configure
+  or /usr/local if the option was not used. Added to libdap++ is a function
+  libdap_version() which returns the version number of the library. Note that
+  libdap_version() is declared as extern "C" so that it can be used in
+  configure tests to check for the library.
+
+* The servers no longer provide three programs to handle the das, dds and
+  data requests. Instead one *_handler is provided. This reduces the size of
+  the servers by a factor of three and paves the way toward integration of
+  the HTML and ASCII code into the server binary, which will improve the
+  performance and security of those features.
diff --git a/OSX_Resources/Description.plist b/OSX_Resources/Description.plist
new file mode 100644
index 0000000..435aa4e
--- /dev/null
+++ b/OSX_Resources/Description.plist
@@ -0,0 +1,10 @@
+<?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">
+<plist version="1.0">
+<dict>
+	<key>IFPkgDescriptionDescription</key>
+	<string></string>
+	<key>IFPkgDescriptionTitle</key>
+	<string>OPeNDAP DAP versions 2 and 3 C++ Implementation</string>
+</dict>
+</plist>
diff --git a/OSX_Resources/Info.plist b/OSX_Resources/Info.plist
new file mode 100644
index 0000000..c85c367
--- /dev/null
+++ b/OSX_Resources/Info.plist
@@ -0,0 +1,46 @@
+<?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">
+<plist version="1.0">
+<dict>
+	<key>CFBundleGetInfoString</key>
+	<string>3.11.1, OPeNDAP libdap</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.opendap.libdap</string>
+	<key>CFBundleShortVersionString</key>
+	<string>3.11.1</string>
+	<key>IFMajorVersion</key>
+	<integer>3</integer>
+	<key>IFMinorVersion</key>
+	<integer>11</integer>
+	<key>IFPkgFlagAllowBackRev</key>
+	<false/>
+	<key>IFPkgFlagAuthorizationAction</key>
+	<string>RootAuthorization</string>
+	<key>IFPkgFlagBackgroundAlignment</key>
+	<string>topleft</string>
+	<key>IFPkgFlagBackgroundScaling</key>
+	<string>none</string>
+	<key>IFPkgFlagDefaultLocation</key>
+	<string>/usr/local/opendap/servers/hyrax-1.7.0</string>
+	<key>IFPkgFlagFollowLinks</key>
+	<true/>
+	<key>IFPkgFlagInstallFat</key>
+	<false/>
+	<key>IFPkgFlagInstalledSize</key>
+	<integer>10000</integer>
+	<key>IFPkgFlagIsRequired</key>
+	<true/>
+	<key>IFPkgFlagOverwritePermissions</key>
+	<false/>
+	<key>IFPkgFlagRelocatable</key>
+	<false/>
+	<key>IFPkgFlagRestartAction</key>
+	<string>NoRestart</string>
+	<key>IFPkgFlagRootVolumeOnly</key>
+	<false/>
+	<key>IFPkgFlagUpdateInstalledLanguages</key>
+	<false/>
+	<key>IFPkgFormatVersion</key>
+	<real>0.10000000149011612</real>
+</dict>
+</plist>
diff --git a/OSX_Resources/Info.plist.proto b/OSX_Resources/Info.plist.proto
new file mode 100644
index 0000000..da051c6
--- /dev/null
+++ b/OSX_Resources/Info.plist.proto
@@ -0,0 +1,46 @@
+<?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">
+<plist version="1.0">
+<dict>
+	<key>CFBundleGetInfoString</key>
+	<string>_FULL_VERSION_, OPeNDAP libdap</string>
+	<key>CFBundleIdentifier</key>
+	<string>org.opendap.libdap</string>
+	<key>CFBundleShortVersionString</key>
+	<string>_FULL_VERSION_</string>
+	<key>IFMajorVersion</key>
+	<integer>_MAJOR_VERSION_</integer>
+	<key>IFMinorVersion</key>
+	<integer>_MINOR_VERSION_</integer>
+	<key>IFPkgFlagAllowBackRev</key>
+	<false/>
+	<key>IFPkgFlagAuthorizationAction</key>
+	<string>RootAuthorization</string>
+	<key>IFPkgFlagBackgroundAlignment</key>
+	<string>topleft</string>
+	<key>IFPkgFlagBackgroundScaling</key>
+	<string>none</string>
+	<key>IFPkgFlagDefaultLocation</key>
+	<string>_PREFIX_</string>
+	<key>IFPkgFlagFollowLinks</key>
+	<true/>
+	<key>IFPkgFlagInstallFat</key>
+	<false/>
+	<key>IFPkgFlagInstalledSize</key>
+	<integer>10000</integer>
+	<key>IFPkgFlagIsRequired</key>
+	<true/>
+	<key>IFPkgFlagOverwritePermissions</key>
+	<false/>
+	<key>IFPkgFlagRelocatable</key>
+	<false/>
+	<key>IFPkgFlagRestartAction</key>
+	<string>NoRestart</string>
+	<key>IFPkgFlagRootVolumeOnly</key>
+	<false/>
+	<key>IFPkgFlagUpdateInstalledLanguages</key>
+	<false/>
+	<key>IFPkgFormatVersion</key>
+	<real>0.10000000149011612</real>
+</dict>
+</plist>
diff --git a/OSX_Resources/InstallationCheck b/OSX_Resources/InstallationCheck
new file mode 100755
index 0000000..9d9b387
--- /dev/null
+++ b/OSX_Resources/InstallationCheck
@@ -0,0 +1,45 @@
+#!/bin/sh
+#
+# Check the architecture
+
+# Check to make sure the computer is running 10.5 or later.
+
+version=`uname -a | sed 's/.*Darwin Kernel Version \([0-9.]*\):.*/\1/'`
+major=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
+minor=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
+
+if test $major -lt 9 -o $major -eq 9 -a $minor -lt 8
+then
+    # Warn and display message 16 (the string displayed will be read from 
+    # InstallationCheck.strings using the exit code minus 32 to select the
+    # specific string).
+    exit 48
+fi
+
+# we need libcurl 7.10.6 according to configure.ac
+version=`curl-config --version | sed 's/libcurl \([0-9.]*\).*/\1/'`
+major=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
+minor=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
+
+if test $major -lt 7 -o $major -eq 7 -a $minor -lt 10
+then
+    # Fail and display message 17 (exit code - 96) (the string displayed 
+    # will be read from InstallationCheck.strings using the exit code 
+    # minus 96 to select the specific string.)
+    exit 113
+fi
+
+# we need libxml2 2.6.16 according to configure.ac
+version=`xml2-config --version | sed 's/\([0-9.]*\).*/\1/'`
+major=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
+minor=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
+
+if test $major -lt 2 -o $major -eq 2 -a $minor -lt 6
+then
+    # Fail and display message 18 (exit code - 96) (the string displayed 
+    # will be read from InstallationCheck.strings using the exit code 
+    # minus 96 to select the specific string.)
+    exit 114
+fi
+
+exit 0
diff --git a/OSX_Resources/InstallationCheck.strings b/OSX_Resources/InstallationCheck.strings
new file mode 100644
index 0000000..cbe0522
--- /dev/null
+++ b/OSX_Resources/InstallationCheck.strings
@@ -0,0 +1,6 @@
+"16" = "This software has not been tested with Mac OS/X versions prior to Panther. Even though the installer says you cannot install the software, you can go ahead and give it a try...";
+"17" = "This software requires the Curl library, vesion 7.10.x or greater";
+"18" = "This software requires the XML2 library, version 2.2.x or greater";
+"19" = "This distribution is for the PowerPC CPU but it appears you have an Intel Mac.";
+"20" = "This distribution is for the Intel CPU but it appears you have a PowerPC Mac.";
+
diff --git a/OSX_Resources/License.txt b/OSX_Resources/License.txt
new file mode 100644
index 0000000..b713790
--- /dev/null
+++ b/OSX_Resources/License.txt
@@ -0,0 +1,177 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE		       
+                     Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.     
+ 59 Temple Place, Suite 330, 
+ Boston, MA  02111-1307  USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away yourfreedom to share and change it.  By contrast, the GNU General PublicLicenses are intended to guarantee your freedom to share and changefree software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to somespecially designated software packages--typically libraries--of theFree Software Foundation and other authors who decide to use it.  Youcan use it too, but we suggest you first think carefully about whetherthis license or the ordinary General Public License is the betterstrategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,not price.  Our General Public Licenses are designed to make sure thatyou have the freedom to distribute copies of free software (and chargefor this service if you wish); that you receive source code or can getit if you want it; that you can change the software and use pieces ofit in new free programs; and that you are informed that you can dothese things.
+
+  To protect your rights, we need to make restrictions that forbiddistributors to deny you these rights or to ask you to surrender theserights.  These restrictions translate to certain responsibilities foryou if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratisor for a fee, you must give the recipients all the rights that we gaveyou.  You must make sure that they, too, receive or can get the sourcecode.  If you link other code with the library, you must providecomplete object files to the recipients, so that they can relink themwith the library after making changes to the library and recompilingit.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright thelibrary, and (2) we offer you this license, which gives you legalpermission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear thatthere is no warranty for the free library.  Also, if the library ismodified by someone else and passed on, the recipients should knowthat what they have is not the original version, so that the originalauthor's reputation will not be affected by problems that might beintroduced by others.
+
+  Finally, software patents pose a constant threat to the existence ofany free program.  We wish to make sure that a company cannoteffectively restrict the users of a free program by obtaining arestrictive license from a patent holder.  Therefore, we insist thatany patent license obtained for a version of the library must beconsistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by theordinary GNU General Public License.  This license, the GNU LesserGeneral Public License, applies to certain designated libraries, andis quite different from the ordinary General Public License.  We usethis license for certain libraries in order to permit linking thoselibraries into non-free programs.
+
+  When a program is linked with a library, whether statically or usinga shared library, the combination of the two is legally speaking acombined work, a derivative of the original library.  The ordinaryGeneral Public License therefore permits such linking only if theentire combination fits its criteria of freedom.  The Lesser GeneralPublic License permits more lax criteria for linking other code withthe library.
+
+  We call this license the "Lesser" General Public License because itdoes Less to protect the user's freedom than the ordinary GeneralPublic License.  It also provides other free software developers Lessof an advantage over competing non-free programs.  These disadvantagesare the reason we use the ordinary General Public License for manylibraries.  However, the Lesser license provides advantages in certainspecial circumstances.
+
+  For example, on rare occasions, there may be a special need toencourage the widest possible use of a certain library, so that it becomesa de-facto standard.  To achieve this, non-free programs must beallowed to use the library.  A more frequent case is that a freelibrary does the same job as widely used non-free libraries.  In thiscase, there is little to gain by limiting the free library to freesoftware only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-freeprograms enables a greater number of people to use a large body offree software.  For example, permission to use the GNU C Library innon-free programs enables many more people to use the whole GNUoperating system, as well as its variant, the GNU/Linux operatingsystem.
+
+  Although the Lesser General Public License is Less protective of theusers' freedom, it does ensure that the user of a program that islinked with the Library has the freedom and the wherewithal to runthat program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution andmodification follow.  Pay close attention to the difference between a"work based on the library" and a "work that uses the library".  Theformer contains code derived from the library, whereas the latter mustbe combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or otherprogram which contains a notice placed by the copyright holder orother authorized party saying it may be distributed under the terms ofthis Lesser General Public License (also called "this License").Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or dataprepared so as to be conveniently linked with application programs(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or workwhich has been distributed under these terms.  A "work based on theLibrary" means either the Library or any derivative work undercopyright law: that is to say, a work containing the Library or aportion of it, either verbatim or with modifications and/or translatedstraightforwardly into another language.  (Hereinafter, translation isincluded without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work formaking modifications to it.  For a library, complete source code meansall the source code for all modules it contains, plus any associatedinterface definition files, plus the scripts used to control compilationand installation of the library.
+
+  Activities other than copying, distribution and modification are notcovered by this License; they are outside its scope.  The act ofrunning a program using the Library is not restricted, and output fromsuch a program is covered only if its contents constitute a work basedon the Library (independent of the use of the Library in a tool forwriting it).  Whether that is true depends on what the Library doesand what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library'scomplete source code as you receive it, in any medium, provided thatyou conspicuously and appropriately publish on each copy anappropriate copyright notice and disclaimer of warranty; keep intactall the notices that refer to this License and to the absence of anywarranty; and distribute a copy of this License along with theLibrary.
+
+  You may charge a fee for the physical act of transferring a copy,and you may at your option offer warranty protection in exchange for afee.
+
+  2. You may modify your copy or copies of the Library or any portionof it, thus forming a work based on the Library, and copy anddistribute such modifications or work under the terms of Section 1above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a    table of data to be supplied by an application program that uses    the facility, other than as an argument passed when the facility    is invoked, then you must make a good faith effort to ensure that,    in the event an application does not supply such function or    table, the facility still operates, and performs whatever part of    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has    a purpose that is entirely well-defined independent of the    application.  Therefore, Subsection 2d requires that any    application-supplied function or table used by this function must    be optional: if the application does not supply it, the square    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  Ifidentifiable sections of that work are not derived from the Library,and can be reasonably considered independent and separate works inthemselves, then this License, and its terms, do not apply to thosesections when you distribute them as separate works.  But when youdistribute the same sections as part of a whole which is a work basedon the Library, the distribution of the whole must be on the terms ofthis License, whose permis [...]
+
+Thus, it is not the intent of this section to claim rights or contestyour rights to work written entirely by you; rather, the intent is toexercise the right to control the distribution of derivative orcollective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Librarywith the Library (or with a work based on the Library) on a volume ofa storage or distribution medium does not bring the other work underthe scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General PublicLicense instead of this License to a given copy of the Library.  To dothis, you must alter all the notices that refer to this License, sothat they refer to the ordinary GNU General Public License, version 2,instead of to this License.  (If a newer version than version 2 of theordinary GNU General Public License has appeared, then you can specifythat version instead if you wish.)  Do not make any other change inthese notices.
+
+  Once this change is made in a given copy, it is irreversible forthat copy, so the ordinary GNU General Public License applies to allsubsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code ofthe Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion orderivative of it, under Section 2) in object code or executable formunder the terms of Sections 1 and 2 above provided that you accompanyit with the complete corresponding machine-readable source code, whichmust be distributed under the terms of Sections 1 and 2 above on amedium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copyfrom a designated place, then offering equivalent access to copy thesource code from the same place satisfies the requirement todistribute the source code, even though third parties are notcompelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of theLibrary, but is designed to work with the Library by being compiled orlinked with it, is called a "work that uses the Library".  Such awork, in isolation, is not a derivative work of the Library, andtherefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Librarycreates an executable that is a derivative of the Library (because itcontains portions of the Library), rather than a "work that uses thelibrary".  The executable is therefore covered by this License.Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header filethat is part of the Library, the object code for the work may be aderivative work of the Library even though the source code is not.Whether this is true is especially significant if the work can belinked without the Library, or if the work is itself a library.  Thethreshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, datastructure layouts and accessors, and small macros and small inlinefunctions (ten lines or less in length), then the use of the objectfile is unrestricted, regardless of whether it is legally a derivativework.  (Executables containing this object code plus portions of theLibrary will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you maydistribute the object code for the work under the terms of Section 6.Any executables containing that work also fall under Section 6,whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine orlink a "work that uses the Library" with the Library to produce awork containing portions of the Library, and distribute that workunder terms of your choice, provided that the terms permitmodification of the work for the customer's own use and reverseengineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that theLibrary is used in it and that the Library and its use are covered bythis License.  You must supply a copy of this License.  If the workduring execution displays copyright notices, you must include thecopyright notice for the Library among them, as well as a referencedirecting the user to the copy of this License.  Also, you must do oneof these things:
+
+    a) Accompany the work with the complete corresponding    machine-readable source code for the Library including whatever    changes were used in the work (which must be distributed under    Sections 1 and 2 above); and, if the work is an executable linked    with the Library, with the complete machine-readable "work that    uses the Library", as object code and/or source code, so that the    user can modify the Library and then relink to produce a modified    executable containing th [...]
+
+    b) Use a suitable shared library mechanism for linking with the    Library.  A suitable mechanism is one that (1) uses at run time a    copy of the library already present on the user's computer system,    rather than copying library functions into the executable, and (2)    will operate properly with a modified version of the library, if    the user installs one, as long as the modified version is    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at    least three years, to give the same user the materials    specified in Subsection 6a, above, for a charge no more    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy    from a designated place, offer equivalent access to copy the above    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses theLibrary" must include any data and utility programs needed forreproducing the executable from it.  However, as a special exception,the materials to be distributed need not include anything that isnormally distributed (in either source or binary form) with the majorcomponents (compiler, kernel, and so on) of the operating system onwhich the executable runs, unless that component itself accompaniesthe executable.
+
+  It may happen that this requirement contradicts the licenserestrictions of other proprietary libraries that do not normallyaccompany the operating system.  Such a contradiction means you cannotuse both them and the Library together in an executable that youdistribute.
+
+  7. You may place library facilities that are a work based on theLibrary side-by-side in a single library together with other libraryfacilities not covered by this License, and distribute such a combinedlibrary, provided that the separate distribution of the work based onthe Library and of the other library facilities is otherwisepermitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work    based on the Library, uncombined with any other library    facilities.  This must be distributed under the terms of the    Sections above.
+
+    b) Give prominent notice with the combined library of the fact    that part of it is a work based on the Library, and explaining    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distributethe Library except as expressly provided under this License.  Anyattempt otherwise to copy, modify, sublicense, link with, ordistribute the Library is void, and will automatically terminate yourrights under this License.  However, parties who have received copies,or rights, from you under this License will not have their licensesterminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have notsigned it.  However, nothing else grants you permission to modify ordistribute the Library or its derivative works.  These actions areprohibited by law if you do not accept this License.  Therefore, bymodifying or distributing the Library (or any work based on theLibrary), you indicate your acceptance of this License to do so, andall its terms and conditions for copying, distributing or modifyingthe Library or works base [...]
+
+  10. Each time you redistribute the Library (or any work based on theLibrary), the recipient automatically receives a license from theoriginal licensor to copy, distribute, link with or modify the Librarysubject to these terms and conditions.  You may not impose any furtherrestrictions on the recipients' exercise of the rights granted herein.You are not responsible for enforcing compliance by third parties withthis License.
+
+  11. If, as a consequence of a court judgment or allegation of patentinfringement or for any other reason (not limited to patent issues),conditions are imposed on you (whether by court order, agreement orotherwise) that contradict the conditions of this License, they do notexcuse you from the conditions of this License.  If you cannotdistribute so as to satisfy simultaneously your obligations under thisLicense and any other pertinent obligations, then as a consequence youmay not distrib [...]
+
+If any portion of this section is held invalid or unenforceable under anyparticular circumstance, the balance of the section is intended to apply,and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe anypatents or other property right claims or to contest validity of anysuch claims; this section has the sole purpose of protecting theintegrity of the free software distribution system which isimplemented by public license practices.  Many people have madegenerous contributions to the wide range of software distributedthrough that system in reliance on consistent application of thatsystem; it is up to the author/donor to de [...]
+
+This section is intended to make thoroughly clear what is believed tobe a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted incertain countries either by patents or by copyrighted interfaces, theoriginal copyright holder who places the Library under this License may addan explicit geographical distribution limitation excluding those countries,so that distribution is permitted only in or among countries not thusexcluded.  In such case, this License incorporates the limitation as ifwritten in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or newversions of the Lesser General Public License from time to time.Such new versions will be similar in spirit to the present version,but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Libraryspecifies a version number of this License which applies to it and"any later version", you have the option of following the terms andconditions either of that version or of any later version published bythe Free Software Foundation.  If the Library does not specify alicense version number, you may choose any version ever published bythe Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other freeprograms whose distribution conditions are incompatible with these,write to the author to ask for permission.  For software which iscopyrighted by the Free Software Foundation, write to the FreeSoftware Foundation; we sometimes make exceptions for this.  Ourdecision will be guided by the two goals of preserving the free statusof all derivatives of our free software and of promoting the sharingand reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NOWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OROTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANYKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULARPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THELIBRARY IS WITH YOU.  SHO [...]
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO INWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFYAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOUFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL ORCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THELIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEINGRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR AFAILURE OF THE LIBRARY TO OPERA [...]
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatestpossible use to the public, we recommend making it free software thateveryone can redistribute and change.  You can do so by permittingredistribution under these terms (or, alternatively, under the terms of theordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It issafest to attach them to the start of each source file to most effectivelyconvey the exclusion of warranty; and each file should have at least the"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 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    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or yourschool, if any, to sign a "copyright disclaimer" for the library, ifnecessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
diff --git a/OSX_Resources/ReadMe.txt b/OSX_Resources/ReadMe.txt
new file mode 100644
index 0000000..612796a
--- /dev/null
+++ b/OSX_Resources/ReadMe.txt
@@ -0,0 +1,237 @@
+Updated for version 3.11.1
+
+Bug fixes only.
+
+Updated for version 3.11.0
+
+Now constraint expressions can have multiple function calls that return data.
+
+I've bumped up the DAP version from 3.3 to 3.4 to reflect this change.
+
+Updated for Version 3.10.2
+
+BaseType::transfer_attributes() and related methods provide a way forhandlers to customize how attributes from a DAS object are merged intoa DDS.
+
+In the past we supported a kind of client-side system that could augmentthe attributes call the 'AIS' (Ancillary Information System). This hasbeen removed - our server now supports the NcML language to do much the samething but in a way that can be set on the server once for all users. It's alsoan emerging convention that's gaining wide support within the community.
+
+Updated for Version 3.10.0
+
+DAP 3.3 is now supported; see http://docs.opendap.org/index.php/DAP3/4.
+
+This version of libdap contains many changes that are needed for bothDAP 4 and the NcML handler. This version of the library is requiredfor the Hyrax 1.6 handlers.
+
+The 'deflate' program is no longer part of this library package sincewe are no longer supporting the old data server system (based on WWW'sCGI specification).
+
+Updated for version 3.9.2
+
+Now libdap supports DAP 3.2. You can read about the evolving DAP 3.x protocolat http://docs.opendap.org/index.php/DAP3/4. If your client sends theXDAP-Accept header with a value of 3.2 the DDX is different (it includesprotocol information and also an xmlbase element).
+
+Behavior change for the DAS: In the past the format handlers added doublequotes to the values of string attributes when they added those values to theAttrTable object. This meant that the value of the attribute in the C++object was actually not correct since it contained quotes not found in theoriginal attribute value. I modified libdap so that if an attribute value inthe C++ AttrTable object does not have quotes then those quotes are addedwhen the value is output in a DAS response (but  [...]
+
+If you have a handler and it's not adding quotes to the String attribute values - good, don't change that! If your handler does add quotes, pleasemodify it so the DDX will be correct.  
+
+Our handler's old, broken, behavior can be resurrected by removing the ATTR_STRING_QUOTE FIX define in the appropriate files.
+
+Updated for version 3.8.2 (23 June 2008)
+
+HTTP Cache and win32 installer fixes (the latter are actually in the 3.8.1installer for winXP). API change: The functions used to merge ancillary datahave been moved to their own class (Ancillary).
+
+Updated for version 3.8.1 (10 June 2008)
+
+The syntax for PROXY_SERVER in the .dodsrc file was relaxed. See the .dodsrcfile for more information.
+
+Updated for Version 3.8.0 (29 February 2008)
+
+The libdap classes and code are now inside of the libdap namespace. In orderto access any of the classes, for example, you will need to do one of thefollowing. After including the libdap headers you can:
+
+1. add a using statement for the entire libdap namespace:
+
+using namespace libdap ;
+
+2. add a using statement for the classes that you will be using:
+
+using libdap::DAS ;
+
+3. inside your code scope the use of libdap classes.
+
+libdap::DAS *das = code_to_get_das() ;
+
+Added method to HTTPCache to return not only the FILE pointer of a cachedresponse but also the name of the file in the cache, to allow for this filename to be passed to data handlers in the BES to be read.
+
+See NEWS for more information about changes for this version and ChangeLogfor the gory details.
+
+Updated for Version 3.7.10 (28 November 2007)
+
+A bug fix release. See NEWS.
+
+Updated for Version 3.7.9 (13 November 2007)
+
+This release is a bug fix and refactoring release. Old classes which were nolonger used have been removed, the FILE* output methods are slated to bereplaced with ones which will use iostream and will support a chuckedtransfer 'Marshaller,' and the transfer_data() methods have been made aformal part of the library, implemented for all classes, fixed and renamed tointern_data(). Many bugs in the library were also fixed.
+
+Updated for version 3.7.8 (26 June 2007)
+
+The major fixes in this version are memory errors found and fixed in theRegex class and HTTP header processing software. This version also supportspkg-config on hosts that have that installed.
+
+See NEWS for more information about changes for this version and ChangeLogfor the gory details.
+
+Notes for version 3.7.7 (2 May 2007)
+
+The major fix here is to the source build. We've fixed the issue where sourcebuilds failed to make the dapserver and dapclient libraries.
+
+Notes for version 3.7.6 (12 March 2007)
+
+Two bug fixes, both minor. Problems in the linear_scale() constraintexpression function and a bad/missing #include in GNURegex.h were fixed.
+
+There was an error in the INSTALL file sent out in the previous release. Itsaid this library implemented DAP version 3.2, but in fact it implementsversion 3.1. The version 3.2 release will be along soon (RSN).
+
+Notes for version 3.7.5 (7 Feb 2007)
+
+This version includes many fixes from the first Server4 beta releaseplus fixes for the server-side functions. It also includes a smootherWin32 build.
+
+Notes for version 3.7.4 (2 Jan 2007)
+
+Release for the Server4 beta release.
+
+Notes for version 3.7.3 (24 Nov 2006)
+
+This version of libdap contains a beta release of the server-side functionsgeogrid(), geoarray(), linear_scale() and version(). These can be used toselect parts of Grids and Arrays using latitude and longitude values insteadof array position indexes. The linear_scale() function can be used to scalevariables (including those return by other function) using 'y = mx + b'. Theversion() function can be used to find out which versions of the functions areinstalled.
+
+EXAMPLES
+
+To get version information use the 'version()' function. Currently, version()can only be called when asking for data, and you must give the name of a datasource, although in the default version of version() the data source is notused. The version function takes one optional argument which may be the strings'help' or 'xml'. Use 'help' to get help on using the function; use 'xml' to getversion information encoded using XML instead of plain text:
+
+[jimg at zoe libdap]$ url=http://test.opendap.org/dap/data/nc/coads_climatology.nc
+[jimg at zoe libdap]$ ./getdap -D "$url?version()"
+The data:
+String version = "Function set: version 1.0, grid 1.0, geogrid 1.0b2, 
+		          geoarray 0.9b1, linear_scale 1.0b1";
+
+[jimg at zoe libdap]$ ./getdap -D "$url?version(help)"
+The data:
+String version = "Usage: version() returns plain text information about ...
+
+[jimg at zoe libdap]$ ./getdap -D "$url?version(xml)"
+The data:
+String version = "<?xml version=\"1.0\"?>
+    <functions>
+        <function name=\"version\" version=\"1.0\"/>
+        <function name=\"grid\" version=\"1.0\"/>
+        <function name=\"geogrid\" version=\"1.0\"/>
+        <function name=\"geoarray\" version=\"1.0\"/>
+        <function name=\"linear_scale\" version=\"1.0\"/>
+    </functions>";
+
+The geogrid function can only be used with variables that are Grids:
+
+[jimg at zoe libdap]$ getdap -d "$url"
+Dataset {
+    Float64 COADSX[COADSX = 180];
+    Float64 COADSY[COADSY = 90];
+    Float64 TIME[TIME = 12];
+    Grid {
+      Array:
+        Float32 SST[TIME = 12][COADSY = 90][COADSX = 180];
+      Maps:
+        Float64 TIME[TIME = 12];
+        Float64 COADSY[COADSY = 90];
+        Float64 COADSX[COADSX = 180];
+    } SST;
+    Grid {
+    .
+    .
+    .
+
+
+Pass the name of the Grid variable and the upper-left and lower-right corners of the lat/lon rectangle to geogrid. Optionally, pass one or more relationalexpressions to select parts of dimensions that are not lat/lon. 
+
+Note: in libdap 3.7.3 calling geogrid with a constraint on each dimensionmay return incorrect values that indicate missing data even though data shouldhave been returned.
+
+[jimg at zoe libdap]$ getdap -D "$url?geogrid(SST,30,-60,20,-60,\"TIME=366\")"
+The data:
+Grid {
+  Array:
+    Float32 SST[TIME = 1][COADSY = 7][COADSX = 2];
+  Maps:
+    Float64 TIME[TIME = 1];
+    Float64 COADSY[COADSY = 7];
+    Float64 COADSX[COADSX = 2];
+} SST = {  Array: {{{24.4364, 25.0923},{23.7465, 24.4146},{19.843, 23.6033},
+{16.8464, 17.7756},{16.65, 16.818},{-1e+34, 15.3656},{18.7214, 13.1286}}}  
+Maps: {366}, {19, 21, 23, 25, 27, 29, 31}, {-61, -59} };
+
+
+The geoarray() function works like geogrid() except that it's used to selectfrom an Array variable and not a Grid. In addition to the four lat/lon valuesfor selection rectangle, the caller must supply the data's corner points. A subsequent release of libdap will include a version that reads the data extentfrom the data source when possible so caller's won't normally have to know thedata's extent ahead of time.
+
+The linear_scale() function take either one or three arguments. The first(only) argument is the name of a variable or the return from anotherfunction. This variable will be scaled using the 'y = mx + b' equation where'x' is the value(s) of the input variable and 'm' and 'b' are read from thedata source using the values of attributes name 'scale_factor' and'add_offset.' If these are not present, or to over ride their values, m and bcan be supplied using the second and third arguments.
+
+Note that there are still some problems with linear_scale() in this release.
+
+See NEWS and ChangeLog for information about other changes
+
+Notes for version 3.7.2
+
+This version of libdap is required for the 9/15/06 alpha release of Server4.The library now contains software which enables Server4 to build the ASCIIdata response for all types of variables, including Sequence and nestedSequence variables. These features are additions to the API, so older codewill work just fine with the new library. See NEWS for more specific infoabout bug fixes.
+
+Notes for version 3.7.1
+
+This is a bug fix release (mostly) made for users of the netcdf clientlibrary who need a fix for a problem dealing with attributes from the HDF4server. 
+
+NOTES for version 3.7.0
+
+This version includes new features and an implementation change.
+
+This version of libdap now returns the DAP protocol version number, 3.1, inan HTTP response header. Use this to determine which protocol version thelibrary implements. The inclusion of a protocol version number is the soleofficial new feature of DAP 3.1. Use Connect::get_protocol() to get theversion number. Clients can use this to determine the features supported by aserver. The Connect::get_version() method can still be used to get ourserver's implementation version. The distinction is  [...]
+
+The libdap library now contains an implementation of the DDX object/response,although this is an alpha implementation and it's actually been part of thelibrary for some time now. The implementation contained in this version ofthe library is close enough to the version we intend for DAP4 that developerscan start to use it. Most of the server handlers will return DDXs when asked.
+
+The DDX combines the information previously held by the DDS and DAS objects,making it much easier to associate attributes to variables. As the namesuggests, the DDX uses XML rather than curly-braces. You can drop the DDXinto your favorite XML parser and get a DOM tree; no need to use our parsers.However, libdap contains a nice SAX parser that will build the libdap objectsdirectly from the XML DDX object/response. Also included in libdap aremethods to build a DDX using a DDS and DAS, so t [...]
+
+Finally, the library contains two structural changes. First, the librarynamed 'libdap' now holds the DAP implementation while two new libraries,'libdapclient' and 'libdapserver', now hold the client and server helperclasses which are not strictly part of the DAP. Secondly, the DDS/DDX objectnow takes the constraint evaluator as a parameter. The classConstraintEvaluator holds our default evaluator, but it's now possible to useyour own evaluator .
+
+NOTES for version 3.6.1
+
+Version 3.6.1 is bug fix release.
+
+NOTES for version 3.6.0
+
+This version of the library may not work older source code. Many of the deprecated methods have been removed. 
+
+Added are headers which send information about the version of the DAP protocolthat the library implements (in contrast to the implementation of the libraryitself). A new header named XOPeNDAP-Server is used to send information aboutthe implementation of servers.
+
+The libtool interface version has been incremented from 3 to 4 (these versionsdo no track the software's release version since several releases might present compatible binary interfaces). 
+
+NOTES for version 3.5.3
+
+This version of libdap++ cannot be used to build the 3.4.x and previousclients and/or servers. However, client and servers built using this code_will_ work with the older clients and servers.
+
+WHAT'S IN THIS DIRECTORY?
+
+This directory contains the OPeNDAP C++ implementation of the DataAccess Protocol version 2 (DAP2) with some extensions that will bepart of DAP3.  Documentation for this software can be found on theOPeNDAP home page at http://www.opendap.org/. The NASA/ESE RFC whichdescribes DAP2, implemented by the library, can be found athttp://spg.gsfc.nasa.gov/rfc/004/.
+
+The DAP2 is used to provide a uniform way of accessing a variety ofdifferent types of data across the Internet. It was originally part ofthe DODS and then NVODS projects. The focus of those projects wasaccess to Earth-Science data, so much of the software developed usingthe DAP2 to date has centered on that discipline. However, the DAP2data model is very general (and similar to a modern structuredprogramming language) so it can be applied to a wide variety offields.
+
+The DAP2 is implemented as a set of C++ classes that can be used tobuild data servers and clients. The classes may be specialized tomimic the behavior of other data access APIs, such as netCDF. In thisway, programs originally meant to work with local data in thoseformats can be re-linked and equipped to work with data storedremotely in many different formats.  The classes can also byspecialized to build standalone client programs.
+
+The DAP2 is contained in a single library: libdap++.a. Also includedin the library are classes and utility functions which simplifybuilding clients and servers.
+
+WHAT ELSE IS THERE?
+
+The file README.dodsrc describes the client-side behavior which can becontrolled using the .dodsrc file. This includes client-side caching,proxy servers, et c., and is described in a separate file so it's easyto include in your clients.
+
+The file README.AIS describes the prototype Ancillary InformationService (AIS) included in this version of the library. The AIS is(currently) a client-side capability which provides a way to augmentDAP attributes. This is a very useful feature because it can be usedto add missing metadata to a data source. The AIS is accessed by usingthe AISConnect class in place of Connect in your client.
+
+This directory also contains test programs for the DAP2, a samplespecialization of the classes, getdap (a useful command-line webclient created with DAP2) and dap-config (a utility script to simplifylinking with libdap.a). Also included as of version 3.5.2 islibdap.m4, an autoconf macro which developers can use along withautoconf to test for libdap. This macro will be installed in${prefix}/share/aclocal and can be by any package which uses autoconffor its builds. See the file for more in [...]
+
+We also have Java and C versions of the DAP2 library whichinter-operate with software which uses this library. In other words,client programs built with the Java DAP2 implementation cancommunicate with servers built with this (C++) implementation of theDAP2. The C DAP2 library, called the Ocapi, only implements theclient-side part of the protocol. Clients written using the Ocapi areinteroperable with both the Java and C++ DAP2 libraries. Note that theOcapi is in early beta and available  [...]
+
+THREAD SAFETY
+
+We don't need to do this since the STL is also not thread safe. Usersof libdap have to be sure that multiple threads never makesimultaneous and/or overlapping calls to a single copy of libdap. Ifseveral threads are part of a program and each will make calls tolibdap, either those threads must synchronize their calls or arrangeto each use their own copy of libdap.  Some aspects of the library''are'' thread-safe: the singleton classes are all protected as is theHTTP cache (which uses the l [...]
+
+INSTALLATION INSTRUCTIONS
+
+See the file INSTALL in this directory for information on building thelibrary and the geturl client.
+
+COPYRIGHT INFORMATION
+
+The OPeNDAP DAP library is copyrighted using the GNU Lesser GPL. Seethe file COPYING or contact the Free Software Foundation, Inc., at 59Temple Place, Suite 330, Boston, MA 02111-1307 USA. Older versions ofthe DAP were copyrighted by the University of Rhode Island andMassachusetts Institute of Technology; see the file COPYRIGHT_URI. Thefile deflate.c is also covered by COPYRIGHT_W3C.
\ No newline at end of file
diff --git a/OSX_Resources/Welcome.html b/OSX_Resources/Welcome.html
new file mode 100644
index 0000000..1383d92
--- /dev/null
+++ b/OSX_Resources/Welcome.html
@@ -0,0 +1,23 @@
+<h2>About the OPeNDAP DAP2 C++ Library Package</h2>
+
+<p>This package contains the OPeNDAP C++ implementation of the Data
+Access Protocol version 2 (DAP2) with some extensions that will be
+part of DAP3. Documentation for this software can be found on the
+OPeNDAP home page at <tt>http://www.opendap.org/</tt>. The NASA/ESE
+RFC which describes DAP2, implemented by the library, can be found at
+<tt>http://www.esdswg.org/spg/rfc/ese-rfc-004</tt>.</p>
+
+<p>The DAP2 is used to provide a uniform way of accessing a variety of
+different types of data across the Internet. It was originally part of
+the DODS and then NVODS projects. The focus of those projects was
+access to Earth-Science data, so much of the software developed using
+the DAP2 to date has centered on that discipline. However, the DAP2
+data model is very general (and similar to a modern structured
+programming language) so it can be applied to a wide variety of
+fields.</p>
+
+<p>This package is required for many of the other Mac OS/X packages
+  OPeNDAP has written. By default it will use <tt>/usr</tt> as the
+  base directory for installation. If you change the default
+  installation prefix, be sure to modify the PATH environment variable
+  accordingly.</p>
diff --git a/OSX_Resources/background.jpg b/OSX_Resources/background.jpg
new file mode 100644
index 0000000..ef5e26b
Binary files /dev/null and b/OSX_Resources/background.jpg differ
diff --git a/OSX_Resources/macify_license_file.pl b/OSX_Resources/macify_license_file.pl
new file mode 100755
index 0000000..36e24d2
--- /dev/null
+++ b/OSX_Resources/macify_license_file.pl
@@ -0,0 +1,36 @@
+#!/usr/bin/perl
+#
+
+use strict 'vars';
+
+unix2mac("COPYING", "OSX_Resources/License.txt");
+
+# Read a textfile where each line is terminated by a newline and
+# paragraphs are terminated by an otherwise blank line. Write the text
+# out without those pesky line-terminating newlines.
+sub unix2mac {
+  my ($infile_name, $outfile_name) = @_;
+
+  open IN, $infile_name or die("Could not open $infile_name!\n");
+  open OUT, ">$outfile_name" 
+    or die("Could not open output for $outfile_name!\n");
+
+  my $code = 0;
+
+  while (<IN>) {
+    if ( /^<code>\s*$/ ) {
+      $code = 1;
+    } elsif ( /^<\/code>\s*$/ ) {
+      $code = 0;
+    } elsif ( $code eq 1 ) {
+      print OUT $_ ;
+    } elsif ( /^\s*$/ ) {
+      print OUT "\n\n" ;	# Blank line
+    } else {
+      chomp $_ ; print OUT $_ ; # Character line
+    }
+  }
+
+  close IN;
+  close OUT;
+}
diff --git a/OSX_Resources/update_mac_package_contents.pl b/OSX_Resources/update_mac_package_contents.pl
new file mode 100755
index 0000000..254dcbf
--- /dev/null
+++ b/OSX_Resources/update_mac_package_contents.pl
@@ -0,0 +1,43 @@
+#!/usr/bin/perl
+#
+
+use strict 'vars';
+my $debug = 0;
+
+my $readme = $ARGV[0];
+my $version_file = $ARGV[1];
+my $package_dir = $ARGV[2];
+
+unix2mac($readme, "OSX_Resources/ReadMe.txt");
+
+##################################################################
+# Read a textfile where each line is terminated by a newline and
+# paragraphs are terminated by an otherwise blank line. Write the text
+# out without those pesky line-terminating newlines.
+sub unix2mac {
+  my ($infile_name, $outfile_name) = @_;
+
+  open IN, $infile_name or die("Could not open $infile_name!\n");
+  open OUT, ">$outfile_name" 
+    or die("Could not open output for $outfile_name!\n");
+
+  my $code = 0;
+
+  while (<IN>) {
+    if ( /^<code>\s*$/ ) {
+      $code = 1;
+    } elsif ( /^<\/code>\s*$/ ) {
+      $code = 0;
+    } elsif ( $code eq 1 ) {
+      print OUT $_ ;
+    } elsif ( /^\s*$/ ) {
+      print OUT "\n\n" ;	# Blank line
+    } else {
+      # the [\015] is the DOS ^M character.
+      chomp $_ ; tr/[\015]/ / ; print OUT $_ ; # Character line
+    }
+  }
+
+  close IN;
+  close OUT;
+}
diff --git a/ObjectType.h b/ObjectType.h
new file mode 100644
index 0000000..fdda7f7
--- /dev/null
+++ b/ObjectType.h
@@ -0,0 +1,73 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _object_type_h
+#define _object_type_h
+
+namespace libdap
+{
+
+/** When a version 2.x or greater DAP data server sends an object, it uses
+    the Content-Description header of the response to indicate the type of
+    object contained in the response. During the parse of the header a member
+    of Connect is set to one of these values so that other mfuncs can tell
+    the type of object without parsing the stream themselves.
+
+    <pre>
+     enum ObjectType {
+       unknown_type,
+       dods_das,
+       dods_dds,
+       dods_data,
+       dods_error,
+       web_error,
+       dods_ddx,
+       dap4_ddx,
+       dap4_data,
+       dap4_error,
+       dap4_data_ddx
+     };
+     </pre>
+
+    @brief The type of object in the stream coming from the data
+    server.  */
+
+enum ObjectType {
+    unknown_type,
+    dods_das,
+    dods_dds,
+    dods_data,
+    dods_error,
+    web_error,
+    dap4_ddx,		// This describes the DDX part of the data_ddx response
+    dap4_data,		// The Data part of the data_ddx
+    dap4_error,
+    dap4_data_ddx,	// This is the description for the whole data_ddx
+    dods_ddx	   	// This is the old value used prior to dap4
+};
+
+} // namespace libdap
+
+#endif
diff --git a/Operators.h b/Operators.h
new file mode 100644
index 0000000..58fa1de
--- /dev/null
+++ b/Operators.h
@@ -0,0 +1,276 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Templates for relational operations.
+//
+// jhrg 3/24/99
+
+#ifndef _operators_h
+#define _operators_h
+
+
+#include "GNURegex.h"  // GNU Regex class used for string =~ op.
+#include "parser.h"  // for ID_MAX
+#include "ce_expr.tab.hh"
+
+using namespace std;
+
+namespace libdap
+{
+
+inline unsigned
+dods_max(int i1, int i2)
+{
+    return (unsigned)((i1 > i2) ? i1 : i2);
+}
+
+/** Compare two numerical types, both of which are either signed or unsigned.
+    This class is one implementation of the comparison policy used by
+    rops.
+
+    @see rops
+    @see USCmp
+    @see SUCmp */
+template<class T1, class T2> class Cmp
+{
+public:
+    static bool eq(T1 v1, T2 v2)
+    {
+        return v1 == v2;
+    }
+    static bool ne(T1 v1, T2 v2)
+    {
+        return v1 != v2;
+    }
+    static bool gr(T1 v1, T2 v2)
+    {
+        return v1 > v2;
+    }
+    static bool ge(T1 v1, T2 v2)
+    {
+        return v1 >= v2;
+    }
+    static bool lt(T1 v1, T2 v2)
+    {
+        return v1 < v2;
+    }
+    static bool le(T1 v1, T2 v2)
+    {
+        return v1 <= v2;
+    }
+    static bool re(T1, T2)
+    {
+        cerr << "Illegal operation" << endl;
+        return false;
+    }
+};
+
+/** Compare two numerical types, the first one unsigned and the second
+    signed. If the signed argument is negative, zero is used in the
+    comparison. This class is one implementation of the comparison policy
+    used by rops.
+
+    @see rops
+    @see SUCmp
+    @see Cmp */
+template<class UT1, class T2> class USCmp
+{
+public:
+    static bool eq(UT1 v1, T2 v2)
+    {
+        return v1 == dods_max(0, v2);
+    }
+    static bool ne(UT1 v1, T2 v2)
+    {
+        return v1 != dods_max(0, v2);
+    }
+    static bool gr(UT1 v1, T2 v2)
+    {
+        return v1 > dods_max(0, v2);
+    }
+    static bool ge(UT1 v1, T2 v2)
+    {
+        return v1 >= dods_max(0, v2);
+    }
+    static bool lt(UT1 v1, T2 v2)
+    {
+        return v1 < dods_max(0, v2);
+    }
+    static bool le(UT1 v1, T2 v2)
+    {
+        return v1 <= dods_max(0, v2);
+    }
+    static bool re(UT1, T2)
+    {
+        cerr << "Illegal operation" << endl;
+        return false;
+    }
+};
+
+/** Compare two numerical types, the first one signed and the second
+    unsigned. If the signed argument is negative, zero is used in the
+    comparison. This class is one implementation of the comparison policy
+    used by rops. This class is here to make writing the Byte::ops, ...
+    member functions simpler. It is not necessary since the functions could
+    twiddle the order of arguments to rops and use <tt>USCmp</tt>. Having
+    this class make Byte:ops, ... simpler to read and write.
+
+    @see Byte::ops
+    @see USCmp
+    @see Cmp
+    @see ops */
+template<class T1, class UT2> class SUCmp
+{
+public:
+    static bool eq(T1 v1, UT2 v2)
+    {
+        return dods_max(0, v1) == v2;
+    }
+    static bool ne(T1 v1, UT2 v2)
+    {
+        return dods_max(0, v1) != v2;
+    }
+    static bool gr(T1 v1, UT2 v2)
+    {
+        return dods_max(0, v1) > v2;
+    }
+    static bool ge(T1 v1, UT2 v2)
+    {
+        return dods_max(0, v1) >= v2;
+    }
+    static bool lt(T1 v1, UT2 v2)
+    {
+        return dods_max(0, v1) < v2;
+    }
+    static bool le(T1 v1, UT2 v2)
+    {
+        return dods_max(0, v1) <= v2;
+    }
+    static bool re(T1, UT2)
+    {
+        cerr << "Illegal operation" << endl;
+        return false;
+    }
+};
+
+/** Compare two string types.
+    This class is one implementation of the comparison policy used by
+    rops.
+
+    @see rops */
+template<class T1, class T2> class StrCmp
+{
+public:
+    static bool eq(T1 v1, T2 v2)
+    {
+        return v1 == v2;
+    }
+    static bool ne(T1 v1, T2 v2)
+    {
+        return v1 != v2;
+    }
+    static bool gr(T1 v1, T2 v2)
+    {
+        return v1 > v2;
+    }
+    static bool ge(T1 v1, T2 v2)
+    {
+        return v1 >= v2;
+    }
+    static bool lt(T1 v1, T2 v2)
+    {
+        return v1 < v2;
+    }
+    static bool le(T1 v1, T2 v2)
+    {
+        return v1 <= v2;
+    }
+    static bool re(T1 v1, T2 v2)
+    {
+        Regex r(v2.c_str());
+        return r.match(v1.c_str(), v1.length()) > 0;
+    }
+};
+
+/** This template function is used to compare two values of two instances of
+    the DAP2 simple types (Byte, ..., Str). The function does not take the
+    DAP2 objects as arguments; the caller must access the values of those
+    objects and pass them to this function. The reason for this is that all
+    the possible functions that could be generated from this template would
+    have to be explicitly listed as friend functions in each of the DAP2
+    simple type classes. In the current implementation, only the simple type
+    classes must be friends - to see why, look at Byte::ops and note that it
+    accesses the <tt>_buf</tt> member of Int16, ..., Float64 and thus must be a
+    friend of those classes.
+
+    NB: This would all be simpler if: 1) g++ supported template friend
+    functions (without explicit listing of all the template's arguments). 2)
+    we did not have unsigned types.
+
+    T1 The type of <tt>a</tt>.
+
+    T2 The type of <tt>b</tt>.
+
+    C A class which implements the policy used for comparing <tt>a</tt>
+    and <tt>b</tt>.
+
+    @param a The first argument.
+    @param b The second argument.
+    @param op The relational operator.
+    @see Byte::ops */
+
+template<class T1, class T2, class C>
+bool rops(T1 a, T2 b, int op)
+{
+    switch (op) {
+    case SCAN_EQUAL:
+        return C::eq(a, b);
+    case SCAN_NOT_EQUAL:
+        return C::ne(a, b);
+    case SCAN_GREATER:
+        return C::gr(a, b);
+    case SCAN_GREATER_EQL:
+        return C::ge(a, b);
+    case SCAN_LESS:
+        return C::lt(a, b);
+    case SCAN_LESS_EQL:
+        return C::le(a, b);
+    case SCAN_REGEXP:
+        return C::re(a, b);
+    default:
+        cerr << "Unknown operator" << endl;
+        return false;
+    }
+}
+
+} // namespace libdap
+
+#endif // _operators_h
diff --git a/PipeResponse.h b/PipeResponse.h
new file mode 100644
index 0000000..bb720fc
--- /dev/null
+++ b/PipeResponse.h
@@ -0,0 +1,92 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef pipe_response_h
+#define pipe_response_h
+
+#include <cstdio>
+
+#ifndef response_h
+#include "Response.h"
+#endif
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+using namespace std;
+
+namespace libdap
+{
+
+/** @brief Encapsulate a response.
+    This class provides special treatment for 'stream pipes.' It arranges
+    to close them using pclose() instead of fclose(). */
+class PipeResponse: public Response
+{
+private:
+    FILE *d_pstream;
+
+protected:
+
+public:
+    /** @brief Initialize with a stream returned by popen().
+      
+        Create an instance initialized to a stream returned by
+	popen(). By default get_type() and get_version() return
+	default values of unknown_type and "dods/0.0", respectively.
+	Note that this class closes the stream.
+        
+        @note Since Unix provides no easy way to differentiate between a 
+        FILE* returned by fopen() or popen(), you're on your own here. Make
+        sure you use the correct type of FILE Pointer. 
+        
+        @see Response
+        
+        @param s Pointer to a pipe stream returned by popen().
+        */
+    PipeResponse(FILE *s) : Response(0), d_pstream(s)
+    {}
+
+    /** Close the stream. */
+    virtual ~PipeResponse()
+    {
+        if (d_pstream)
+            pclose(d_pstream);
+    }
+
+    virtual FILE *get_stream() const
+    {
+        return d_pstream;
+    }
+    virtual void set_stream(FILE *s)
+    {
+        d_pstream = s;
+    }
+};
+
+} // namespace libdap
+
+#endif // pipe_response_h
diff --git a/RCReader.cc b/RCReader.cc
new file mode 100644
index 0000000..780f7b2
--- /dev/null
+++ b/RCReader.cc
@@ -0,0 +1,498 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Jose Garcia <jgarcia at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 2001,2002
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+// jose Jose Garcia <jgarcia at ucar.edu>
+
+/** A singleton which reads and parses the .dodsrc file. This code was
+    extracted from Connect (which has since changed considerably).
+
+    @author: jose */
+
+// #define DODS_DEBUG
+#include "config.h"
+
+#include <cstring>
+#include <cstdlib>
+
+#include <unistd.h>  // for stat
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+#define FALSE 0
+// Win32 does not define F_OK. 08/21/02 jhrg
+#define F_OK 0
+#define DIR_SEP_STRING "\\"
+#define DIR_SEP_CHAR   '\\'
+#include <direct.h>
+#else
+#define DIR_SEP_STRING "/"
+#define DIR_SEP_CHAR   '/'
+#endif
+
+#include <pthread.h>
+
+#include <fstream>
+
+#include "debug.h"
+#include "RCReader.h"
+#include "Error.h"
+
+using namespace std;
+
+namespace libdap {
+
+RCReader* RCReader::_instance = 0;
+
+// This variable (instance_control) is used to ensure that in a MT
+// environment _instance is correctly initialized. See the get_instance
+// method. 08/07/02 jhrg
+static pthread_once_t instance_control = PTHREAD_ONCE_INIT;
+
+/** Using values from this instance of RCReader, write out values for a
+    default .dodsrc file. Nominally this will use the defaults for each thing
+    that might be read from the configuration file. */
+
+bool
+RCReader::write_rc_file(const string &pathname)
+{
+    DBG(cerr << "Writing the RC file to " << pathname << endl);
+    ofstream fpo(pathname.c_str());
+
+    // If the file couldn't be created.  Nothing needs to be done here,
+    // the program will simply use the defaults.
+
+    if (fpo) {
+        // This means we just created the file.  We will now save
+        // the defaults in it for future use.
+        fpo << "# OPeNDAP client configuration file. See the OPeNDAP" << endl;
+        fpo << "# users guide for information." << endl;
+        fpo << "USE_CACHE=" << _dods_use_cache << endl;
+        fpo << "# Cache and object size are given in megabytes (20 ==> 20Mb)."
+        << endl;
+        fpo << "MAX_CACHE_SIZE=" << _dods_cache_max  << endl;
+        fpo << "MAX_CACHED_OBJ=" << _dods_cached_obj << endl;
+        fpo << "IGNORE_EXPIRES=" << _dods_ign_expires  << endl;
+        fpo << "CACHE_ROOT=" << d_cache_root << endl;
+        fpo << "DEFAULT_EXPIRES=" << _dods_default_expires << endl;
+        fpo << "ALWAYS_VALIDATE=" << _dods_always_validate << endl;
+        fpo << "# Request servers compress responses if possible?" << endl;
+        fpo << "# 1 (yes) or 0 (false)." << endl;
+        fpo << "DEFLATE=" << _dods_deflate << endl;
+
+        fpo << "# Should SSL certificates and hosts be validated? SSL" << endl;
+        fpo << "# will only work with signed certificates." << endl;
+        fpo << "VALIDATE_SSL=" << d_validate_ssl << endl;
+
+        fpo << "# Proxy configuration (optional parts in []s)." << endl;
+	fpo << "# You may also use the 'http_proxy' environment variable"
+	    << endl;
+	fpo << "# but a value in this file will override that env variable."
+	    << endl;
+        fpo << "# PROXY_SERVER=[http://][username:password@]host[:port]"
+        << endl;
+        if (!d_dods_proxy_server_host.empty()) {
+            fpo << "PROXY_SERVER=" <<  d_dods_proxy_server_protocol << "://"
+            << (d_dods_proxy_server_userpw.empty()
+                ? ""
+                : d_dods_proxy_server_userpw + "@")
+            + d_dods_proxy_server_host
+            + ":" + long_to_string(d_dods_proxy_server_port) << endl;
+        }
+
+        fpo << "# NO_PROXY_FOR=<host|domain>" << endl;
+        if (!d_dods_no_proxy_for_host.empty()) {
+            fpo << "NO_PROXY_FOR=" << d_dods_no_proxy_for_host << endl;
+        }
+
+        fpo << "# AIS_DATABASE=<file or url>" << endl;
+
+	fpo << "# COOKIE_JAR=.dods_cookies" << endl;
+	fpo << "# The cookie jar is a file that holds cookies sent from"
+	    << endl;
+	fpo << "# servers such as single signon systems. Uncomment this"
+	    << endl;
+	fpo << "# option and provide a file name to activate this feature."
+	    << endl;
+	fpo << "# If the value is a filename, it will be created in this"
+	    << endl;
+	fpo << "# directory; a full pathname can be used to force a specific"
+	    << endl;
+	fpo << "# location." << endl;
+
+        fpo.close();
+        return true;
+    }
+
+    return false;
+}
+
+bool
+RCReader::read_rc_file(const string &pathname)
+{
+    DBG(cerr << "Reading the RC file from " << pathname << endl);
+
+    ifstream fpi(pathname.c_str());
+    if (fpi) {
+        // The file exists and we may now begin to parse it.
+        // Defaults are already stored in the variables, if the correct
+        // tokens are found in the file then those defaults will be
+        // overwritten.
+        char *value;
+        // TODO Replace with a vector<char>
+        //char *tempstr = new char[1024];
+        vector<char> tempstr(1024);
+        int tokenlength;
+        while (true) {
+            fpi.getline(&tempstr[0], 1023);
+            if (!fpi.good())
+                break;
+
+            value = strchr(&tempstr[0], '=');
+            if (!value)
+                continue;
+            tokenlength = value - &tempstr[0];
+            value++;
+
+            if ((strncmp(&tempstr[0], "USE_CACHE", 9) == 0)
+                && tokenlength == 9) {
+                _dods_use_cache = atoi(value) ? true : false;
+            }
+            else if ((strncmp(&tempstr[0], "MAX_CACHE_SIZE", 14) == 0)
+                     && tokenlength == 14) {
+                _dods_cache_max = atoi(value);
+            }
+            else if ((strncmp(&tempstr[0], "MAX_CACHED_OBJ", 14) == 0)
+                     && tokenlength == 14) {
+                _dods_cached_obj = atoi(value);
+            }
+            else if ((strncmp(&tempstr[0], "IGNORE_EXPIRES", 14) == 0)
+                     && tokenlength == 14) {
+                _dods_ign_expires = atoi(value);
+            }
+            else if ((strncmp(&tempstr[0], "DEFLATE", 7) == 0)
+                     && tokenlength == 7) {
+                _dods_deflate = atoi(value) ? true : false;
+            }
+            else if ((strncmp(&tempstr[0], "CACHE_ROOT", 10) == 0)
+                     && tokenlength == 10) {
+                d_cache_root = value;
+                if (d_cache_root[d_cache_root.length() - 1] != DIR_SEP_CHAR)
+                    d_cache_root += string(DIR_SEP_STRING);
+            }
+            else if ((strncmp(&tempstr[0], "DEFAULT_EXPIRES", 15) == 0)
+                     && tokenlength == 15) {
+                _dods_default_expires = atoi(value);
+            }
+            else if ((strncmp(&tempstr[0], "ALWAYS_VALIDATE", 15) == 0)
+                     && tokenlength == 15) {
+                _dods_always_validate = atoi(value);
+            }
+            else if ((strncmp(&tempstr[0], "VALIDATE_SSL", 12) == 0)
+                     && tokenlength == 12) {
+                d_validate_ssl = atoi(value);
+            }
+            else if (strncmp(&tempstr[0], "AIS_DATABASE", 12) == 0
+                     && tokenlength == 12) {
+                d_ais_database = value;
+	    }
+            else if (strncmp(&tempstr[0], "COOKIE_JAR", 10) == 0
+                     && tokenlength == 10) {
+		// if the value of COOKIE_JAR starts with a slash, use it as
+		// is. However, if it does not start with a slash, prefix it
+		// with the directory that contains the .dodsrc file.
+		if (value[0] == '/') {
+		    d_cookie_jar = value;
+		}
+		else {
+		    d_cookie_jar = d_rc_file_path.substr(0, d_rc_file_path.find(".dodsrc")) + string(value);
+		}
+		DBG(cerr << "set cookie jar to: " << d_cookie_jar << endl);
+            }
+            else if ((strncmp(&tempstr[0], "PROXY_SERVER", 12) == 0)
+                     && tokenlength == 12) {
+                // Setup a proxy server for all requests.
+		// The original syntax was <protocol>,<machine> where the
+		// machine could also contain the user/pass and port info.
+		// Support that but also support machine prefixed by
+		// 'http://' with and without the '<protocol>,' prefix. jhrg
+		// 4/21/08 (see bug 1095).
+                string proxy = value;
+                string::size_type comma = proxy.find(',');
+
+                // Since the <protocol> is now optional, the comma might be
+                // here. If it is, check that the protocol given is http.
+                if (comma != string::npos) {
+		    d_dods_proxy_server_protocol = proxy.substr(0, comma);
+		    downcase(d_dods_proxy_server_protocol);
+		    if (d_dods_proxy_server_protocol != "http")
+			throw Error("The only supported protocol for a proxy server is \"HTTP\". Correct your \".dodsrc\" file.");
+		    proxy = proxy.substr(comma + 1);
+		}
+		else {
+		    d_dods_proxy_server_protocol = "http";
+		}
+
+		// Look for a 'protocol://' prefix; skip if found
+		string::size_type protocol = proxy.find("://");
+		if (protocol != string::npos) {
+		    proxy = proxy.substr(protocol + 3);
+		}
+
+                // Break apart into userpw, host and port.
+                string::size_type at_sign = proxy.find('@');
+                if (at_sign != string::npos) { // has userpw
+                    d_dods_proxy_server_userpw = proxy.substr(0, at_sign);
+                    proxy = proxy.substr(at_sign + 1);
+                }
+                else
+                    d_dods_proxy_server_userpw = "";
+
+                // Get host and look for a port number
+                string::size_type colon = proxy.find(':');
+                if (colon != string::npos) {
+                    d_dods_proxy_server_host = proxy.substr(0, colon);
+                    d_dods_proxy_server_port
+			= strtol(proxy.substr(colon + 1).c_str(), 0, 0);
+                }
+                else {
+                    d_dods_proxy_server_host = proxy;
+		    d_dods_proxy_server_port = 80;
+                }
+            }
+            else if ((strncmp(&tempstr[0], "NO_PROXY_FOR", 12) == 0)
+                     && tokenlength == 12) {
+                // Setup a proxy server for all requests.
+                string no_proxy = value;
+                string::size_type comma = no_proxy.find(',');
+
+                // Since the protocol is required, the comma *must* be
+                // present. We could throw an Error on the malformed line...
+                if (comma == string::npos) {
+		    d_dods_no_proxy_for_protocol = "http";
+		    d_dods_no_proxy_for_host = no_proxy;
+		    d_dods_no_proxy_for = true;
+		}
+		else {
+		    d_dods_no_proxy_for_protocol = no_proxy.substr(0, comma);
+		    d_dods_no_proxy_for_host = no_proxy.substr(comma + 1);
+		    d_dods_no_proxy_for = true;
+		}
+            }
+        }
+
+        //delete [] tempstr; tempstr = 0;
+
+        fpi.close(); // Close the .dodsrc file. 12/14/99 jhrg
+
+        return true;
+    }  // End of cache file parsing.
+
+    return false;
+}
+
+// Helper for check_env_var(). This is its main logic, separated out for the
+// cases under WIN32 where we don't use an environment variable.  09/19/03
+// jhrg
+string
+RCReader::check_string(string env_var)
+{
+	DBG(cerr << "Entering check_string... (" << env_var << ")" << endl);
+    struct stat stat_info;
+
+	if (stat(env_var.c_str(), &stat_info) != 0) {
+		DBG(cerr << "stat returned non-zero" << endl);
+        return "";  // ENV VAR not a file or dir, bail
+	}
+
+	if (S_ISREG(stat_info.st_mode)) {
+		DBG(cerr << "S_ISREG: " << S_ISREG(stat_info.st_mode) << endl);
+        return env_var;  // ENV VAR is a file, use it
+	}
+
+    // ENV VAR is a directory, does it contain .dodsrc? Can we create
+    // .dodsrc if it's not there?
+    if (S_ISDIR(stat_info.st_mode)) {
+		DBG(cerr << "S_ISDIR: " << S_ISDIR(stat_info.st_mode) << endl);
+        if (*env_var.rbegin() != DIR_SEP_CHAR) // Add trailing / if missing
+            env_var += DIR_SEP_STRING;
+        // Trick: set d_cache_root here in case we're going to create the
+        // .dodsrc later on. If the .dodsrc file exists, its value will
+        // overwrite this value, if not write_rc_file() will use the correct
+        // value. 09/19/03 jhrg
+        d_cache_root = env_var + string(".dods_cache") + DIR_SEP_STRING;
+        env_var += ".dodsrc";
+        if (stat(env_var.c_str(), &stat_info) == 0 &&
+			S_ISREG(stat_info.st_mode)) {
+			DBG(cerr << "Found .dodsrc in \"" << env_var << "\"" << endl);
+            return env_var; // Found .dodsrc in ENV VAR
+		}
+
+        // Didn't find .dodsrc in ENV VAR and ENV VAR is a directory; try to
+        // create it. Note write_rc_file uses d_cache_root (set above) when
+        // it creates the RC file's contents.
+		if (write_rc_file(env_var)) {
+			DBG(cerr << "Wrote .dodsrc in \"" << env_var << "\"" << endl);
+            return env_var;
+		}
+    }
+
+    // If we're here, then we've neither found nor created the RC file.
+	DBG(cerr << "could neither find nor create a .dodsrc file" << endl);
+    return "";
+}
+
+/** Examine an environment variable. If the env variable is set, then if
+    this is the name of a file, use that as the name of the RC file. If this
+    is the name of a directory, look in that directory for a file called
+    .dodsrc. If there's no such file, create it using default values for its
+    parameters. In the last case, write the .dodsrc so that the .dods_cache
+    directory is located in the directory named by DODS_CONF.
+
+    @return The pathname to the RC file or "" if another variable/method
+    should be used to find/create the RC file. */
+string
+RCReader::check_env_var(const string &variable_name)
+{
+    char *ev = getenv(variable_name.c_str());
+    if (!ev || strlen(ev) == 0)
+        return "";
+
+    return check_string(ev);
+}
+
+RCReader::RCReader() throw(Error)
+{
+    d_rc_file_path = "";
+    d_cache_root = "";
+
+    // ** Set default values **
+    // Users must explicitly turn caching on.
+    _dods_use_cache = false;
+    _dods_cache_max = 20;
+    _dods_cached_obj = 5;
+    _dods_ign_expires = 0;
+    _dods_default_expires = 86400;
+    _dods_always_validate = 0;
+
+    _dods_deflate = 0;
+    d_validate_ssl = 1;
+
+    //flags for PROXY_SERVER=<protocol>,<host url>
+    // New syntax PROXY_SERVER=[http://][user:pw@]host[:port]
+    d_dods_proxy_server_protocol = "";
+    d_dods_proxy_server_host = "";
+    d_dods_proxy_server_port = 0;
+    d_dods_proxy_server_userpw = "";
+
+    _dods_proxy_server_host_url = ""; // deprecated
+
+    // PROXY_FOR is deprecated.
+    // flags for PROXY_FOR=<regex>,<proxy host url>,<flags>
+    _dods_proxy_for = false; // true if proxy_for is used.
+    _dods_proxy_for_regexp = "";
+    _dods_proxy_for_proxy_host_url = "";
+    _dods_proxy_for_regexp_flags = 0;
+
+    //flags for NO_PROXY_FOR=<protocol>,<host>,<port>
+    // New syntax NO_PROXY_FOR=<host|domain>
+    d_dods_no_proxy_for = false;
+    d_dods_no_proxy_for_protocol = ""; // deprecated
+    d_dods_no_proxy_for_host = "";
+    // default to port 0 if not specified. This means all ports. Using 80
+    // will fail when the URL does not contain the port number. That's
+    // probably a bug in libwww. 10/23/2000 jhrg
+    _dods_no_proxy_for_port = 0; // deprecated
+
+    d_cookie_jar = "";
+
+#ifdef WIN32
+    string homedir = string("C:") + string(DIR_SEP_STRING) + string("Dods");
+    d_rc_file_path = check_string(homedir);
+    if (d_rc_file_path.empty()) {
+	homedir = string("C:") + string(DIR_SEP_STRING) + string("opendap");
+	d_rc_file_path = check_string(homedir);
+    }
+    //  Normally, I'd prefer this for WinNT-based systems.
+    if (d_rc_file_path.empty())
+        d_rc_file_path = check_env_var("APPDATA");
+    if (d_rc_file_path.empty())
+        d_rc_file_path = check_env_var("TEMP");
+    if (d_rc_file_path.empty())
+        d_rc_file_path = check_env_var("TMP");
+#else
+    d_rc_file_path = check_env_var("DODS_CONF");
+    if (d_rc_file_path.empty())
+        d_rc_file_path = check_env_var("HOME");
+#endif
+    DBG(cerr << "Looking for .dodsrc in: " << d_rc_file_path << endl);
+
+    if (!d_rc_file_path.empty())
+        read_rc_file(d_rc_file_path);
+}
+
+RCReader::~RCReader()
+{}
+
+/** Static void private method. */
+void
+RCReader::delete_instance()
+{
+    if (RCReader::_instance) {
+        delete RCReader::_instance;
+        RCReader::_instance = 0;
+    }
+}
+
+/** Static void private method. */
+void
+RCReader::initialize_instance()
+{
+    DBGN(cerr << "RCReader::initialize_instance() ... ");
+
+    RCReader::_instance = new RCReader;
+    atexit(RCReader::delete_instance);
+
+    DBG(cerr << "exiting." << endl);
+}
+
+RCReader*
+RCReader::instance()
+{
+	DBG(cerr << "Entring RCReader::instance" << endl);
+    // The instance_control variable is defined at the top of this file.
+    // 08/07/02 jhrg
+    pthread_once(&instance_control, initialize_instance);
+
+    DBG(cerr << "Instance value: " << hex << _instance << dec << endl);
+
+    return _instance;
+}
+
+} // namespace libdap
diff --git a/RCReader.h b/RCReader.h
new file mode 100644
index 0000000..8df3492
--- /dev/null
+++ b/RCReader.h
@@ -0,0 +1,360 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Jose Garcia <jgarcia at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 2001-2002
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//         jose  Jose Garcia <jgarcia at ucar.edu>
+
+#ifndef _rc_reader_h_
+#define _rc_reader_h_
+
+#include <iostream>
+#include <string>
+
+#include "Error.h"
+#include "util.h"
+
+using namespace std;
+
+namespace libdap
+{
+
+/** Read the .dodsrc file. By default the file ~/.dodsrc is read. If the
+    environment variable DODS_CONF is set, use that value as the pathname to
+    the configuration file. Else, if the environment variable DODS_CACHE_INIT
+    is set, use that value.
+
+    NB: DODS_CACHE_INIT is deprecated and may be removed in the future.
+
+    @author Jose Garcia <jgarcia at ucar.edu> */
+class RCReader
+{
+private:
+    string d_rc_file_path;
+    string d_cache_root;
+
+    bool _dods_use_cache; // 0- Disabled 1- Enabled
+    unsigned int _dods_cache_max; // Max cache size in Mbytes
+    unsigned int _dods_cached_obj; // Max cache entry size in Mbytes
+    int _dods_ign_expires; // 0- Honor expires 1- Ignore them
+
+    // NB: NEVER_DEFLATE: I added this (12/1/99 jhrg) because libwww 5.2.9
+    // cannot process compressed (i.e., deflated) documents in the cache.
+    // Users must be able to choose whether they want compressed data that
+    // will always be refreshed or uncompressed data that will be cached.
+    // When set this flag overrides the value passed into the Connect
+    // object's constructor. This gives users control over the value.
+    // Previously, this could only be set by the program that called
+    // Connect(...). Note that I've now (4/6/2000 jhrg) fixed libwww so this
+    // parameter is no longer needed.111
+    //
+    // Added back in, but with a better name (removed double negative).
+    // 6/27/2002 jhrg
+    bool _dods_deflate;  // 1- request comp responses, 0- don't
+
+    int _dods_default_expires; // 24 hours in seconds
+    int _dods_always_validate; // Let libwww decide by default so set to 0
+
+    // flags for PROXY_SERVER=<protocol>,<host url>
+    string d_dods_proxy_server_protocol;
+    string d_dods_proxy_server_host;
+    int d_dods_proxy_server_port;
+    string d_dods_proxy_server_userpw;
+
+    // Should libcurl validate SSL hosts/certificates"
+    int d_validate_ssl;
+
+    string _dods_proxy_server_host_url; // deprecated
+
+    // The proxy-for stuff is all deprecated. 06/17/04 jhrg
+    // flags for PROXY_FOR=<regex>,<proxy host url>,<flags>
+    bool _dods_proxy_for; // true if proxy_for is used.
+    string _dods_proxy_for_regexp;
+    string _dods_proxy_for_proxy_host_url;
+    int _dods_proxy_for_regexp_flags; // not used w/libcurl. 6/27/2002 jhrg
+
+    //flags for NO_PROXY_FOR=<protocol>,<host>,<port>
+    bool d_dods_no_proxy_for; // true if no_proxy_for is used.
+    string d_dods_no_proxy_for_protocol;
+    string d_dods_no_proxy_for_host;
+    int _dods_no_proxy_for_port; // not used w/libcurl. 6/27/2002 jhrg
+
+    // Make this a vector of strings or support a PATH-style list. 02/26/03
+    // jhrg
+    string d_ais_database;
+
+    string d_cookie_jar;
+
+    static RCReader* _instance;
+
+    RCReader() throw(Error);
+    ~RCReader();
+
+    // File I/O methods
+    bool write_rc_file(const string &pathname);
+    bool read_rc_file(const string &pathname);
+
+    // Look for the RC file
+    string check_env_var(const string &variable_name);
+    string check_string(string env_var);
+
+    static void initialize_instance();
+    static void delete_instance();
+
+    friend class RCReaderTest;
+    friend class HTTPConnectTest;
+
+public:
+    static RCReader* instance();
+
+    // GET METHODS
+    string get_dods_cache_root() const throw()
+    {
+        return d_cache_root;
+    }
+    bool get_use_cache() const throw()
+    {
+        return _dods_use_cache;
+    }
+    int get_max_cache_size()  const throw()
+    {
+        return _dods_cache_max;
+    }
+    unsigned int get_max_cached_obj() const throw()
+    {
+        return _dods_cached_obj;
+    }
+    int get_ignore_expires() const throw()
+    {
+        return _dods_ign_expires;
+    }
+    int get_default_expires() const throw()
+    {
+        return _dods_default_expires;
+    }
+    int get_always_validate() const throw()
+    {
+        return _dods_always_validate;
+    }
+    int get_validate_ssl() const throw()
+    {
+        return d_validate_ssl;
+    }
+
+    bool get_deflate() const throw()
+    {
+        return _dods_deflate;
+    }
+
+    /// Get the proxy server protocol
+    string get_proxy_server_protocol() const throw()
+    {
+        return d_dods_proxy_server_protocol;
+    }
+    /// Get the proxy host
+    string get_proxy_server_host() const throw()
+    {
+        return d_dods_proxy_server_host;
+    }
+    /// Get the proxy port
+    int get_proxy_server_port() const throw()
+    {
+        return d_dods_proxy_server_port;
+    }
+    /// Get the proxy username and password
+    string get_proxy_server_userpw() const throw()
+    {
+        return d_dods_proxy_server_userpw;
+    }
+    /// @deprecated
+    string get_proxy_server_host_url() const throw()
+    {
+        return (d_dods_proxy_server_userpw.empty() ? "" : d_dods_proxy_server_userpw + "@")
+               + d_dods_proxy_server_host
+               + ":" + long_to_string(d_dods_proxy_server_port);
+    }
+
+    // The whole regex/proxy-for implementation needs reworking. We really
+    // need a vector of structs which hold the information on a set of regexes
+    // and matching proxies. Then in the code that derefs a URL, we should
+    // check to see if the URL matches any of the regexs, et cetera. I'm
+    // going to disable the entire feature and see if anyone complains. If
+    // they do, we can fix it. If not, one less thing to do... 06/17/04 jhrg
+    /// @deprecated
+    bool is_proxy_for_used() throw()
+    {
+        return _dods_proxy_for;
+    }
+    /// @deprecated
+    string get_proxy_for_regexp() const throw()
+    {
+        return _dods_proxy_for_regexp;
+    }
+    /// @deprecated
+    string get_proxy_for_proxy_host_url() const throw()
+    {
+        return _dods_proxy_for_proxy_host_url;
+    }
+
+    /// @deprecated
+    int get_proxy_for_regexp_flags() const throw()
+    {
+        return _dods_proxy_for_regexp_flags;
+    }
+
+    // The whole no_proxy implementation also needs a rewrite. However, it is
+    // useful as it is since the user can give a domain and there's often a
+    // real need for suppressing proxy access for the local domain. The
+    // ..._port() method is bogus, however, so it is deprecated. There's no
+    // code that uses it. 06/17/04 jhrg
+    bool is_no_proxy_for_used() throw()
+    {
+        return d_dods_no_proxy_for;
+    }
+    string get_no_proxy_for_protocol() const throw()
+    {
+        return d_dods_no_proxy_for_protocol;
+    }
+    string get_no_proxy_for_host() const throw()
+    {
+        return d_dods_no_proxy_for_host;
+    }
+
+    /// @deprecated
+    int    get_no_proxy_for_port() const throw()
+    {
+        return _dods_no_proxy_for_port;
+    }
+
+    string get_ais_database() const throw()
+    {
+        return d_ais_database;
+    }
+
+    string get_cookie_jar() const throw()
+    {
+	return d_cookie_jar;
+    }
+
+    // SET METHODS
+    void set_use_cache(bool b) throw()
+    {
+        _dods_use_cache = b;
+    }
+    void set_max_cache_size(int i) throw()
+    {
+        _dods_cache_max = i;
+    }
+    void set_max_cached_obj(int i) throw()
+    {
+        _dods_cached_obj = i;
+    }
+    void set_ignore_expires(int i) throw()
+    {
+        _dods_ign_expires = i;
+    }
+    void set_default_expires(int i) throw()
+    {
+        _dods_default_expires = i;
+    }
+    void set_always_validate(int i) throw()
+    {
+        _dods_always_validate = i;
+    }
+    void set_validate_ssl(int i) throw()
+    {
+        d_validate_ssl = i;
+    }
+
+    void set_deflate(bool b) throw()
+    {
+        _dods_deflate = b;
+    }
+
+    void set_proxy_server_protocol(const string &s) throw()
+    {
+        d_dods_proxy_server_protocol = s;
+    }
+    void set_proxy_server_host(const string &s) throw()
+    {
+        d_dods_proxy_server_host = s;
+    }
+    void set_proxy_server_port(int l) throw()
+    {
+        d_dods_proxy_server_port = l;
+    }
+    void set_proxy_server_userpw(const string &s) throw()
+    {
+        d_dods_proxy_server_userpw = s;
+    }
+
+    /// @deprecated
+    void set_proxy_server_host_url(const string &s) throw()
+    {
+        _dods_proxy_server_host_url = s;
+    }
+
+    /// @deprecated
+    void set_proxy_for_regexp(const string &s) throw()
+    {
+        _dods_proxy_for_regexp = s;
+    }
+    /// @deprecated
+    void set_proxy_for_proxy_host_url(const string &s) throw()
+    {
+        _dods_proxy_for_proxy_host_url = s;
+    }
+    /// @deprecated
+    void set_proxy_for_regexp_flags(int i) throw()
+    {
+        _dods_proxy_for_regexp_flags = i;
+    }
+
+    void set_no_proxy_for_protocol(const string &s) throw()
+    {
+        d_dods_no_proxy_for_protocol = s;
+    }
+    void set_no_proxy_for_host(const string &s) throw()
+    {
+        d_dods_no_proxy_for_host = s;
+    }
+
+    /// @deprecated
+    void set_no_proxy_for_port(int i) throw()
+    {
+        _dods_no_proxy_for_port = i;
+    }
+
+    void set_ais_database(const string &db) throw()
+    {
+        d_ais_database = db;
+    }
+};
+
+} // namespace libdap
+
+#endif // _RCReader_h_
diff --git a/README b/README
new file mode 100644
index 0000000..737e465
--- /dev/null
+++ b/README
@@ -0,0 +1,414 @@
+Updated for version 3.11.1
+
+Bug fixes only.
+
+Updated for version 3.11.0
+
+Now constraint expressions can have multiple function calls that return data.
+
+I've bumped up the DAP version from 3.3 to 3.4 to reflect this change.
+
+Updated for Version 3.10.2
+
+BaseType::transfer_attributes() and related methods provide a way for
+handlers to customize how attributes from a DAS object are merged into
+a DDS.
+
+In the past we supported a kind of client-side system that could augment
+the attributes call the 'AIS' (Ancillary Information System). This has
+been removed - our server now supports the NcML language to do much the same
+thing but in a way that can be set on the server once for all users. It's also
+an emerging convention that's gaining wide support within the community.
+
+Updated for Version 3.10.0
+
+DAP 3.3 is now supported; see http://docs.opendap.org/index.php/DAP3/4.
+
+This version of libdap contains many changes that are needed for both
+DAP 4 and the NcML handler. This version of the library is required
+for the Hyrax 1.6 handlers.
+
+The 'deflate' program is no longer part of this library package since
+we are no longer supporting the old data server system (based on WWW's
+CGI specification).
+
+Updated for version 3.9.2
+
+Now libdap supports DAP 3.2. You can read about the evolving DAP 3.x protocol
+at http://docs.opendap.org/index.php/DAP3/4. If your client sends the
+XDAP-Accept header with a value of 3.2 the DDX is different (it includes
+protocol information and also an xmlbase element).
+
+Behavior change for the DAS: In the past the format handlers added double
+quotes to the values of string attributes when they added those values to the
+AttrTable object. This meant that the value of the attribute in the C++
+object was actually not correct since it contained quotes not found in the
+original attribute value. I modified libdap so that if an attribute value in
+the C++ AttrTable object does not have quotes then those quotes are added
+when the value is output in a DAS response (but not a DDX since there's no
+need to quote the value in that response). This ensures that the text in the
+DAS wire representation will parse whether a handler has added quotes or not
+(paving the way for fixed handlers). At the same time I fixed all of our
+handlers so that they no longer add the erroneous quotes. This fixes a
+problem with the DDX where the quotes were showing up as part of the
+attribute value. The change to libdap is such that a broken handler will not
+be any more broken but a fixed handler will work for both DAS and DDX
+generation.
+
+If you have a handler and it's not adding quotes to the String attribute 
+values - good, don't change that! If your handler does add quotes, please
+modify it so the DDX will be correct.  
+
+Our handler's old, broken, behavior can be resurrected by removing the 
+ATTR_STRING_QUOTE FIX define in the appropriate files.
+
+Updated for version 3.8.2 (23 June 2008)
+
+HTTP Cache and win32 installer fixes (the latter are actually in the 3.8.1
+installer for winXP). API change: The functions used to merge ancillary data
+have been moved to their own class (Ancillary).
+
+Updated for version 3.8.1 (10 June 2008)
+
+The syntax for PROXY_SERVER in the .dodsrc file was relaxed. See the .dodsrc
+file for more information.
+
+Updated for Version 3.8.0 (29 February 2008)
+
+The libdap classes and code are now inside of the libdap namespace. In order
+to access any of the classes, for example, you will need to do one of the
+following. After including the libdap headers you can:
+
+1. add a using statement for the entire libdap namespace:
+
+using namespace libdap ;
+
+2. add a using statement for the classes that you will be using:
+
+using libdap::DAS ;
+
+3. inside your code scope the use of libdap classes.
+
+libdap::DAS *das = code_to_get_das() ;
+
+Added method to HTTPCache to return not only the FILE pointer of a cached
+response but also the name of the file in the cache, to allow for this file
+name to be passed to data handlers in the BES to be read.
+
+See NEWS for more information about changes for this version and ChangeLog
+for the gory details.
+
+Updated for Version 3.7.10 (28 November 2007)
+
+A bug fix release. See NEWS.
+
+Updated for Version 3.7.9 (13 November 2007)
+
+This release is a bug fix and refactoring release. Old classes which were no
+longer used have been removed, the FILE* output methods are slated to be
+replaced with ones which will use iostream and will support a chucked
+transfer 'Marshaller,' and the transfer_data() methods have been made a
+formal part of the library, implemented for all classes, fixed and renamed to
+intern_data(). Many bugs in the library were also fixed.
+
+Updated for version 3.7.8 (26 June 2007)
+
+The major fixes in this version are memory errors found and fixed in the
+Regex class and HTTP header processing software. This version also supports
+pkg-config on hosts that have that installed.
+
+See NEWS for more information about changes for this version and ChangeLog
+for the gory details.
+
+Notes for version 3.7.7 (2 May 2007)
+
+The major fix here is to the source build. We've fixed the issue where source
+builds failed to make the dapserver and dapclient libraries.
+
+Notes for version 3.7.6 (12 March 2007)
+
+Two bug fixes, both minor. Problems in the linear_scale() constraint
+expression function and a bad/missing #include in GNURegex.h were fixed.
+
+There was an error in the INSTALL file sent out in the previous release. It
+said this library implemented DAP version 3.2, but in fact it implements
+version 3.1. The version 3.2 release will be along soon (RSN).
+
+Notes for version 3.7.5 (7 Feb 2007)
+
+This version includes many fixes from the first Server4 beta release
+plus fixes for the server-side functions. It also includes a smoother
+Win32 build.
+
+Notes for version 3.7.4 (2 Jan 2007)
+
+Release for the Server4 beta release.
+
+Notes for version 3.7.3 (24 Nov 2006)
+
+This version of libdap contains a beta release of the server-side functions
+geogrid(), geoarray(), linear_scale() and version(). These can be used to
+select parts of Grids and Arrays using latitude and longitude values instead
+of array position indexes. The linear_scale() function can be used to scale
+variables (including those return by other function) using 'y = mx + b'. The
+version() function can be used to find out which versions of the functions are
+installed.
+
+EXAMPLES
+
+To get version information use the 'version()' function. Currently, version()
+can only be called when asking for data, and you must give the name of a data
+source, although in the default version of version() the data source is not
+used. The version function takes one optional argument which may be the strings
+'help' or 'xml'. Use 'help' to get help on using the function; use 'xml' to get
+version information encoded using XML instead of plain text:
+
+<code>
+[jimg at zoe libdap]$ url=http://test.opendap.org/dap/data/nc/coads_climatology.nc
+[jimg at zoe libdap]$ ./getdap -D "$url?version()"
+The data:
+String version = "Function set: version 1.0, grid 1.0, geogrid 1.0b2, 
+		          geoarray 0.9b1, linear_scale 1.0b1";
+
+[jimg at zoe libdap]$ ./getdap -D "$url?version(help)"
+The data:
+String version = "Usage: version() returns plain text information about ...
+
+[jimg at zoe libdap]$ ./getdap -D "$url?version(xml)"
+The data:
+String version = "<?xml version=\"1.0\"?>
+    <functions>
+        <function name=\"version\" version=\"1.0\"/>
+        <function name=\"grid\" version=\"1.0\"/>
+        <function name=\"geogrid\" version=\"1.0\"/>
+        <function name=\"geoarray\" version=\"1.0\"/>
+        <function name=\"linear_scale\" version=\"1.0\"/>
+    </functions>";
+
+The geogrid function can only be used with variables that are Grids:
+
+[jimg at zoe libdap]$ getdap -d "$url"
+Dataset {
+    Float64 COADSX[COADSX = 180];
+    Float64 COADSY[COADSY = 90];
+    Float64 TIME[TIME = 12];
+    Grid {
+      Array:
+        Float32 SST[TIME = 12][COADSY = 90][COADSX = 180];
+      Maps:
+        Float64 TIME[TIME = 12];
+        Float64 COADSY[COADSY = 90];
+        Float64 COADSX[COADSX = 180];
+    } SST;
+    Grid {
+    .
+    .
+    .
+</code>
+    
+Pass the name of the Grid variable and the upper-left and lower-right corners 
+of the lat/lon rectangle to geogrid. Optionally, pass one or more relational
+expressions to select parts of dimensions that are not lat/lon. 
+
+Note: in libdap 3.7.3 calling geogrid with a constraint on each dimension
+may return incorrect values that indicate missing data even though data should
+have been returned.
+
+<code>
+[jimg at zoe libdap]$ getdap -D "$url?geogrid(SST,30,-60,20,-60,\"TIME=366\")"
+The data:
+Grid {
+  Array:
+    Float32 SST[TIME = 1][COADSY = 7][COADSX = 2];
+  Maps:
+    Float64 TIME[TIME = 1];
+    Float64 COADSY[COADSY = 7];
+    Float64 COADSX[COADSX = 2];
+} SST = {  Array: {{{24.4364, 25.0923},{23.7465, 24.4146},{19.843, 23.6033},
+{16.8464, 17.7756},{16.65, 16.818},{-1e+34, 15.3656},{18.7214, 13.1286}}}  
+Maps: {366}, {19, 21, 23, 25, 27, 29, 31}, {-61, -59} };
+</code>
+
+The geoarray() function works like geogrid() except that it's used to select
+from an Array variable and not a Grid. In addition to the four lat/lon values
+for selection rectangle, the caller must supply the data's corner points. A 
+subsequent release of libdap will include a version that reads the data extent
+from the data source when possible so caller's won't normally have to know the
+data's extent ahead of time.
+
+The linear_scale() function take either one or three arguments. The first
+(only) argument is the name of a variable or the return from another
+function. This variable will be scaled using the 'y = mx + b' equation where
+'x' is the value(s) of the input variable and 'm' and 'b' are read from the
+data source using the values of attributes name 'scale_factor' and
+'add_offset.' If these are not present, or to over ride their values, m and b
+can be supplied using the second and third arguments.
+
+Note that there are still some problems with linear_scale() in this release.
+
+See NEWS and ChangeLog for information about other changes
+
+Notes for version 3.7.2
+
+This version of libdap is required for the 9/15/06 alpha release of Server4.
+The library now contains software which enables Server4 to build the ASCII
+data response for all types of variables, including Sequence and nested
+Sequence variables. These features are additions to the API, so older code
+will work just fine with the new library. See NEWS for more specific info
+about bug fixes.
+
+Notes for version 3.7.1
+
+This is a bug fix release (mostly) made for users of the netcdf client
+library who need a fix for a problem dealing with attributes from the HDF4
+server. 
+
+NOTES for version 3.7.0
+
+This version includes new features and an implementation change.
+
+This version of libdap now returns the DAP protocol version number, 3.1, in
+an HTTP response header. Use this to determine which protocol version the
+library implements. The inclusion of a protocol version number is the sole
+official new feature of DAP 3.1. Use Connect::get_protocol() to get the
+version number. Clients can use this to determine the features supported by a
+server. The Connect::get_version() method can still be used to get our
+server's implementation version. The distinction is that as more groups
+provide their own implementations of the DAP, the protocol version will
+provide a way for clients to determine capabilities independently of
+implementation.
+
+The libdap library now contains an implementation of the DDX object/response,
+although this is an alpha implementation and it's actually been part of the
+library for some time now. The implementation contained in this version of
+the library is close enough to the version we intend for DAP4 that developers
+can start to use it. Most of the server handlers will return DDXs when asked.
+
+The DDX combines the information previously held by the DDS and DAS objects,
+making it much easier to associate attributes to variables. As the name
+suggests, the DDX uses XML rather than curly-braces. You can drop the DDX
+into your favorite XML parser and get a DOM tree; no need to use our parsers.
+However, libdap contains a nice SAX parser that will build the libdap objects
+directly from the XML DDX object/response. Also included in libdap are
+methods to build a DDX using a DDS and DAS, so there's an easy migration path
+for both servers and clients.
+
+Finally, the library contains two structural changes. First, the library
+named 'libdap' now holds the DAP implementation while two new libraries,
+'libdapclient' and 'libdapserver', now hold the client and server helper
+classes which are not strictly part of the DAP. Secondly, the DDS/DDX object
+now takes the constraint evaluator as a parameter. The class
+ConstraintEvaluator holds our default evaluator, but it's now possible to use
+your own evaluator .
+
+NOTES for version 3.6.1
+
+Version 3.6.1 is bug fix release.
+
+NOTES for version 3.6.0
+
+This version of the library may not work older source code. Many of the 
+deprecated methods have been removed. 
+
+Added are headers which send information about the version of the DAP protocol
+that the library implements (in contrast to the implementation of the library
+itself). A new header named XOPeNDAP-Server is used to send information about
+the implementation of servers.
+
+The libtool interface version has been incremented from 3 to 4 (these versions
+do no track the software's release version since several releases might 
+present compatible binary interfaces). 
+
+NOTES for version 3.5.3
+
+This version of libdap++ cannot be used to build the 3.4.x and previous
+clients and/or servers. However, client and servers built using this code
+_will_ work with the older clients and servers.
+
+WHAT'S IN THIS DIRECTORY?
+
+This directory contains the OPeNDAP C++ implementation of the Data
+Access Protocol version 2 (DAP2) with some extensions that will be
+part of DAP3.  Documentation for this software can be found on the
+OPeNDAP home page at http://www.opendap.org/. The NASA/ESE RFC which
+describes DAP2, implemented by the library, can be found at
+http://spg.gsfc.nasa.gov/rfc/004/.
+
+The DAP2 is used to provide a uniform way of accessing a variety of
+different types of data across the Internet. It was originally part of
+the DODS and then NVODS projects. The focus of those projects was
+access to Earth-Science data, so much of the software developed using
+the DAP2 to date has centered on that discipline. However, the DAP2
+data model is very general (and similar to a modern structured
+programming language) so it can be applied to a wide variety of
+fields.
+
+The DAP2 is implemented as a set of C++ classes that can be used to
+build data servers and clients. The classes may be specialized to
+mimic the behavior of other data access APIs, such as netCDF. In this
+way, programs originally meant to work with local data in those
+formats can be re-linked and equipped to work with data stored
+remotely in many different formats.  The classes can also by
+specialized to build standalone client programs.
+
+The DAP2 is contained in a single library: libdap++.a. Also included
+in the library are classes and utility functions which simplify
+building clients and servers.
+
+WHAT ELSE IS THERE?
+
+The file README.dodsrc describes the client-side behavior which can be
+controlled using the .dodsrc file. This includes client-side caching,
+proxy servers, et c., and is described in a separate file so it's easy
+to include in your clients.
+
+The file README.AIS describes the prototype Ancillary Information
+Service (AIS) included in this version of the library. The AIS is
+(currently) a client-side capability which provides a way to augment
+DAP attributes. This is a very useful feature because it can be used
+to add missing metadata to a data source. The AIS is accessed by using
+the AISConnect class in place of Connect in your client.
+
+This directory also contains test programs for the DAP2, a sample
+specialization of the classes, getdap (a useful command-line web
+client created with DAP2) and dap-config (a utility script to simplify
+linking with libdap.a). Also included as of version 3.5.2 is
+libdap.m4, an autoconf macro which developers can use along with
+autoconf to test for libdap. This macro will be installed in
+${prefix}/share/aclocal and can be by any package which uses autoconf
+for its builds. See the file for more information.
+
+We also have Java and C versions of the DAP2 library which
+inter-operate with software which uses this library. In other words,
+client programs built with the Java DAP2 implementation can
+communicate with servers built with this (C++) implementation of the
+DAP2. The C DAP2 library, called the Ocapi, only implements the
+client-side part of the protocol. Clients written using the Ocapi are
+interoperable with both the Java and C++ DAP2 libraries. Note that the
+Ocapi is in early beta and available only from CVS at this time (5 May
+2005).
+  
+THREAD SAFETY
+
+We don't need to do this since the STL is also not thread safe. Users
+of libdap have to be sure that multiple threads never make
+simultaneous and/or overlapping calls to a single copy of libdap. If
+several threads are part of a program and each will make calls to
+libdap, either those threads must synchronize their calls or arrange
+to each use their own copy of libdap.  Some aspects of the library
+''are'' thread-safe: the singleton classes are all protected as is the
+HTTP cache (which uses the local file system).
+
+INSTALLATION INSTRUCTIONS
+
+See the file INSTALL in this directory for information on building the
+library and the geturl client.
+
+COPYRIGHT INFORMATION
+
+The OPeNDAP DAP library is copyrighted using the GNU Lesser GPL. See
+the file COPYING or contact the Free Software Foundation, Inc., at 59
+Temple Place, Suite 330, Boston, MA 02111-1307 USA. Older versions of
+the DAP were copyrighted by the University of Rhode Island and
+Massachusetts Institute of Technology; see the file COPYRIGHT_URI. The
+file deflate.c is also covered by COPYRIGHT_W3C.
diff --git a/README.dodsrc b/README.dodsrc
new file mode 100644
index 0000000..8f48059
--- /dev/null
+++ b/README.dodsrc
@@ -0,0 +1,150 @@
+$Id: README.dodsrc 18646 2008-04-25 19:21:25Z jimg $
+
+Current for version 3.7.6 (12 March 2007)
+
+The libdap client-side configuration file (.dodsrc) is used to configure how
+clients cache responses and how they interact with proxy servers. By default
+the configuration file resides in a users home directory and is called
+`.dodsrc'. This can be changed by creating the environment variable
+DODS_CONF and setting it to the full pathname of the configuration file.
+
+About the Win32 builds:
+
+For Win32 (Windows XP and Vista) a client linked with libdapclient will look
+for the .dodsrc file in the following locations: C:\Dods; %APPDATA%; %TEMP%;
+and %TMP%. If no .dodsrc file is found, the library will create one in
+%APPDATA%. Note that on some Windows XP machines a user's 'Application Data'
+directory is hidden. To see and edit the .dodsrc file, open a file browser
+window from the Start menu, go to your home directory and then type in 
+'Application Data'. The .dodsrc file will be created by the first OPeNDAP
+client to run if there's not a copy already there.
+
+Another note about the Win32 builds and the .dodsrc file: It appears that
+client-side caching does not work in recent versions of the library, so until
+further notice, leave USE_CACHE set to zero.
+
+New feature added with libdap version 3.7.3 (7 Nov 2006)
+
+The configuration file can now be used to control client-side behavior when
+accessing servers using SSL. By default, certificates must be signed by a
+certificate authority. The libcurl package recognizes a large set of 
+CAs; you can sign your own certificates as well (but see the OpenSSL
+documentation for more information). In addition, server hosts must identify
+themselves using the same name as is used in the certificate.
+
+To disable these features, set the configuration parameter VALIDATE_SSL to
+zero. By default, these features are now enabled following the defaults for
+libcurl.
+
+If a DODS client starts and cannot find the configuration file, then one with
+default parameters will be created in the user's home directory. By default
+caching will be enabled with a maximum cache size of 20M and a default
+expiration time of 24 hours. By default no proxy server is configured and SSL
+hosts and certificates are validated. Also by default, compression is not
+activated.
+
+A sample configuration file looks like (the line numbers are not part of the
+file; they've been added to make the description clearer):
+
+0   # Comments start with a `#' in the first column.
+1	USE_CACHE=1
+2	MAX_CACHE_SIZE=20
+3	MAX_CACHED_OBJ=5
+4	IGNORE_EXPIRES=0
+5	CACHE_ROOT=/home/jimg/.dods_cache/
+6	DEFAULT_EXPIRES=86400
+7	DEFLATE=0
+8	VALIDATE_SSL=1
+9	PROXY_SERVER=http,http://jimg:password@dcz.dods.org/
+10	NO_PROXY_FOR=http,dcz.dods.org
+11	AIS_DATABASE=.ais_sst_database
+    
+COMMENTS 
+Starting a line with a `#' makes that line a comment. 
+
+CACHING 
+
+The parameters on lines 1 through 6 determine how the DAP++ library will use
+its HTTP 1.1 cache. If the value of USE_CACHE is 1, the cache is active. A
+value of 0 turns off the cache. Make sure you use zero (0) and not the letter
+`O'.
+
+The value of MAX_CACHE_SIZE sets the maximum size of the cache in megabytes.
+Once the cache reaches this size, caching more objects will cause cache
+garbage collection. The algorithm used is to first purge the cache of any
+stale entries and then remove remaining entries starting with those that have
+the lowest hit count. Garbage collection stops when 90% of the cache has been
+purged.
+
+The value of MAX_CACHED_OBJ sets the maximum size of any individual object in
+the cache in megabytes. Objects received from a server larger than this value
+will not be cached even if there's room for them without purging other
+objects.
+
+The parameter CACHE_ROOT contains the pathname to the cache's top directory.
+If two or more users want to share a cache, then they must both have read and
+write permissions to the cache root.
+
+If the value of IGNORE_EXPIRES is 1, then Expires: headers in response
+documents will be ignored. The value of DEFAULT_EXPIRES sets the expiration
+time for any response that does not include either an Expires or
+Last-Modified header. The value is given in seconds; 86,400 is 24 hours. In
+general you should *not* ignore the Expires header; the server probably had a
+good reason to send it along with the response. This parameter is here for
+unusual situations.
+
+Note: If a Last-Modified header is returned with the response, and there's
+*no* Expires header, the expiration time is is 10% of the difference between
+the current time and the LM time or 48 hours, whichever is smaller. Note that
+libdap ignores the DEFAULT_EXPIRES time in this case. Any request made before
+the expiration time will use the cached response without validation. Any
+request made after the expiration time will use a conditional GET. Servers
+that have been upgraded to 3.2 or greater will return a 304 response if the
+cached response is still valid or a new response if it is not valid.
+
+If the value of ALWAYS_VALIDATE is 1, then all accesses will be validated with
+the origin server. A value of 0 causes libwww to use the more complex
+expiration and validate algorithm.
+
+CONTROLLING DATA COMPRESSION
+
+If the DEFLATE parameter is set to one (DEFLATE=1) then clients will request 
+that servers compress data transmissions. Servers may or may not honor this
+request depending on their abilities.
+
+SSL VALIDATION
+
+Set VALIDATE_SSL to zero to turn off SSL server host and certificate
+validation. By default, SSL hosts and certificates are now validated. If
+you're using your own certificates and don't want to pay to have them signed
+by a CA or to run your own authorization site, use this to defeat SSL
+validation. The old libdap default behavior was to _not_ perform validation
+(because that was the old libcurl default) and we've included this option so
+that you can get that old behavior.
+
+PROXY SERVERS
+
+Note that the parameters PROXY_SERVER and NO_PROXY_FOR may be repeated
+to add multiple proxy servers, suppress proxy access for several hosts, etc.
+
+Lines 9 and 10 contain the parameters used to configure a proxy server.
+The parameter PROXY_SERVER configures a default proxy server. The format is
+
+    PROXY_SERVER=<protocol>,<proxy host url>
+
+The only supported protocols are http, https, and ftp.
+<proxy host url> must be a full URL to the host running the proxy server. If a
+password is used to access the proxy server, include it in the URL using the
+<user:password at host> syntax as shown in the example.
+
+The NO_PROXY parameter provides a simple way to say that access to a certain
+host should never go through a proxy. The syntax of NO_PROXY is:
+
+    NO_PROXY=<protocol>,<hostname>
+
+where <protocol> is as for PROXY_SERVER
+<hostname> is the name of the host, not a url.
+
+The Ancillary Information Service
+
+See README.AIS for more information about the AIS.
diff --git a/RValue.cc b/RValue.cc
new file mode 100644
index 0000000..adbe583
--- /dev/null
+++ b/RValue.cc
@@ -0,0 +1,177 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1996-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// This file contains mfuncs defined for struct rvalue (see expr.h) that
+// *cannot* be included in that struct's declaration because their
+// definitions must follow *both* rvalue's and func_rvalue's declarations.
+// jhrg 3/4/96
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: RValue.cc 24281 2011-03-09 00:22:31Z jimg $"
+    };
+
+#include <cassert>
+#include <iostream>
+
+#include "BaseType.h"
+#include "expr.h"
+#include "RValue.h"
+#include "DDS.h"
+#include "dods-limits.h"
+#include "util.h"
+
+using namespace std;
+
+namespace libdap {
+
+rvalue_list *
+make_rvalue_list(rvalue *rv)
+{
+    assert(rv);
+
+    rvalue_list *rvals = new rvalue_list;
+
+    return append_rvalue_list(rvals, rv);
+}
+
+// Given a rvalue_list pointer RVALS and a value pointer VAL, make a variable
+// to hold VAL and append that variable to the list RVALS.
+//
+// Returns: A pointer to the updated rvalue_list.
+
+rvalue_list *
+append_rvalue_list(rvalue_list *rvals, rvalue *rv)
+{
+    rvals->push_back(rv);
+
+    return rvals;
+}
+
+
+/** Build an argument list suitable for calling a \c btp_func,
+    \c bool_func, and so on. Since this takes an rvalue_list and
+    not an rvalue, it is a function rather than a class
+    member.
+
+    This function performs a common task but does not fit within the RValue
+    class well. It is used by Clause and ce_expr.y.
+
+    @param args A list of RValue objects
+    @param dds Use this DDS when evaluating functions */
+BaseType **
+build_btp_args(rvalue_list *args, DDS &dds)
+{
+    int argc = 0;
+
+    if (args)
+        argc = args->size();
+
+    // Sanitize allocation size
+    if (!size_ok(sizeof(BaseType*), argc + 1))
+        throw Error(malformed_expr, string("Malformed argument list (")
+                + long_to_string(argc) + string(")."));
+
+    // Add space for a null terminator
+    BaseType **argv = new BaseType*[argc + 1];
+
+    int index = 0;
+    if (argv && argc) {
+        for (rvalue::Args_iter i = args->begin(); i != args->end() && index
+                < argc + 1; ++i)
+            argv[index++] = (*i)->bvalue(dds);
+    }
+
+    if (index != argc) {
+        delete[] argv;
+        throw InternalErr(__FILE__, __LINE__, "index out of range.");
+    }
+
+    argv[index] = 0; // Add the null terminator.
+
+    return argv;
+}
+
+rvalue::rvalue(BaseType *bt): d_value(bt), d_func(0), d_args(0)
+{}
+
+rvalue::rvalue(btp_func f, vector<rvalue *> *a) : d_value(0), d_func(f), d_args(a)
+{}
+
+rvalue::rvalue(): d_value(0), d_func(0), d_args(0)
+{}
+
+rvalue::~rvalue()
+{
+    // Deleting the BaseType pointers in value and args is a bad idea since
+    // those might be variables in the dataset. The DDS dtor will take care
+    // of deleting them. The constants wrapped in BaseType objects should be
+    // pushed on the list of CE-allocated temp objects which the CE frees.
+}
+
+string
+rvalue::value_name()
+{
+    assert(d_value);
+
+    return d_value->name();
+}
+
+/** Return the BaseType * for a given rvalue. If
+    the rvalue is a func_rvalue, evaluates the func_rvalue and returns the
+    result. The functions referenced by func_rvalues must encapsulate their
+    return values in BaseType *s.
+
+    @param dds The dds to pass to a function.
+*/
+BaseType *
+rvalue::bvalue(DDS &dds)
+{
+    if (d_value) {        // i.e., if this RValue is a BaseType
+        return d_value;
+    }
+    else if (d_func) {
+        // If func is true, then args must be set. See the constructor.
+        // 12/23/04 jhrg
+        BaseType **argv = build_btp_args(d_args, dds);
+        BaseType *ret_val;
+        (*d_func)(d_args->size(), argv, dds, &ret_val);
+        delete[] argv;
+        return ret_val;
+    }
+    else {
+        return 0;
+    }
+}
+
+} // namespace libdap
+
diff --git a/RValue.h b/RValue.h
new file mode 100644
index 0000000..5175e72
--- /dev/null
+++ b/RValue.h
@@ -0,0 +1,77 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1998-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+#ifndef _rvalue_h
+#define _rvalue_h
+
+namespace libdap
+{
+
+/** Holds the rvalues for the parser, Clause objects and evaluator.
+
+    @see Clause.h
+    @see DDS.h
+    @see expr.y */
+
+class rvalue
+{
+private:
+    BaseType *d_value;
+    btp_func d_func;  // pointer to a function returning BaseType *
+    std::vector<rvalue *> *d_args;  // arguments to the function
+
+public:
+    typedef std::vector<rvalue *>::iterator Args_iter ;
+    typedef std::vector<rvalue *>::const_iterator Args_citer ;
+
+    rvalue(BaseType *bt);
+    rvalue(btp_func f, vector<rvalue *> *a);
+    rvalue();
+
+    virtual ~rvalue();
+    string value_name();
+
+    BaseType *bvalue(DDS &dds);
+};
+
+// This type def must come after the class definition above. It is used in
+// the Clause and DDS classes.
+typedef std::vector<rvalue *> rvalue_list;
+typedef std::vector<rvalue *>::const_iterator rvalue_list_citer ;
+typedef std::vector<rvalue *>::iterator rvalue_list_iter ;
+
+rvalue_list *make_rvalue_list(rvalue *rv);
+rvalue_list *append_rvalue_list(rvalue_list *rvals, rvalue *rv);
+
+BaseType **build_btp_args(rvalue_list *args, DDS &dds);
+
+} // namespace libdap
+#endif // _rvalue_h
diff --git a/Resource.h b/Resource.h
new file mode 100644
index 0000000..96389fd
--- /dev/null
+++ b/Resource.h
@@ -0,0 +1,156 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef resource_h
+#define resource_h
+
+#include <string>
+#include <iostream>
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+using namespace std;
+
+namespace libdap
+{
+
+/** Bind an ancillary resource with the rule that should be used when
+    combining it with a primary resource. Ancillary resources are always
+    specified using URLs. If an ancillary resource is a local file, use
+    <code>file://</code> URLs.
+
+    Note that operator<< is defined for Resource as a function.
+
+    @brief Associate a rule with an ancillary resource.
+    @author James Gallagher <jgallagher at opendap.org> */
+class Resource
+{
+public:
+
+    /** The AIS uses this enumeration to describe how a given ancillary should
+    be merged into a primary data source.
+
+    <ul>
+    <li>overwrite: Attributes in the ancillary source overwrite those in
+    the primary source. New values are added.</li>
+    <li>replace: The ancillary source replaces the primary. All of the
+    Attributes in the primary are removed.</li>
+    <li>fallback: The ancillary resource provides a set of fallback values
+    if the primary data source lacks any attributes. Note that this does
+    not apply to individual attributes, but to an entire set. The fallback
+    attributes are used only if the original data source lacks attributes
+    altogether. 
+    </ul>
+
+    @brief How are ancillary resources used.
+    @author James Gallagher <jgallagher at opendap.org> */
+    enum rule { overwrite, replace, fallback };
+
+    /** Build a Resource with a null URL and set the combination rule to the
+    default. */
+    Resource() : d_url(""), d_rule(overwrite)
+    {}
+
+    /** Build a resource. Set the combination rule to the default value,
+    which is overwrite. 
+    @param u The ancillary resource URL. */
+    Resource(const string &u) : d_url(u), d_rule(overwrite)
+    {}
+
+    /** Build a Resource.
+    @param u The ancillary resource URL.
+    @param r The combination rule. */
+    Resource(const string &u, const rule &r) : d_url(u), d_rule(r)
+    {}
+
+    /** Build a Resource.
+
+        Note: If this is used in a callback, make sure to check the value of
+    <code>r</code> before calling this constructor. Exceptions thrown
+    within callbacks are not portable. Valid values are "overwrite",
+    "replace" and "fallback". The constructor accepts "default" as a
+    synonym for "overwrite".
+
+    @param u The ancillary resource URL.
+    @param r The name of the combination rule. */
+    Resource(const string &u, const string &r) throw(Error) : d_url(u)
+    {
+        if (r == "replace")
+            d_rule = replace;
+        else if (r == "fallback")
+            d_rule = fallback;
+        else if (r == "overwrite" || r == "default")
+            d_rule = overwrite;
+        else
+            throw Error(string("An AIS Resource object was created with an unknown rule type '") + r);
+    }
+
+    virtual ~Resource()
+{}
+
+    /** Return the resource URL. */
+    virtual string get_url() const
+    {
+        return d_url;
+    }
+
+    /** Set the resource URL.
+    @param u The resource's URL. */
+    virtual void set_url(const string &u)
+    {
+        d_url = u;
+    }
+
+    /** Return combination rule for this resource. */
+    virtual Resource::rule get_rule() const
+    {
+        return d_rule;
+    }
+
+    /** Set the resource's combination rule.
+    @param r The combination rule. */
+    virtual void set_rule(const Resource::rule &r)
+    {
+        d_rule = r;
+    }
+
+    /** Write the XML for this resource. This function is defined in
+    AISResoruces. 
+    @param os Write to this ostream.
+    @paran r The Resource to write. */
+    friend ostream &operator<<(ostream &os, const Resource &r);
+
+
+private:
+
+    string d_url;
+    Resource::rule d_rule;
+};
+
+} // namespace libdap
+
+#endif // resource_h
diff --git a/Response.h b/Response.h
new file mode 100644
index 0000000..aaa96f2
--- /dev/null
+++ b/Response.h
@@ -0,0 +1,160 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef response_h
+#define response_h
+
+#include <cstdio>
+#include <string>
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+using namespace std;
+
+#ifndef _object_type_h
+#include "ObjectType.h"
+#endif
+
+#ifndef _internalerr_h
+#include "InternalErr.h"
+#endif
+
+namespace libdap
+{
+
+/** Encapsulate a response. Instead of directly returning the FILE pointer
+    from which a response is read, return an instance of this object. For a
+    simple system where all that needs to be done to free the stream and its
+    associated resources, this is overkill. However, some streams may require
+    complex operations to free their resources once the client is done with
+    the stream. Those classes should return a subclass of Response
+    which has those operations built into the destructor.
+
+    @todo If the code that parses the MIME headers was moved from Connect and
+    HTTPConnect to this class and its children, it would be easier to build
+    a FileConnect class (or maybe the specifics of the connection type could
+    be held in the Response object and HTTPConnect and the to be written
+    FileConnect would not be needed). */
+class Response
+{
+private:
+    /// The data stream
+    FILE *d_stream;
+    /// Response object type
+    ObjectType d_type;
+    /// Server version
+    string d_version;
+    /// The DAP server's protocol
+    string d_protocol;
+    /// The HTTP response code
+    int d_status;
+
+protected:
+    /** @name Suppressed default methods */
+    //@{
+    Response()
+    {}
+    Response(const Response &)
+    {}
+    Response &operator=(const Response &)
+    {
+        throw InternalErr(__FILE__, __LINE__, "Unimplemented assignment");
+    }
+    //@}
+
+public:
+    /** Initialize with a stream. Create an instance initialized to a stream.
+	by default get_type() and get_version() return default values of
+	unknown_type and "dods/0.0", respectively. Specializations (see
+	HTTPResponse and HTTPConnect) may fill these fields in with other
+	values.
+        @param s Read data from this stream.
+        @param status The HTTP response status code.*/
+    Response(FILE *s, int status = 0) : d_stream(s), d_type(unknown_type),
+            d_version("dods/0.0"), d_protocol("2.0"),
+            d_status(status)
+    { }
+
+    /** Close the stream. */
+    virtual ~Response()
+    {
+        if (d_stream)
+            fclose(d_stream);
+    }
+
+    /** @name Accessors */
+    //@{
+    virtual int get_status() const
+    {
+        return d_status;
+    }
+    virtual FILE *get_stream() const
+    {
+        return d_stream;
+    }
+    virtual ObjectType get_type() const
+    {
+        return d_type;
+    }
+    virtual string get_version() const
+    {
+        return d_version;
+    }
+    virtual string get_protocol() const
+    {
+        return d_protocol;
+    }
+    //@}
+
+    /** @name Mutators */
+    //@{
+    virtual void set_status(int s)
+    {
+        d_status = s;
+    }
+    virtual void set_stream(FILE *s)
+    {
+        d_stream = s;
+    }
+    virtual void set_type(ObjectType o)
+    {
+        d_type = o;
+    }
+    virtual void set_version(const string &v)
+    {
+        d_version = v;
+    }
+    virtual void set_protocol(const string &p)
+    {
+        d_protocol = p;
+    }
+    //@}
+};
+
+} // namespace libdap
+
+#endif // response_h
diff --git a/ResponseBuilder.cc b/ResponseBuilder.cc
new file mode 100644
index 0000000..33266ab
--- /dev/null
+++ b/ResponseBuilder.cc
@@ -0,0 +1,723 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2011 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+static char rcsid[] not_used = { "$Id: ResponseBuilder.cc 23477 2010-09-02 21:02:59Z jimg $" };
+
+#include <signal.h>
+
+#ifndef WIN32
+// #include <unistd.h>   // for getopt
+#include <sys/wait.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include <iostream>
+#include <string>
+#include <sstream>
+#include <cstring>
+
+#include <uuid/uuid.h>	// used to build CID header value for data ddx
+
+#include "DAS.h"
+#include "DDS.h"
+#include "debug.h"
+#include "mime_util.h"	// for last_modified_time() and rfc_822_date()
+#include "escaping.h"
+#include "ResponseBuilder.h"
+#include "XDRStreamMarshaller.h"
+
+#ifndef WIN32
+#include "SignalHandler.h"
+#include "EventHandler.h"
+#include "AlarmHandler.h"
+#endif
+
+#define CRLF "\r\n"             // Change here, expr-test.cc
+using namespace std;
+
+namespace libdap {
+
+ResponseBuilder::~ResponseBuilder()
+{
+}
+
+/** Called when initializing a ResponseBuilder that's not going to be passed a
+ command line arguments. */
+void ResponseBuilder::initialize()
+{
+    // Set default values. Don't use the C++ constructor initialization so
+    // that a subclass can have more control over this process.
+    d_dataset = "";
+    d_ce = "";
+    d_timeout = 0;
+
+    d_default_protocol = DAP_PROTOCOL_VERSION;
+#if 0 	// Keyword support moved to Keywords class
+    // Load known_keywords
+    d_known_keywords.insert("dap2");
+    d_known_keywords.insert("dap2.0");
+
+    d_known_keywords.insert("dap3.2");
+    d_known_keywords.insert("dap3.3");
+
+    d_known_keywords.insert("dap4");
+    d_known_keywords.insert("dap4.0");
+#endif
+#ifdef WIN32
+    //  We want serving from win32 to behave in a manner
+    //  similar to the UNIX way - no CR->NL terminated lines
+    //  in files. Hence stdout goes to binary mode.
+    _setmode(_fileno(stdout), _O_BINARY);
+#endif
+}
+
+#if 0
+/**
+ * Add the keyword to the set of keywords that apply to this request.
+ * @param kw The keyword
+ */
+void ResponseBuilder::add_keyword(const string &kw)
+{
+    d_keywords.insert(kw);
+}
+
+/**
+ * Lookup a keyword and return true if it has been set for this request,
+ * otherwise return false.
+ * @param kw Keyword
+ * @return true if the keyword is set.
+ */
+bool ResponseBuilder::is_keyword(const string &kw) const
+{
+    return d_keywords.count(kw) != 0;
+}
+
+/**
+ * Get a list of the strings that make up the set of current keywords for
+ * this request.
+ * @return The list of keywords as a list of string objects.
+ */
+list<string> ResponseBuilder::get_keywords() const
+{
+    list<string> kws;
+    set<string>::const_iterator i;
+    for (i = d_keywords.begin(); i != d_keywords.end(); ++i)
+	kws.push_front(*i);
+    return kws;
+}
+
+/**
+ * Is the word one of the known keywords for this version of libdap?
+ * @param w
+ * @return true if the keyword is known
+ */
+bool ResponseBuilder::is_known_keyword(const string &w) const
+{
+    return d_known_keywords.count(w) != 0;
+}
+#endif
+
+/** Return the entire constraint expression in a string.  This
+ includes both the projection and selection clauses, but not the
+ question mark.
+
+ @brief Get the constraint expression.
+ @return A string object that contains the constraint expression. */
+string ResponseBuilder::get_ce() const
+{
+    return d_ce;
+}
+
+void ResponseBuilder::set_ce(string _ce)
+{
+    d_ce = www2id(_ce, "%", "%20");
+
+#if 0
+    // Get the whole CE
+    string projection = www2id(_ce, "%", "%20");
+    string selection = "";
+
+    // Separate the selection part (which follows/includes the first '&')
+    string::size_type amp = projection.find('&');
+    if (amp != string::npos) {
+	selection = projection.substr(amp);
+	projection = projection.substr(0, amp);
+    }
+
+    // Extract keywords; add to the ResponseBuilder keywords. For this, scan for
+    // a known set of keywords and assume that anything else is part of the
+    // projection and should be left alone. Keywords must come before variables
+    // The 'projection' string will look like: '' or 'dap4.0' or 'dap4.0,u,v'
+    while (!projection.empty()) {
+	string::size_type i = projection.find(',');
+	string next_word = projection.substr(0, i);
+	if (is_known_keyword(next_word)) {
+	    add_keyword(next_word);
+	    projection = projection.substr(i + 1);
+	}
+	else {
+	    break; // exit on first non-keyword
+	}
+    }
+
+    // The CE is whatever is left after removing the keywords
+    d_ce = projection + selection;
+#endif
+}
+
+/** The ``dataset name'' is the filename or other string that the
+ filter program will use to access the data. In some cases this
+ will indicate a disk file containing the data.  In others, it
+ may represent a database query or some other exotic data
+ access method.
+
+ @brief Get the dataset name.
+ @return A string object that contains the name of the dataset. */
+string ResponseBuilder::get_dataset_name() const
+{
+    return d_dataset;
+}
+
+void ResponseBuilder::set_dataset_name(const string ds)
+{
+    d_dataset = www2id(ds, "%", "%20");
+}
+
+/** Set the server's timeout value. A value of zero (the default) means no
+ timeout.
+
+ @param t Server timeout in seconds. Default is zero (no timeout). */
+void ResponseBuilder::set_timeout(int t)
+{
+    d_timeout = t;
+}
+
+/** Get the server's timeout value. */
+int ResponseBuilder::get_timeout() const
+{
+    return d_timeout;
+}
+
+/** Use values of this instance to establish a timeout alarm for the server.
+ If the timeout value is zero, do nothing.
+
+ @todo When the alarm handler is called, two CRLF pairs are dumped to the
+ stream and then an Error object is sent. No attempt is made to write the
+ 'correct' MIME headers for an Error object. Instead, a savvy client will
+ know that when an exception is thrown during a deserialize operation, it
+ should scan ahead in the input stream for an Error object. Add this, or a
+ sensible variant once libdap++ supports reliable error delivery. Dumb
+ clients will never get the Error object... */
+void ResponseBuilder::establish_timeout(ostream &stream) const
+{
+#ifndef WIN32
+    if (d_timeout > 0) {
+	SignalHandler *sh = SignalHandler::instance();
+	EventHandler *old_eh = sh->register_handler(SIGALRM, new AlarmHandler(stream));
+	delete old_eh;
+	alarm(d_timeout);
+    }
+#endif
+}
+
+/** This function formats and prints an ASCII representation of a
+ DAS on stdout.  This has the effect of sending the DAS object
+ back to the client program.
+
+ @brief Transmit a DAS.
+ @param out The output stream to which the DAS is to be sent.
+ @param das The DAS object to be sent.
+ @param anc_location The directory in which the external DAS file resides.
+ @param with_mime_headers If true (the default) send MIME headers.
+ @return void
+ @see DAS */
+void ResponseBuilder::send_das(ostream &out, DAS &das, bool with_mime_headers) const
+{
+    if (with_mime_headers)
+	set_mime_text(out, dods_das, x_plain, last_modified_time(d_dataset), "2.0");
+    das.print(out);
+
+    out << flush;
+}
+
+/** This function formats and prints an ASCII representation of a
+ DDS on stdout.  When called by a CGI program, this has the
+ effect of sending a DDS object back to the client
+ program. Either an entire DDS or a constrained DDS may be sent.
+
+ @brief Transmit a DDS.
+ @param out The output stream to which the DAS is to be sent.
+ @param dds The DDS to send back to a client.
+ @param eval A reference to the ConstraintEvaluator to use.
+ @param constrained If this argument is true, evaluate the
+ current constraint expression and send the `constrained DDS'
+ back to the client.
+ @param anc_location The directory in which the external DAS file resides.
+ @param with_mime_headers If true (the default) send MIME headers.
+ @return void
+ @see DDS */
+void ResponseBuilder::send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval, bool constrained,
+	bool with_mime_headers) const
+{
+    // If constrained, parse the constraint. Throws Error or InternalErr.
+    if (constrained)
+	eval.parse_constraint(d_ce, dds);
+
+    if (eval.functional_expression())
+	throw Error("Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
+
+    if (with_mime_headers)
+	set_mime_text(out, dods_dds, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
+
+    if (constrained)
+	dds.print_constrained(out);
+    else
+	dds.print(out);
+
+    out << flush;
+}
+
+void ResponseBuilder::dataset_constraint(ostream &out, DDS & dds, ConstraintEvaluator & eval, bool ce_eval) const
+{
+    // send constrained DDS
+    dds.print_constrained(out);
+    out << "Data:\n";
+    out << flush;
+
+    // Grab a stream that encodes using XDR.
+    XDRStreamMarshaller m(out);
+
+    try {
+	// Send all variables in the current projection (send_p())
+	for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
+	    if ((*i)->send_p()) {
+		DBG(cerr << "Sending " << (*i)->name() << endl);
+		(*i)->serialize(eval, dds, m, ce_eval);
+	    }
+    }
+    catch (Error & e) {
+	throw;
+    }
+}
+
+void ResponseBuilder::dataset_constraint_ddx( ostream &out, DDS & dds, ConstraintEvaluator & eval,
+	const string &boundary, const string &start, bool ce_eval) const
+{
+    // Write the MPM headers for the DDX (text/xml) part of the response
+    set_mime_ddx_boundary(out, boundary, start, dap4_ddx);
+
+    // Make cid
+    uuid_t uu;
+    uuid_generate(uu);
+    char uuid[37];
+    uuid_unparse(uu, &uuid[0]);
+    char domain[256];
+    if (getdomainname(domain, 255) != 0 || strlen(domain) == 0)
+	strncpy(domain, "opendap.org", 255);
+
+    string cid = string(&uuid[0]) + "@" + string(&domain[0]);
+
+    // Send constrained DDX with a data blob reference
+    dds.print_xml(out, true, cid);
+
+    // Write the MPM headers for the data part of the response.
+    set_mime_data_boundary(out, boundary, cid, dap4_data, binary);
+
+    // Grab a stream that encodes using XDR.
+    XDRStreamMarshaller m(out);
+
+    try {
+	// Send all variables in the current projection (send_p())
+	for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++)
+	    if ((*i)->send_p()) {
+		DBG(cerr << "Sending " << (*i)->name() << endl);
+		(*i)->serialize(eval, dds, m, ce_eval);
+	    }
+    }
+    catch (Error & e) {
+	throw;
+    }
+}
+
+/** Send the data in the DDS object back to the client program. The data is
+ encoded using a Marshaller, and enclosed in a MIME document which is all sent
+ to \c data_stream. If this is being called from a CGI, \c data_stream is
+ probably \c stdout and writing to it has the effect of sending the
+ response back to the client.
+
+ @brief Transmit data.
+ @param dds A DDS object containing the data to be sent.
+ @param eval A reference to the ConstraintEvaluator to use.
+ @param data_stream Write the response to this stream.
+ @param anc_location A directory to search for ancillary files (in
+ addition to the CWD).  This is used in a call to
+ get_data_last_modified_time().
+ @param with_mime_headers If true, include the MIME headers in the response.
+ Defaults to true.
+ @return void */
+void ResponseBuilder::send_data(ostream & data_stream, DDS & dds, ConstraintEvaluator & eval, bool with_mime_headers) const
+{
+    // Set up the alarm.
+    establish_timeout(data_stream);
+    dds.set_timeout(d_timeout);
+
+    eval.parse_constraint(d_ce, dds); // Throws Error if the ce doesn't
+    // parse.
+
+    dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+    // Start sending the response...
+
+    // Handle *functional* constraint expressions specially
+    if (eval.function_clauses()) {
+	DDS *fdds = eval.eval_function_clauses(dds);
+	if (with_mime_headers)
+	    set_mime_binary(data_stream, dods_data, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
+
+	dataset_constraint(data_stream, *fdds, eval, false);
+	delete fdds;
+    }
+    else {
+	if (with_mime_headers)
+	    set_mime_binary(data_stream, dods_data, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
+
+	dataset_constraint(data_stream, dds, eval);
+    }
+
+    data_stream << flush;
+}
+
+/** Send the DDX response. The DDX never contains data, instead it holds a
+ reference to a Blob response which is used to get the data values. The
+ DDS and DAS objects are built using code that already exists in the
+ servers.
+
+ @param dds The dataset's DDS \e with attributes in the variables.
+ @param eval A reference to the ConstraintEvaluator to use.
+ @param out Destination
+ @param with_mime_headers If true, include the MIME headers in the response.
+ Defaults to true. */
+void ResponseBuilder::send_ddx(ostream &out, DDS &dds, ConstraintEvaluator &eval, bool with_mime_headers) const
+{
+    // If constrained, parse the constraint. Throws Error or InternalErr.
+    if (!d_ce.empty())
+	eval.parse_constraint(d_ce, dds);
+
+    if (eval.functional_expression())
+	throw Error(
+		"Function calls can only be used with data requests. To see the structure of the underlying data source, reissue the URL without the function.");
+
+    if (with_mime_headers)
+	set_mime_text(out, dap4_ddx, x_plain, last_modified_time(d_dataset), dds.get_dap_version());
+    dds.print_xml(out, !d_ce.empty(), "");
+}
+
+/** Send the data in the DDS object back to the client program. The data is
+ encoded using a Marshaller, and enclosed in a MIME document which is all sent
+ to \c data_stream. If this is being called from a CGI, \c data_stream is
+ probably \c stdout and writing to it has the effect of sending the
+ response back to the client.
+
+ @brief Transmit data.
+ @param dds A DDS object containing the data to be sent.
+ @param eval A reference to the ConstraintEvaluator to use.
+ @param data_stream Write the response to this stream.
+ @param anc_location A directory to search for ancillary files (in
+ addition to the CWD).  This is used in a call to
+ get_data_last_modified_time().
+ @param with_mime_headers If true, include the MIME headers in the response.
+ Defaults to true.
+ @return void */
+void ResponseBuilder::send_data_ddx(ostream & data_stream, DDS & dds, ConstraintEvaluator & eval, const string &start,
+	const string &boundary, bool with_mime_headers) const
+{
+    // Set up the alarm.
+    establish_timeout(data_stream);
+    dds.set_timeout(d_timeout);
+
+    eval.parse_constraint(d_ce, dds); // Throws Error if the ce doesn't
+    // parse.
+
+    dds.tag_nested_sequences(); // Tag Sequences as Parent or Leaf node.
+
+    // Start sending the response...
+
+    // Handle *functional* constraint expressions specially
+    if (eval.function_clauses()) {
+	DDS *fdds = eval.eval_function_clauses(dds);
+	if (with_mime_headers)
+	    set_mime_multipart(data_stream, boundary, start, dap4_data_ddx, x_plain, last_modified_time(d_dataset));
+	data_stream << flush;
+	// TODO: Change this to dataset_constraint_ddx()
+	dataset_constraint(data_stream, *fdds, eval, false);
+	delete fdds;
+    }
+    else {
+	if (with_mime_headers)
+	    set_mime_multipart(data_stream, boundary, start, dap4_data_ddx, x_plain, last_modified_time(d_dataset));
+	data_stream << flush;
+	dataset_constraint_ddx(data_stream, dds, eval, boundary, start);
+    }
+
+    data_stream << flush;
+
+    if (with_mime_headers)
+	data_stream << CRLF << "--" << boundary << "--" << CRLF;
+}
+
+static const char *descrip[] = { "unknown", "dods_das", "dods_dds", "dods_data", "dods_error", "web_error", "dap4-ddx",
+	"dap4-data", "dap4-error", "dap4-data-ddx", "dods_ddx" };
+static const char *encoding[] = { "unknown", "deflate", "x-plain", "gzip", "binary" };
+
+/** Generate an HTTP 1.0 response header for a text document. This is used
+ when returning a serialized DAS or DDS object.
+
+ @param strm Write the MIME header to this stream.
+ @param type The type of this this response. Defaults to
+ application/octet-stream.
+ @param ver The version string; denotes the libdap implementation
+ version.
+ @param enc How is this response encoded? Can be plain or deflate or the
+ x_... versions of those. Default is x_plain.
+ @param last_modified The time to use for the Last-Modified header value.
+ Default is zero which means use the current time. */
+void ResponseBuilder::set_mime_text(ostream &strm, ObjectType type,
+	EncodingType enc, const time_t last_modified,
+	const string &protocol) const
+{
+    strm << "HTTP/1.0 200 OK" << CRLF;
+
+    strm << "XDODS-Server: " << DVR << CRLF;
+    strm << "XOPeNDAP-Server: " << DVR << CRLF;
+
+    if (protocol == "")
+	strm << "XDAP: " << d_default_protocol << CRLF;
+    else
+	strm << "XDAP: " << protocol  << CRLF;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Last-Modified: ";
+    if (last_modified > 0)
+	strm << rfc822_date(last_modified).c_str() << CRLF;
+    else
+	strm << rfc822_date(t).c_str() << CRLF;
+
+    if (type == dap4_ddx)
+	strm << "Content-Type: text/xml" << CRLF;
+    else
+	strm << "Content-Type: text/plain" << CRLF;
+
+    // Note that Content-Description is from RFC 2045 (MIME, pt 1), not 2616.
+    // jhrg 12/23/05
+    strm << "Content-Description: " << descrip[type] << CRLF;
+    if (type == dods_error) // don't cache our error responses.
+	strm << "Cache-Control: no-cache" << CRLF;
+    // Don't write a Content-Encoding header for x-plain since that breaks
+    // Netscape on NT. jhrg 3/23/97
+    if (enc != x_plain)
+	strm << "Content-Encoding: " << encoding[enc] << CRLF;
+    strm << CRLF;
+}
+
+/** Generate an HTTP 1.0 response header for a html document.
+
+ @param strm Write the MIME header to this stream.
+ @param type The type of this this response.
+ @param ver The version string; denotes the libdap implementation
+ version.
+ @param enc How is this response encoded? Can be plain or deflate or the
+ x_... versions of those. Default is x_plain.
+ @param last_modified The time to use for the Last-Modified header value.
+ Default is zero which means use the current time. */
+void ResponseBuilder::set_mime_html(ostream &strm, ObjectType type,
+	EncodingType enc, const time_t last_modified,
+	const string &protocol) const
+{
+    strm << "HTTP/1.0 200 OK" << CRLF;
+
+    strm << "XDODS-Server: " << DVR << CRLF;
+    strm << "XOPeNDAP-Server: " << DVR << CRLF;
+
+    if (protocol == "")
+	strm << "XDAP: " << d_default_protocol << CRLF;
+    else
+	strm << "XDAP: " << protocol  << CRLF;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Last-Modified: ";
+    if (last_modified > 0)
+	strm << rfc822_date(last_modified).c_str() << CRLF;
+    else
+	strm << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Content-type: text/html" << CRLF;
+    // See note above about Content-Description header. jhrg 12/23/05
+    strm << "Content-Description: " << descrip[type] << CRLF;
+    if (type == dods_error) // don't cache our error responses.
+	strm << "Cache-Control: no-cache" << CRLF;
+    // Don't write a Content-Encoding header for x-plain since that breaks
+    // Netscape on NT. jhrg 3/23/97
+    if (enc != x_plain)
+	strm << "Content-Encoding: " << encoding[enc] << CRLF;
+    strm << CRLF;
+}
+
+/** Write an HTTP 1.0 response header for our binary response document (i.e.,
+ the DataDDS object).
+
+ @param strm Write the MIME header to this stream.
+ @param type The type of this this response. Defaults to
+ application/octet-stream.
+ @param ver The version string; denotes the libdap implementation
+ version.
+ @param enc How is this response encoded? Can be plain or deflate or the
+ x_... versions of those. Default is x_plain.
+ @param last_modified The time to use for the Last-Modified header value.
+ Default is zero which means use the current time.
+ */
+void ResponseBuilder::set_mime_binary(ostream &strm, ObjectType type,
+	EncodingType enc, const time_t last_modified,
+	const string &protocol) const
+{
+    strm << "HTTP/1.0 200 OK" << CRLF;
+
+    strm << "XDODS-Server: " << DVR << CRLF;
+    strm << "XOPeNDAP-Server: " << DVR << CRLF;
+
+    if (protocol == "")
+	strm << "XDAP: " << d_default_protocol << CRLF;
+    else
+	strm << "XDAP: " << protocol  << CRLF;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Last-Modified: ";
+    if (last_modified > 0)
+	strm << rfc822_date(last_modified).c_str() << CRLF;
+    else
+	strm << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Content-Type: application/octet-stream" << CRLF;
+    strm << "Content-Description: " << descrip[type] << CRLF;
+    if (enc != x_plain)
+	strm << "Content-Encoding: " << encoding[enc] << CRLF;
+
+    strm << CRLF;
+}
+
+void ResponseBuilder::set_mime_multipart(ostream &strm, const string &boundary,
+	const string &start, ObjectType type, EncodingType enc,
+	const time_t last_modified, const string &protocol) const
+{
+    strm << "HTTP/1.0 200 OK" << CRLF;
+
+    strm << "XDODS-Server: " << DVR << CRLF;
+    strm << "XOPeNDAP-Server: " << DVR << CRLF;
+
+    if (protocol == "")
+	strm << "XDAP: " << d_default_protocol << CRLF;
+    else
+	strm << "XDAP: " << protocol  << CRLF;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Last-Modified: ";
+    if (last_modified > 0)
+	strm << rfc822_date(last_modified).c_str() << CRLF;
+    else
+	strm << rfc822_date(t).c_str() << CRLF;
+
+    strm << "Content-Type: Multipart/Related; boundary=" << boundary << "; start=\"<" << start
+	    << ">\"; type=\"Text/xml\"" << CRLF;
+    strm << "Content-Description: " << descrip[type] << CRLF;
+    if (enc != x_plain)
+	strm << "Content-Encoding: " << encoding[enc] << CRLF;
+
+    strm << CRLF;
+}
+
+void ResponseBuilder::set_mime_ddx_boundary(ostream &strm, const string &boundary,
+	const string &cid, ObjectType type, EncodingType enc) const
+{
+    strm << "--" << boundary << CRLF;
+    strm << "Content-Type: Text/xml; charset=iso-8859-1" << CRLF;
+    strm << "Content-Id: <" << cid << ">" << CRLF;
+    strm << "Content-Description: " << descrip[type] << CRLF;
+    if (enc != x_plain)
+	strm << "Content-Encoding: " << encoding[enc] << CRLF;
+
+    strm << CRLF;
+}
+
+void ResponseBuilder::set_mime_data_boundary(ostream &strm, const string &boundary,
+	const string &cid, ObjectType type, EncodingType enc) const
+{
+    strm << "--" << boundary << CRLF;
+    strm << "Content-Type: application/octet-stream" << CRLF;
+    strm << "Content-Id: <" << cid << ">" << CRLF;
+    strm << "Content-Description: " << descrip[type] << CRLF;
+    if (enc != x_plain)
+	strm << "Content-Encoding: " << encoding[enc] << CRLF;
+
+    strm << CRLF;
+}
+
+/** Generate an HTTP 1.0 response header for an Error object.
+ @param strm Write the MIME header to this stream.
+ @param code HTTP 1.0 response code. Should be 400, ... 500, ...
+ @param reason Reason string of the HTTP 1.0 response header.
+ @param version The version string; denotes the DAP spec and implementation
+ version. */
+void ResponseBuilder::set_mime_error(ostream &strm, int code, const string &reason,
+	const string &protocol) const
+{
+    strm << "HTTP/1.0 " << code << " " << reason.c_str() << CRLF;
+
+    strm << "XDODS-Server: " << DVR << CRLF;
+    strm << "XOPeNDAP-Server: " << DVR << CRLF;
+
+    if (protocol == "")
+	strm << "XDAP: " << d_default_protocol << CRLF;
+    else
+	strm << "XDAP: " << protocol  << CRLF;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF;
+    strm << "Cache-Control: no-cache" << CRLF;
+    strm << CRLF;
+}
+
+} // namespace libdap
+
diff --git a/ResponseBuilder.h b/ResponseBuilder.h
new file mode 100644
index 0000000..e8418ef
--- /dev/null
+++ b/ResponseBuilder.h
@@ -0,0 +1,166 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2011 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _response_builder_h
+#define _response_builder_h
+
+#include <string>
+#include <set>
+
+#ifndef _das_h
+#include "DAS.h"
+#endif
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#ifndef _object_type_h
+#include "ObjectType.h"
+#endif
+
+#ifndef _encodingtype_h
+#include "EncodingType.h"
+#endif
+
+namespace libdap
+{
+
+/**
+
+ @brief Build responses for Hyrax server modules/handlers.
+ @author jhrg 1/28/2011 */
+
+class ResponseBuilder
+{
+public:
+    friend class ResponseBuilderTest;
+
+protected:
+    string d_dataset;  		/// Name of the dataset/database
+    string d_ce;  		/// Constraint expression
+    int d_timeout;  		/// Response timeout after N seconds
+    string d_default_protocol;	/// Version string for the library's default protocol version
+
+#if 0	// Keyword support moved to Keywords class
+    set<string> d_keywords; 	/// Holds all of the keywords passed in the CE
+    set<string> d_known_keywords; /// Holds all of the keywords libdap understands.
+#endif
+    void initialize();
+
+public:
+
+    /** Make an empty instance. Use the set_*() methods to load with needed
+        values. You must call at least set_dataset_name() or be requesting
+        version information. */
+    ResponseBuilder() {
+        initialize();
+    }
+
+    virtual ~ResponseBuilder();
+#if 0
+    virtual void add_keyword(const string &kw);
+    virtual bool is_keyword(const string &kw) const;
+    virtual list<string> get_keywords() const;
+    // This method holds all of the keywords that this version of libdap groks
+    virtual bool is_known_keyword(const string &w) const;
+#endif
+
+    virtual string get_ce() const;
+    virtual void set_ce(string _ce);
+
+    virtual string get_dataset_name() const;
+    virtual void set_dataset_name(const string _dataset);
+
+    void set_timeout(int timeout = 0);
+    int get_timeout() const;
+
+    virtual void establish_timeout(ostream &stream) const;
+
+    virtual void send_das(ostream &out, DAS &das,
+                          bool with_mime_headers = true) const;
+    virtual void send_dds(ostream &out, DDS &dds, ConstraintEvaluator &eval,
+                          bool constrained = false,
+                          bool with_mime_headers = true) const;
+
+    virtual void dataset_constraint(ostream &out, DDS &dds, ConstraintEvaluator &eval,
+                                    bool ce_eval = true) const;
+    virtual void dataset_constraint_ddx(ostream &out, DDS & dds, ConstraintEvaluator & eval,
+                                   const string &boundary, const string &start,
+                                   bool ce_eval = true) const;
+
+    virtual void send_data(ostream &data_stream, DDS &dds, ConstraintEvaluator &eval,
+                           bool with_mime_headers = true) const;
+
+    virtual void send_ddx(ostream &out, DDS &dds, ConstraintEvaluator &eval,
+                          bool with_mime_headers = true) const;
+
+    virtual void send_data_ddx(ostream &data_stream, DDS &dds, ConstraintEvaluator &eval,
+                           const string &start, const string &boundary,
+                           bool with_mime_headers = true) const;
+
+    // These functions are used both by the methods above and by other code
+
+    void set_mime_text(ostream &out, ObjectType type = unknown_type,
+                       EncodingType enc = x_plain,
+                       const time_t last_modified = 0,
+                       const string &protocol = "") const;
+
+    void set_mime_html(ostream &out, ObjectType type = unknown_type,
+                       EncodingType enc = x_plain,
+                       const time_t last_modified = 0,
+                       const string &protocol = "") const;
+
+    void set_mime_binary(ostream &out, ObjectType type = unknown_type,
+                         EncodingType enc = x_plain,
+                         const time_t last_modified = 0,
+                         const string &protocol = "") const;
+
+    void set_mime_multipart(ostream &out, const string &boundary,
+    	const string &start, ObjectType type = unknown_type,
+            EncodingType enc = x_plain,
+            const time_t last_modified = 0,
+            const string &protocol = "") const;
+
+    void set_mime_ddx_boundary(ostream &out, const string &boundary,
+    	const string &start, ObjectType type = unknown_type,
+            EncodingType enc = x_plain) const;
+
+    void set_mime_data_boundary(ostream &out, const string &boundary,
+    	const string &cid, ObjectType type = unknown_type,
+            EncodingType enc = x_plain) const;
+
+    void set_mime_error(ostream &out, int code = 404,
+                        const string &reason = "Dataset not found",
+                        const string &protocol = "") const;
+};
+
+} // namespace libdap
+
+#endif // _response_builder_h
diff --git a/ResponseTooBigErr.cc b/ResponseTooBigErr.cc
new file mode 100644
index 0000000..c0017d5
--- /dev/null
+++ b/ResponseTooBigErr.cc
@@ -0,0 +1,52 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: ResponseTooBigErr.cc 17856 2008-02-02 21:25:59Z pwest $"
+    };
+
+#include <string>
+
+#include "ResponseTooBigErr.h"
+
+namespace libdap {
+
+ResponseTooBigErr::ResponseTooBigErr() : Error()
+{
+    _error_code = unknown_error;
+}
+
+ResponseTooBigErr::ResponseTooBigErr(const string &msg) : Error()
+{
+    _error_code = unknown_error;
+    _error_message = "";
+    _error_message += "A caching error was encounterd:\n";
+    _error_message += msg + "\n";
+}
+
+} // namespace libdap
diff --git a/ResponseTooBigErr.h b/ResponseTooBigErr.h
new file mode 100644
index 0000000..6f87fb8
--- /dev/null
+++ b/ResponseTooBigErr.h
@@ -0,0 +1,55 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _response_too_big_err_h
+#define _response_too_big_err_h 1
+
+
+#include <string>
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+namespace libdap
+{
+
+/** ResponseTooBigErr is thrown by HTTPCache::parse_header and write_body if
+    the response that's being cached is too big. The HTTPCache methods
+    determine just what 'too big' means.
+
+    @author jhrg */
+
+class ResponseTooBigErr: public Error
+{
+
+public:
+    ResponseTooBigErr(const string &msg);
+    ResponseTooBigErr();
+};
+
+} // namespace libdap
+
+#endif // _response_too_big_err_h
diff --git a/Sequence.cc b/Sequence.cc
new file mode 100644
index 0000000..7b753cc
--- /dev/null
+++ b/Sequence.cc
@@ -0,0 +1,1570 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the class Structure
+//
+// jhrg 9/14/94
+
+
+#include "config.h"
+
+#include <algorithm>
+#include <string>
+#include <sstream>
+
+//#define DODS_DEBUG
+//#define DODS_DEBUG2
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "debug.h"
+#include "Error.h"
+#include "InternalErr.h"
+#include "Sequence.h"
+#include "DDS.h"
+#include "DataDDS.h"
+#include "util.h"
+#include "InternalErr.h"
+#include "escaping.h"
+
+using namespace std;
+
+namespace libdap {
+
+static const unsigned char end_of_sequence = 0xA5; // binary pattern 1010 0101
+static const unsigned char start_of_instance = 0x5A; // binary pattern 0101 1010
+
+// Private member functions
+
+void
+Sequence::_duplicate(const Sequence &s)
+{
+    d_row_number = s.d_row_number;
+    d_starting_row_number = s.d_starting_row_number;
+    d_ending_row_number = s.d_ending_row_number;
+    d_row_stride = s.d_row_stride;
+    d_leaf_sequence = s.d_leaf_sequence;
+    d_unsent_data = s.d_unsent_data;
+    d_wrote_soi = s.d_wrote_soi;
+    d_top_most = s.d_top_most;
+
+    Sequence &cs = const_cast<Sequence &>(s);
+
+    // Copy the template BaseType objects.
+    for (Vars_iter i = cs.var_begin(); i != cs.var_end(); i++) {
+        add_var((*i)) ;
+    }
+
+    // Copy the BaseType objects used to hold values.
+    for (vector<BaseTypeRow *>::iterator rows_iter = cs.d_values.begin();
+         rows_iter != cs.d_values.end();
+         rows_iter++) {
+        // Get the current BaseType Row
+        BaseTypeRow *src_bt_row_ptr = *rows_iter;
+        // Create a new row.
+        BaseTypeRow *dest_bt_row_ptr = new BaseTypeRow;
+        // Copy the BaseType objects from a row to new BaseType objects.
+        // Push new BaseType objects onto new row.
+        for (BaseTypeRow::iterator bt_row_iter = src_bt_row_ptr->begin();
+             bt_row_iter != src_bt_row_ptr->end();
+             bt_row_iter++) {
+            BaseType *src_bt_ptr = *bt_row_iter;
+            BaseType *dest_bt_ptr = src_bt_ptr->ptr_duplicate();
+            dest_bt_row_ptr->push_back(dest_bt_ptr);
+        }
+        // Push new row onto d_values.
+        d_values.push_back(dest_bt_row_ptr);
+    }
+}
+
+static void
+write_end_of_sequence(Marshaller &m)
+{
+    m.put_opaque( (char *)&end_of_sequence, 1 ) ;
+}
+
+static void
+write_start_of_instance(Marshaller &m)
+{
+    m.put_opaque( (char *)&start_of_instance, 1 ) ;
+}
+
+static unsigned char
+read_marker(UnMarshaller &um)
+{
+    unsigned char marker;
+    um.get_opaque( (char *)&marker, 1 ) ;
+
+    return marker;
+}
+
+static bool
+is_start_of_instance(unsigned char marker)
+{
+    return (marker == start_of_instance);
+}
+
+static bool
+is_end_of_sequence(unsigned char marker)
+{
+    return (marker == end_of_sequence);
+}
+
+// Public member functions
+
+/** The Sequence constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+
+    @brief The Sequence constructor. */
+Sequence::Sequence(const string &n) : Constructor(n, dods_sequence_c),
+        d_row_number(-1), d_starting_row_number(-1),
+        d_row_stride(1), d_ending_row_number(-1),
+        d_unsent_data(false), d_wrote_soi(false),
+        d_leaf_sequence(false), d_top_most(false)
+{}
+
+/** The Sequence server-side constructor requires the name of the variable
+    to be created and the dataset name from which this variable is being
+    created.
+
+    @param n A string containing the name of the variable to be
+    created.
+    @param d A string containing the name of the dataset from which this
+    variable is being created.
+
+    @brief The Sequence server-side constructor. */
+Sequence::Sequence(const string &n, const string &d)
+    : Constructor(n, d, dods_sequence_c),
+      d_row_number(-1), d_starting_row_number(-1),
+      d_row_stride(1), d_ending_row_number(-1),
+      d_unsent_data(false), d_wrote_soi(false),
+      d_leaf_sequence(false), d_top_most(false)
+{}
+
+/** @brief The Sequence copy constructor. */
+Sequence::Sequence(const Sequence &rhs) : Constructor(rhs)
+{
+    _duplicate(rhs);
+}
+
+BaseType *
+Sequence::ptr_duplicate()
+{
+    return new Sequence(*this);
+}
+
+static inline void
+delete_bt(BaseType *bt_ptr)
+{
+    DBG2(cerr << "In delete_bt: " << bt_ptr << endl);
+    delete bt_ptr; bt_ptr = 0;
+}
+
+static inline void
+delete_rows(BaseTypeRow *bt_row_ptr)
+{
+    DBG2(cerr << "In delete_rows: " << bt_row_ptr << endl);
+
+    for_each(bt_row_ptr->begin(), bt_row_ptr->end(), delete_bt);
+
+    delete bt_row_ptr; bt_row_ptr = 0;
+}
+
+Sequence::~Sequence()
+{
+    DBG2(cerr << "Entering Sequence::~Sequence" << endl);
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        BaseType *btp = *i ;
+        delete btp ; btp = 0;
+    }
+
+    for_each(d_values.begin(), d_values.end(), delete_rows);
+    DBG2(cerr << "exiting Sequence::~Sequence" << endl);
+}
+
+Sequence &
+Sequence::operator=(const Sequence &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+string
+Sequence::toString()
+{
+    ostringstream oss;
+
+    oss << BaseType::toString();
+
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        oss << (*i)->toString();
+    }
+
+    oss << endl;
+
+    return oss.str();
+}
+
+int
+Sequence::element_count(bool leaves)
+{
+    if (!leaves)
+        return _vars.size();
+    else {
+        int i = 0;
+        for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
+            i += (*iter)->element_count(true);
+        }
+        return i;
+    }
+}
+
+bool
+Sequence::is_linear()
+{
+    bool linear = true;
+    bool seq_found = false;
+    for (Vars_iter iter = _vars.begin(); linear && iter != _vars.end(); iter++) {
+        if ((*iter)->type() == dods_sequence_c) {
+            // A linear sequence cannot have more than one child seq. at any
+            // one level. If we've already found a seq at this level, return
+            // false.
+            if (seq_found) {
+                linear = false;
+                break;
+            }
+            seq_found = true;
+            linear = dynamic_cast<Sequence *>((*iter))->is_linear();
+        }
+        else if ((*iter)->type() == dods_structure_c) {
+            linear = dynamic_cast<Structure*>((*iter))->is_linear();
+        }
+        else {
+            // A linear sequence cannot have Arrays, Lists or Grids.
+            linear = (*iter)->is_simple_type();
+        }
+    }
+
+    return linear;
+}
+
+void
+Sequence::set_send_p(bool state)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->set_send_p(state);
+    }
+
+    BaseType::set_send_p(state);
+}
+
+void
+Sequence::set_read_p(bool state)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->set_read_p(state);
+    }
+
+    BaseType::set_read_p(state);
+}
+
+void
+Sequence::set_in_selection(bool state)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->set_in_selection(state);
+    }
+
+    BaseType::set_in_selection(state);
+}
+
+/** @brief Adds a variable to the Sequence.
+
+    Remember that if you wish to add a member to a nested
+    Sequence, you must use the <tt>add_var()</tt> of that
+    Sequence.  This means that variable names need not be unique
+    among a set of nested Sequences.
+
+    @param bt A pointer to the DAP2 type variable to add to this Sequence.
+    @param part defaults to nil */
+void
+Sequence::add_var(BaseType *bt, Part)
+{
+    if (!bt)
+        throw InternalErr(__FILE__, __LINE__,
+                          "Cannot add variable: NULL pointer");
+    // Jose Garcia
+    // We append a copy of bt so the owner of bt is free to deallocate
+
+    BaseType *bt_copy = bt->ptr_duplicate();
+    bt_copy->set_parent(this);
+    _vars.push_back(bt_copy);
+}
+
+// Deprecated
+BaseType *
+Sequence::var(const string &n, btp_stack &s)
+{
+    string name = www2id(n);
+
+    BaseType *btp = m_exact_match(name, &s);
+    if (btp)
+        return btp;
+
+    return m_leaf_match(name, &s);
+}
+
+BaseType *
+Sequence::var(const string &name, bool exact_match, btp_stack *s)
+{
+    string n = www2id(name);
+
+    if (exact_match)
+        return m_exact_match(n, s);
+    else
+        return m_leaf_match(n, s);
+}
+
+BaseType *
+Sequence::m_leaf_match(const string &name, btp_stack *s)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        if ((*i)->name() == name) {
+            if (s)
+                s->push(static_cast<BaseType *>(this));
+            return *i;
+        }
+        if ((*i)->is_constructor_type()) {
+            BaseType *btp = (*i)->var(name, false, s);
+            if (btp) {
+                if (s)
+                    s->push(static_cast<BaseType *>(this));
+                return btp;
+            }
+        }
+    }
+
+    return 0;
+}
+
+BaseType *
+Sequence::m_exact_match(const string &name, btp_stack *s)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        if ((*i)->name() == name) {
+            if (s)
+                s->push(static_cast<BaseType *>(this));
+            return *i;
+        }
+    }
+
+    string::size_type dot_pos = name.find("."); // zero-based index of `.'
+    if (dot_pos != string::npos) {
+        string aggregate = name.substr(0, dot_pos);
+        string field = name.substr(dot_pos + 1);
+
+        BaseType *agg_ptr = var(aggregate);
+        if (agg_ptr) {
+            if (s)
+                s->push(static_cast<BaseType *>(this));
+            return agg_ptr->var(field, true, s); // recurse
+        }
+        else
+            return 0;  // qualified names must be *fully* qualified
+    }
+
+    return 0;
+}
+
+/** @brief Get a whole row from the sequence.
+    @param row Get row number <i>row</i> from the sequence.
+    @return A BaseTypeRow object (vector<BaseType *>). Null if there's no such
+    row number as \e row. */
+BaseTypeRow *
+Sequence::row_value(size_t row)
+{
+    if (row >= d_values.size())
+        return 0;
+    return d_values[row];
+}
+
+/** Set value of this Sequence. This does not perform a deep copy, so data
+    should be allocated on the heap and freed only when the Sequence dtor is
+    called.
+    @see SequenceValues
+    @see BaseTypeRow
+    @param values Set the value of this Sequence. */
+void
+Sequence::set_value(SequenceValues &values)
+{
+    d_values = values;
+}
+
+/** Get the value for this sequence.
+    @return The SequenceValues object for this Sequence. */
+SequenceValues
+Sequence::value()
+{
+    return d_values;
+}
+
+/** @brief Get the BaseType pointer to the named variable of a given row.
+    @param row Read from <i>row</i> in the sequence.
+    @param name Return <i>name</i> from <i>row</i>.
+    @return A BaseType which holds the variable and its value.
+    @see number_of_rows */
+BaseType *
+Sequence::var_value(size_t row, const string &name)
+{
+    BaseTypeRow *bt_row_ptr = row_value(row);
+    if (!bt_row_ptr)
+        return 0;
+
+    BaseTypeRow::iterator bt_row_iter = bt_row_ptr->begin();
+    BaseTypeRow::iterator bt_row_end = bt_row_ptr->end();
+    while (bt_row_iter != bt_row_end && (*bt_row_iter)->name() != name)
+        ++bt_row_iter;
+
+    if (bt_row_iter == bt_row_end)
+        return 0;
+    else
+        return *bt_row_iter;
+}
+
+/** @brief Get the BaseType pointer to the $i^{th}$ variable of <i>row</i>.
+    @param row Read from <i>row</i> in the sequence.
+    @param i Return the $i^{th}$ variable from <i>row</i>.
+    @return A BaseType which holds the variable and its value.
+    @see number_of_rows */
+BaseType *
+Sequence::var_value(size_t row, size_t i)
+{
+    BaseTypeRow *bt_row_ptr = row_value(row);
+    if (!bt_row_ptr)
+        return 0;
+
+    if (i >= bt_row_ptr->size())
+        return 0;
+
+    return (*bt_row_ptr)[i];
+}
+
+unsigned int
+Sequence::width()
+{
+    unsigned int sz = 0;
+
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        sz += (*i)->width();
+    }
+
+    return sz;
+}
+
+// This version returns -1. Each API-specific subclass should define a more
+// reasonable version. jhrg 5/24/96
+
+/** Returns the number of elements in a Sequence object. Note that
+    this is <i>not</i> the number of items in a row, but the number
+    of rows in the complete sequence object. To be meaningful, this
+    must be computed after constraint expresseion (CE) evaluation.
+    The purpose of this function is to facilitate translations
+    between Sequence objects and Array objects, particularly when
+    the Sequence is too large to be transferred from the server to
+    the client in its entirety.
+
+    This function, to be useful, must be specialized for the API and
+    data format in use.
+
+    @return The base implentation returns -1, indicating that the
+    length is not known.  Sub-classes specific to a particular API
+    will have a more complete implementation. */
+int
+Sequence::length()
+{
+    return -1;
+}
+
+
+int
+Sequence::number_of_rows()
+{
+    return d_values.size();
+}
+
+/** When reading a nested sequence, use this method to reset the internal
+    row number counter. This is necessary so that the second, ... instances
+    of the inner/nested sequence will start off reading row zero. */
+void
+Sequence::reset_row_number()
+{
+    d_row_number = -1;
+}
+
+// Notes:
+// Assume that read() is implemented so that, when reading data for a nested
+// sequence, only the outer most level is *actually* read.
+// This is a consequence of our current (12/7/99) implementation of
+// the JGOFS server (which is the only server to actually use nested
+// sequences). 12/7/99 jhrg
+//
+// Stop assuming this. This logic is being moved into the JGOFS server
+// itself. 6/1/2001 jhrg
+
+// The read() function returns a boolean value, with TRUE
+// indicating that read() should be called again because there's
+// more data to read, and FALSE indicating there's no more data
+// to read. Note that this behavior is necessary to properly
+// handle variables that contain Sequences. Jose Garcia If an
+// error exists while reading, the implementers of the surrogate
+// library SHOULD throw an Error object which will propagate
+// beyond this point to to the original caller.
+// Jose Garcia
+
+/** Read row number <i>row</i> of the Sequence. The values of the row
+    are obtained by calling the read() method of the sequence. The
+    current \e row just read is stored in the Sequence instance
+    along with its row number. If a selection expression has been
+    supplied, rows are counted only if they satisfy that expression.
+
+    Note that we can only advance in a Sequence. It is not possible to back up
+    and read a row numbered lower than the current row. If you need that
+    you will need to replace the serialize() method with one of your own.
+
+    Used on the server side.
+
+    @note The first row is row number zero. A Sequence with 100 rows will
+    have row numbers 0 to 99.
+
+    @todo This code ignores the main reason for nesting the sequences, that
+    if the outer Sequence's current instance fails the CE, there's no need to
+    look at the values of the inner Sequence. But in the code that calls this
+    method (serialize() and intern_data()) the CE is not evaluated until the
+    inner-most Sequence (i.e., the leaf Sequence) is read. That means that
+    each instance of the inner Sequence is read and the CE evaluated for each
+    of those reads. To fix this, and the overall problem of complexity here,
+    we need to re-think Sequences and how they behave. 11/13/2007 jhrg
+
+    @return A boolean value, with TRUE indicating that read_row
+    should be called again because there's more data to be read.
+    FALSE indicates the end of the Sequence.
+    @param row The row number to read.
+    @param dds A reference to the DDS for this dataset.
+    @param eval Use this as the constraint expression evaluator.
+    @param ce_eval If True, evaluate any CE, otherwise do not.
+*/
+bool
+Sequence::read_row(int row, DDS &dds,
+                   ConstraintEvaluator &eval, bool ce_eval)
+{
+    DBG2(cerr << "Entering Sequence::read_row for " << name() << endl);
+    if (row < d_row_number)
+        throw InternalErr("Trying to back up inside a sequence!");
+
+    DBG2(cerr << "read_row: row number " << row
+              << ", current row " << d_row_number << endl);
+    if (row == d_row_number)
+    {
+	DBG2(cerr << "Leaving Sequence::read_row for " << name() << endl);
+        return true;
+    }
+
+    dds.timeout_on();
+
+    int eof = 0;  // Start out assuming EOF is false.
+    while (!eof && d_row_number < row) {
+        if (!read_p()) {
+            eof = (read() == false);
+        }
+
+        // Advance the row number if ce_eval is false (we're not supposed to
+        // evaluate the selection) or both ce_eval and the selection are
+        // true.
+        if (!eof && (!ce_eval || eval.eval_selection(dds, dataset())))
+            d_row_number++;
+
+        set_read_p(false); // ...so that the next instance will be read
+    }
+
+    // Once we finish the above loop, set read_p to true so that the caller
+    // knows that data *has* been read. This is how the read() methods of the
+    // elements of the sequence know to not call read() but instead look for
+    // data values inside themselves.
+    set_read_p(true);
+
+    dds.timeout_off();
+
+    // Return true if we have valid data, false if we've read to the EOF.
+    DBG2(cerr << "Leaving Sequence::read_row for " << name()
+              << " with " << (eof == 0) << endl);
+    return eof == 0;
+}
+
+// Private. This is used to process constraints on the rows of a sequence.
+// Starting with 3.2 we support constraints like Sequence[10:2:20]. This
+// odd-looking logic first checks if d_ending_row_number is the sentinel
+// value of -1. If so, the sequence was not constrained by row number and
+// this method should never return true (which indicates that we're at the
+// end of a row-number constraint). If d_ending_row_number is not -1, then is
+// \e i at the end point? 6/1/2001 jhrg
+inline bool
+Sequence::is_end_of_rows(int i)
+{
+    return ((d_ending_row_number == -1) ? false : (i > d_ending_row_number));
+}
+
+/** Serialize a Sequence.
+
+    Leaf Sequences must be marked as such (see DDS::tag_nested_sequence()),
+    as must the top most Sequence.
+
+    How the code works. Methods called for various functions are named in
+    brackets:
+    <ol>
+    <li>Sending a one-level sequence:
+    <pre>
+    Dataset {
+        Sequence {
+            Int x;
+            Int y;
+        } flat;
+    } case_1;
+    </pre>
+
+    Serialize it by reading successive rows and sending all of those that
+    satisfy the CE. Before each row, send a start of instance (SOI) marker.
+    Once all rows have been sent, send an End of Sequence (EOS)
+    marker.[serialize_leaf].</li>
+
+    <li>Sending a nested sequence:
+    <pre>
+    Dataset {
+        Sequence {
+            Int t;
+            Sequence {
+                Int z;
+            } inner;
+        } outer;
+    } case_2;
+    </pre>
+
+    Serialize by reading the first row of outer and storing the values. Do
+    not evaluate the CE [serialize_parent_part_one]. Call serialize() for inner
+    and read each row for it, evaluating the CE for each row that is read.
+    After the first row of inner is read and satisfies the CE, write out the
+    SOI marker and values for outer [serialize_parent_part_two], then write
+    the SOI and values for the first row of inner. Continue to read and send
+    rows of inner until the last row has been read. Send EOS for inner
+    [serialize_leaf]. Now read the next row of outer and repeat. Once outer
+    is completely read, send its EOS marker.</li>
+    </ol>
+
+    Notes:
+    <ol>
+    <li>For a nested Sequence, the child sequence must follow all other types
+    in the parent sequence (like the example). There may be only one nested
+    Sequence per level.</li>
+
+    <li>CE evaluation happens only in a leaf sequence.</li>
+
+    <li>When no data statisfies a CE, the empty Sequence is signalled by a
+    single EOS marker, regardless of the level of nesting of Sequences. That
+    is, the EOS marker is sent for only the outer Sequence in the case of a
+    completely empty response.</li>
+    </ol>
+*/
+bool
+Sequence::serialize(ConstraintEvaluator &eval, DDS &dds,
+                    Marshaller &m, bool ce_eval)
+{
+    DBG2(cerr << "Entering Sequence::serialize for " << name() << endl);
+
+    // Special case leaf sequences!
+    if (is_leaf_sequence())
+        return serialize_leaf(dds, eval, m, ce_eval);
+    else
+        return serialize_parent_part_one(dds, eval, m);
+}
+
+// We know this is not a leaf Sequence. That means that this Sequence holds
+// another Sequence as one of its fields _and_ that child Sequence triggers
+// the actual transmission of values.
+
+bool
+Sequence::serialize_parent_part_one(DDS &dds,
+                                    ConstraintEvaluator &eval, Marshaller &m)
+{
+    DBG2(cerr << "Entering serialize_parent_part_one for " << name() << endl);
+
+    int i = (d_starting_row_number != -1) ? d_starting_row_number : 0;
+
+    // read_row returns true if valid data was read, false if the EOF was
+    // found. 6/1/2001 jhrg
+    // Since this is a parent sequence, read the row ignoring the CE (all of
+    // the CE clauses will be evaluated by the leaf sequence).
+    bool status = read_row(i, dds, eval, false);
+    DBG2(cerr << "Sequence::serialize_parent_part_one::read_row() status: " << status << endl);
+
+    while (status && !is_end_of_rows(i)) {
+        i += d_row_stride;
+
+        // DBG(cerr << "Writing Start of Instance marker" << endl);
+        // write_start_of_instance(sink);
+
+        // In this loop serialize will signal an error with an exception.
+        for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
+            // Only call serialize for child Sequences; the leaf sequence
+            // will trigger the transmission of values for its parents (this
+            // sequence and maybe others) once it gets soem valid data to
+            // send.
+            // Note that if the leaf sequence has no variables in the current
+            // projection, its serialize() method will never be called and that's
+            // the method that triggers actually sending values. Thus the leaf
+            // sequence must be the lowest level sequence with values whose send_p
+            // property is true.
+            if ((*iter)->send_p() && (*iter)->type() == dods_sequence_c)
+                (*iter)->serialize(eval, dds, m);
+        }
+
+        set_read_p(false); // ...so this will read the next instance
+
+        status = read_row(i, dds, eval, false);
+        DBG(cerr << "Sequence::serialize_parent_part_one::read_row() status: " << status << endl);
+    }
+    // Reset current row number for next nested sequence element.
+    d_row_number = -1;
+
+    // Always write the EOS marker? 12/23/04 jhrg
+    // Yes. According to DAP2, a completely empty response is signalled by
+    // a return value of only the EOS marker for the outermost sequence.
+    if (d_top_most || d_wrote_soi) {
+        DBG(cerr << "Writing End of Sequence marker" << endl);
+        write_end_of_sequence(m);
+        d_wrote_soi = false;
+    }
+
+    return true;  // Signal errors with exceptions.
+}
+
+// If we are here then we know that this is 'parent sequence' and that the
+// leaf seq has found valid data to send. We also know that
+// serialize_parent_part_one has been called so data are in the instance's
+// fields. This is wheree we send data. Whereas ..._part_one() contains a
+// loop to iterate over all of rows in a parent sequence, this does not. This
+// method assumes that the serialize_leaf() will call it each time it needs
+// to be called.
+//
+// NB: This code only works if the child sequences appear after all other
+// variables.
+void
+Sequence::serialize_parent_part_two(DDS &dds,
+                                    ConstraintEvaluator &eval, Marshaller &m)
+{
+    DBG(cerr << "Entering serialize_parent_part_two for " << name() << endl);
+
+    BaseType *btp = get_parent();
+    if (btp && btp->type() == dods_sequence_c)
+        dynamic_cast<Sequence&>(*btp).serialize_parent_part_two(dds, eval, m);
+
+    if (d_unsent_data) {
+        DBG(cerr << "Writing Start of Instance marker" << endl);
+        d_wrote_soi = true;
+        write_start_of_instance(m);
+
+        // In this loop serialize will signal an error with an exception.
+        for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
+            // Send all the non-sequence variables
+            DBG(cerr << "Sequence::serialize_parent_part_two(), serializing "
+                << (*iter)->name() << endl);
+            if ((*iter)->send_p() && (*iter)->type() != dods_sequence_c) {
+                DBG(cerr << "Send P is true, sending " << (*iter)->name() << endl);
+                (*iter)->serialize(eval, dds, m, false);
+            }
+        }
+
+        d_unsent_data = false;              // read should set this.
+    }
+}
+
+// This code is only run by a leaf sequence. Note that a one level sequence
+// is also a leaf sequence.
+bool
+Sequence::serialize_leaf(DDS &dds,
+                         ConstraintEvaluator &eval, Marshaller &m, bool ce_eval)
+{
+    DBG(cerr << "Entering Sequence::serialize_leaf for " << name() << endl);
+    int i = (d_starting_row_number != -1) ? d_starting_row_number : 0;
+
+    // read_row returns true if valid data was read, false if the EOF was
+    // found. 6/1/2001 jhrg
+    bool status = read_row(i, dds, eval, ce_eval);
+    DBG(cerr << "Sequence::serialize_leaf::read_row() status: " << status << endl);
+
+    // Once the first valid (satisfies the CE) row of the leaf sequence has
+    // been read, we know we're going to send data. Send the current instance
+    // of the parent/ancestor sequences now, if there are any. We only need
+    // to do this once, hence it's not inside the while loop, but we only
+    // send the parent seq data _if_ there's data in the leaf to send, that's
+    // why we wait until after the first call to read_row() here in the leaf
+    // sequence.
+    //
+    // NB: It's important to only call serialize_parent_part_two() for a
+    // Sequence that really is the parent of a leaf sequence. The fancy cast
+    // will throw and exception if btp is not a Sequence, but doesn't test
+    // that it's a parent sequence as we've defined them here.
+    if (status && !is_end_of_rows(i)) {
+        BaseType *btp = get_parent();
+        if (btp && btp->type() == dods_sequence_c)
+            dynamic_cast<Sequence&>(*btp).serialize_parent_part_two(dds,
+								    eval, m);
+    }
+
+    d_wrote_soi = false;
+    while (status && !is_end_of_rows(i)) {
+        i += d_row_stride;
+
+        DBG(cerr << "Writing Start of Instance marker" << endl);
+        d_wrote_soi = true;
+        write_start_of_instance(m);
+
+        // In this loop serialize will signal an error with an exception.
+        for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
+            DBG(cerr << "Sequence::serialize_leaf(), serializing "
+                << (*iter)->name() << endl);
+            if ((*iter)->send_p()) {
+                DBG(cerr << "Send P is true, sending " << (*iter)->name() << endl);
+                (*iter)->serialize(eval, dds, m, false);
+            }
+        }
+
+        set_read_p(false); // ...so this will read the next instance
+
+        status = read_row(i, dds, eval, ce_eval);
+        DBG(cerr << "Sequence::serialize_leaf::read_row() status: " << status << endl);
+    }
+
+    // Only write the EOS marker if there's a matching Start Of Instnace
+    // Marker in the stream.
+    if (d_wrote_soi || d_top_most) {
+        DBG(cerr << "Writing End of Sequence marker" << endl);
+        write_end_of_sequence(m);
+    }
+
+    return true;  // Signal errors with exceptions.
+}
+
+/** This method is used to evaluate a constraint and based on those results
+    load the Sequence variable with data. This simulates having a server call
+    the serialize() method and a client call the deserialize() method without
+    the overhead of any IPC. Use this method on the server-side to 'load the
+    d_values field with data' so that other code and work with those data.
+
+    The somewhat odd algorithm used by serialize() is largely copied here, so
+    comments about logic in serialize() and the related methods apply here
+    as well.
+
+    @note Even though each Sequence variable has a \e values field, only the
+    top-most Sequence in a hierarchy of Sequences holds values. The field
+    accessed by the var_value() method is completely linked object; access
+    the values of nested Sequences using the BaseType objects returned by
+    var_value().
+
+    @note Only call this method for top-most Sequences. Never call it for
+    Sequences which have a parent (directly or indirectly) variable that is
+    a Sequence.
+
+    @param eval Use this contraint evaluator
+    @param dds This DDS holds the variables for the data source */
+void
+Sequence::intern_data(ConstraintEvaluator &eval, DDS &dds)
+{
+    DBG(cerr << "Sequence::intern_data - for " << name() << endl);
+    DBG2(cerr << "    intern_data, values: " << &d_values << endl);
+
+    // Why use a stack instead of return values? We need the stack because
+    // Sequences neted three of more levels deep will loose the middle
+    // instances when the intern_data_parent_part_two() code is run.
+    sequence_values_stack_t sequence_values_stack;
+
+    DBG2(cerr << "    pushing d_values of " << name() << " (" << &d_values
+              << ") on stack; size: " << sequence_values_stack.size() << endl);
+    sequence_values_stack.push(&d_values);
+
+    intern_data_private(eval, dds, sequence_values_stack);
+}
+
+void
+Sequence::intern_data_private(ConstraintEvaluator &eval,
+                              DDS &dds,
+                              sequence_values_stack_t &sequence_values_stack)
+{
+    DBG(cerr << "Entering intern_data_private for " << name() << endl);
+
+    if (is_leaf_sequence())
+        intern_data_for_leaf(dds, eval, sequence_values_stack);
+    else
+        intern_data_parent_part_one(dds, eval, sequence_values_stack);
+}
+
+void
+Sequence::intern_data_parent_part_one(DDS & dds,
+                                      ConstraintEvaluator & eval,
+                                      sequence_values_stack_t &
+                                      sequence_values_stack)
+{
+    DBG(cerr << "Entering intern_data_parent_part_one for " << name() << endl);
+
+    int i = (get_starting_row_number() != -1) ? get_starting_row_number() : 0;
+
+    // read_row returns true if valid data was read, false if the EOF was
+    // found. 6/1/2001 jhrg
+    // Since this is a parent sequence, read the row ignoring the CE (all of
+    // the CE clauses will be evaluated by the leaf sequence).
+    bool status = read_row(i, dds, eval, false);
+
+    // Grab the current size of the value stack. We do this because it is
+    // possible that no nested sequences for this row happened to be
+    // selected because of a constract evaluation or the last row is not
+    // selected because of a constraint evaluation. In either case, no
+    // nested sequence d_values are pused onto the stack, so there is
+    // nothing to pop at the end of this function. pcw 07/14/08
+    SequenceValues::size_type orig_stack_size = sequence_values_stack.size() ;
+
+    while (status
+           && (get_ending_row_number() == -1
+               || i <= get_ending_row_number()))
+    {
+        i += get_row_stride();
+        for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
+            if ((*iter)->send_p()) {
+                switch ((*iter)->type()) {
+                case dods_sequence_c:
+                    dynamic_cast<Sequence&>(**iter).intern_data_private(
+                            eval, dds, sequence_values_stack);
+                    break;
+
+                default:
+                    (*iter)->intern_data(eval, dds);
+                    break;
+                }
+            }
+        }
+
+        set_read_p(false);      // ...so this will read the next instance
+
+        status = read_row(i, dds, eval, false);
+    }
+
+    // Reset current row number for next nested sequence element.
+    reset_row_number();
+
+    // if the size of the stack is larger than the original size (retrieved
+    // above) then pop the top set of d_values from the stack. If it's the
+    // same, then no nested sequences, or possible the last nested sequence,
+    // were pushed onto the stack, so there is nothing to pop.
+    if( sequence_values_stack.size() > orig_stack_size )
+    {
+	DBG2(cerr << "    popping d_values (" << sequence_values_stack.top()
+	     << ") off stack; size: " << sequence_values_stack.size() << endl);
+	sequence_values_stack.pop();
+    }
+    DBG(cerr << "Leaving intern_data_parent_part_one for " << name() << endl);
+}
+
+void
+Sequence::intern_data_parent_part_two(DDS &dds,
+			      ConstraintEvaluator &eval,
+			      sequence_values_stack_t &sequence_values_stack)
+{
+    DBG(cerr << "Entering intern_data_parent_part_two for " << name() << endl);
+
+    BaseType *btp = get_parent();
+    if (btp && btp->type() == dods_sequence_c) {
+        dynamic_cast<Sequence&>(*btp).intern_data_parent_part_two(
+                                      dds, eval, sequence_values_stack);
+    }
+
+    DBG2(cerr << "    stack size: " << sequence_values_stack.size() << endl);
+    SequenceValues *values = sequence_values_stack.top();
+    DBG2(cerr << "    using values = " << (void *)values << endl);
+
+    if (get_unsent_data()) {
+        BaseTypeRow *row_data = new BaseTypeRow;
+
+        // In this loop transfer_data will signal an error with an exception.
+        for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
+
+            if ((*iter)->send_p() && (*iter)->type() != dods_sequence_c) {
+                row_data->push_back((*iter)->ptr_duplicate());
+            }
+            else if ((*iter)->send_p()) { //Sequence; must be the last variable
+                Sequence *tmp = dynamic_cast<Sequence*>((*iter)->ptr_duplicate());
+                if (!tmp) {
+                	delete row_data;
+                    throw InternalErr(__FILE__, __LINE__, "Expected a Sequence.");
+                }
+                row_data->push_back(tmp);
+                DBG2(cerr << "    pushing d_values of " << tmp->name()
+		     << " (" << &(tmp->d_values)
+                     << ") on stack; size: " << sequence_values_stack.size()
+		     << endl);
+                // This pushes the d_values field of the newly created leaf
+                // Sequence onto the stack. The code then returns to intern
+                // _data_for_leaf() where this value will be used.
+                sequence_values_stack.push(&(tmp->d_values));
+            }
+        }
+
+        DBG2(cerr << "    pushing values for " << name()
+	          << " to " << values << endl);
+        values->push_back(row_data);
+        set_unsent_data(false);
+    }
+    DBG(cerr << "Leaving intern_data_parent_part_two for " << name() << endl);
+}
+
+void
+Sequence::intern_data_for_leaf(DDS &dds,
+                               ConstraintEvaluator &eval,
+                               sequence_values_stack_t &sequence_values_stack)
+{
+    DBG(cerr << "Entering intern_data_for_leaf for " << name() << endl);
+
+    int i = (get_starting_row_number() != -1) ? get_starting_row_number() : 0;
+
+    DBG2(cerr << "    reading row " << i << endl);
+    bool status = read_row(i, dds, eval, true);
+    DBG2(cerr << "    status: " << status << endl);
+    DBG2(cerr << "    ending row number: " << get_ending_row_number() << endl);
+
+    if (status && (get_ending_row_number() == -1 || i <= get_ending_row_number())) {
+        BaseType *btp = get_parent();
+        if (btp && btp->type() == dods_sequence_c) {
+            // This call will read the values for the parent sequences and
+            // then allocate a new instance for the leaf and push that onto
+            // the stack.
+            dynamic_cast<Sequence&>(*btp).intern_data_parent_part_two(
+					    dds, eval, sequence_values_stack);
+        }
+
+        // intern_data_parent_part_two pushes the d_values field of the leaf
+        // onto the stack, so this operation grabs that value and then loads
+        // data into it.
+        SequenceValues *values = sequence_values_stack.top();
+        DBG2(cerr << "    using values = " << values << endl);
+
+        while (status && (get_ending_row_number() == -1
+                          || i <= get_ending_row_number())) {
+            i += get_row_stride();
+
+            // Copy data from the object's fields to this new BaeTypeRow instance
+            BaseTypeRow *row_data = new BaseTypeRow;
+            for (Vars_iter iter = var_begin(); iter != var_end(); iter++) {
+                if ((*iter)->send_p()) {
+                    row_data->push_back((*iter)->ptr_duplicate());
+                }
+            }
+
+            DBG2(cerr << "    pushing values for " << name()
+	              << " to " << values << endl);
+            // Save the row_data to values().
+            values->push_back(row_data);
+
+            set_read_p(false);      // ...so this will read the next instance
+            // Read the ith row into this object's fields
+            status = read_row(i, dds, eval, true);
+        }
+
+        DBG2(cerr << "    popping d_values (" << sequence_values_stack.top()
+             << ") off stack; size: " << sequence_values_stack.size() << endl);
+        sequence_values_stack.pop();
+    }
+    DBG(cerr << "Leaving intern_data_for_leaf for " << name() << endl);
+}
+
+/** @brief Deserialize (read from the network) the entire Sequence.
+
+    This method used to read a single row at a time. Now the entire
+    sequence is read at once. The method used to return True to indicate
+    that more data needed to be deserialized and False when the sequence
+    was completely read. Now it simply returns false. This might seem odd,
+    but making this method return false breaks existing software the least.
+
+    @param um An UnMarshaller that knows how to deserialize data
+    @param dds A DataDDS from which to read.
+    @param reuse Passed to child objects when they are deserialized. Some
+    implementations of derialize() use this to determine if new storage should
+    be allocated or existing storage reused.
+    @exception Error if a sequence stream marker cannot be read.
+    @exception InternalErr if the <tt>dds</tt> param is not a DataDDS.
+    @return A return value of false indicates that an EOS ("end of
+    Sequence") marker was found, while a value of true indicates
+    that there are more rows to be read. This version always reads the
+    entire sequence, so it always returns false.
+*/
+bool
+Sequence::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
+{
+    DataDDS *dd = dynamic_cast<DataDDS *>(dds);
+    if (!dd)
+        throw InternalErr("Expected argument 'dds' to be a DataDDS!");
+
+    DBG2(cerr << "Reading from server/protocol version: "
+         << dd->get_protocol_major() << "." << dd->get_protocol_minor()
+         << endl);
+
+    // Check for old servers.
+    if (dd->get_protocol_major() < 2) {
+        throw Error(string("The protocl version (") + dd->get_protocol()
+		    + ") indicates that this\nis an old server which may not correctly transmit Sequence variables.\nContact the server administrator.");
+    }
+
+    while (true) {
+        // Grab the sequence stream's marker.
+        unsigned char marker = read_marker(um);
+        if (is_end_of_sequence(marker))
+            break;  // EXIT the while loop here!!!
+        else if (is_start_of_instance(marker)) {
+            d_row_number++;
+            DBG2(cerr << "Reading row " << d_row_number << " of "
+                 << name() << endl);
+            BaseTypeRow *bt_row_ptr = new BaseTypeRow;
+            // Read the instance's values, building up the row
+            for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
+                BaseType *bt_ptr = (*iter)->ptr_duplicate();
+                bt_ptr->deserialize(um, dds, reuse);
+                DBG2(cerr << "Deserialized " << bt_ptr->name() << " ("
+                     << bt_ptr << ") = ");
+                DBG2(bt_ptr->print_val(stderr, ""));
+                bt_row_ptr->push_back(bt_ptr);
+            }
+            // Append this row to those accumulated.
+            d_values.push_back(bt_row_ptr);
+        }
+        else
+            throw Error("I could not read the expected Sequence data stream marker!");
+    };
+
+    return false;
+}
+
+// Return the current row number.
+
+/** Return the starting row number if the sequence was constrained using
+    row numbers (instead of, or in addition to, a relational constraint).
+    If a relational constraint was also given, the row number corresponds
+    to the row number of the sequence <i>after</i> applying the relational
+    constraint.
+
+    If the bracket notation was not used to constrain this sequence, this
+    method returns -1.
+
+    @brief Get the starting row number.
+    @return The starting row number. */
+int
+Sequence::get_starting_row_number()
+{
+    return d_starting_row_number;
+}
+
+/** Return the row stride number if the sequence was constrained using
+    row numbers (instead of, or in addition to, a relational constraint).
+    If a relational constraint was also given, the row stride is applied
+    to the sequence <i>after</i> applying the relational constraint.
+
+    If the bracket notation was not used to constrain this sequence, this
+    method returns -1.
+
+    @brief Get the row stride.
+    @return The row stride. */
+int
+Sequence::get_row_stride()
+{
+    return d_row_stride;
+}
+
+/** Return the ending row number if the sequence was constrained using
+    row numbers (instead of, or in addition to, a relational constraint).
+    If a relational constraint was also given, the row number corresponds
+    to the row number of the sequence <i>after</i> applying the
+    relational constraint.
+
+    If the bracket notation was not used to constrain this sequence, this
+    method returns -1.
+
+    @brief Get the ending row number.
+    @return The ending row number. */
+int
+Sequence::get_ending_row_number()
+{
+    return d_ending_row_number;
+}
+
+/** Set the start, stop and stride for a row-number type constraint.
+    This should be used only when the sequence is constrained using the
+    bracket notation (which supplies start, stride and stop information).
+    If omitted, the stride defaults to 1.
+
+    @param start The starting row number. The first row is row zero.
+    @param stop The eding row number. The 20th row is row 19.
+    @param stride The stride. A stride of two skips every other row. */
+void
+Sequence::set_row_number_constraint(int start, int stop, int stride)
+{
+    if (stop < start)
+        throw Error(malformed_expr, "Starting row number must precede the ending row number.");
+
+    d_starting_row_number = start;
+    d_row_stride = stride;
+    d_ending_row_number = stop;
+}
+
+/** Never use this interface for Sequence! To add data to the members of a
+    Sequence, use BaseTypeRow variables and operate on them individually. */
+unsigned int
+Sequence::val2buf(void *, bool)
+{
+    throw InternalErr(__FILE__, __LINE__, "Never use this method; see the programmer's guide documentation.");
+    return sizeof(Sequence);
+}
+
+/** Never use this interface for Sequence! Use Sequence::var_value() or
+    Sequence::row_value().
+
+    @deprecated */
+unsigned int
+Sequence::buf2val(void **)
+{
+    throw InternalErr(__FILE__, __LINE__, "Use Sequence::var_value() or Sequence::row_value() in place of Sequence::buf2val()");
+    return sizeof(Sequence);
+}
+
+#if FILE_METHODS
+void
+Sequence::print_one_row(FILE *out, int row, string space,
+                        bool print_row_num)
+{
+    if (print_row_num)
+        fprintf(out, "\n%s%d: ", space.c_str(), row) ;
+
+    fprintf(out, "{ ") ;
+
+    int elements = element_count() - 1;
+    int j;
+    BaseType *bt_ptr;
+    // Print first N-1 elements of the row.
+    for (j = 0; j < elements; ++j) {
+        bt_ptr = var_value(row, j);
+        if (bt_ptr) {  // data
+            if (bt_ptr->type() == dods_sequence_c)
+                dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
+                (out, space + "    ", false, print_row_num);
+            else
+                bt_ptr->print_val(out, space, false);
+            fprintf(out, ", ") ;
+        }
+    }
+
+    // Print Nth element; end with a `}.'
+    bt_ptr = var_value(row, j);
+    if (bt_ptr) {  // data
+        if (bt_ptr->type() == dods_sequence_c)
+            dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
+            (out, space + "    ", false, print_row_num);
+        else
+            bt_ptr->print_val(out, space, false);
+    }
+
+    fprintf(out, " }") ;
+}
+#endif
+
+void
+Sequence::print_one_row(ostream &out, int row, string space,
+                        bool print_row_num)
+{
+    if (print_row_num)
+	out << "\n" << space << row << ": " ;
+
+    out << "{ " ;
+
+    int elements = element_count();
+    int j = 0;
+    BaseType *bt_ptr = 0;
+
+    // This version of print_one_row() works for both data read with
+    // deserialize(), where each variable is assumed to have valid data, and
+    // intern_data(), where some/many variables do not. Because of that, it's
+    // not correct to assume that all of the elements will be printed, which
+    // is what the old code did.
+    // Print the first value
+    while (j < elements && !bt_ptr) {
+        bt_ptr = var_value(row, j++);
+        if (bt_ptr) {  // data
+            if (bt_ptr->type() == dods_sequence_c)
+                dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
+                     (out, space + "    ", false, print_row_num);
+            else
+                bt_ptr->print_val(out, space, false);
+        }
+    }
+
+    // Print the remaining values
+    while (j < elements) {
+        bt_ptr = var_value(row, j++);
+        if (bt_ptr) {  // data
+            out << ", ";
+            if (bt_ptr->type() == dods_sequence_c)
+                dynamic_cast<Sequence*>(bt_ptr)->print_val_by_rows
+                        (out, space + "    ", false, print_row_num);
+            else
+                bt_ptr->print_val(out, space, false);
+        }
+    }
+
+    out << " }" ;
+}
+
+#if FILE_METHODS
+void
+Sequence::print_val_by_rows(FILE *out, string space, bool print_decl_p,
+                            bool print_row_numbers)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = ") ;
+    }
+
+    fprintf(out, "{ ") ;
+
+    int rows = number_of_rows() - 1;
+    int i;
+    for (i = 0; i < rows; ++i) {
+        print_one_row(out, i, space, print_row_numbers);
+        fprintf(out, ", ") ;
+    }
+    print_one_row(out, i, space, print_row_numbers);
+
+    fprintf(out, " }") ;
+
+    if (print_decl_p)
+        fprintf(out, ";\n") ;
+}
+#endif
+
+void
+Sequence::print_val_by_rows(ostream &out, string space, bool print_decl_p,
+                            bool print_row_numbers)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " ;
+    }
+
+    out << "{ " ;
+
+    int rows = number_of_rows() - 1;
+    int i;
+    for (i = 0; i < rows; ++i) {
+        print_one_row(out, i, space, print_row_numbers);
+	out << ", " ;
+    }
+    print_one_row(out, i, space, print_row_numbers);
+
+    out << " }" ;
+
+    if (print_decl_p)
+	out << ";\n" ;
+}
+
+#if FILE_METHODS
+void
+Sequence::print_val(FILE *out, string space, bool print_decl_p)
+{
+    print_val_by_rows(out, space, print_decl_p, false);
+}
+#endif
+
+void
+Sequence::print_val(ostream &out, string space, bool print_decl_p)
+{
+    print_val_by_rows(out, space, print_decl_p, false);
+}
+
+
+bool
+Sequence::check_semantics(string &msg, bool all)
+{
+    if (!BaseType::check_semantics(msg))
+        return false;
+
+    if (!unique_names(_vars, name(), type_name(), msg))
+        return false;
+
+    if (all)
+        for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+            if (!(*i)->check_semantics(msg, true)) {
+                return false;
+            }
+        }
+
+    return true;
+}
+
+void
+Sequence::set_leaf_p(bool state)
+{
+    d_leaf_sequence = state;
+}
+
+bool
+Sequence::is_leaf_sequence()
+{
+    return d_leaf_sequence;
+}
+
+/** @brief Mark the Sequence which holds the leaf elements.
+
+    In a nested Sequence, the Sequence which holds the leaf elements is special
+    because it during the serialization of this Sequence's data that constraint
+    Expressions must be evaluated. If CEs are evaluated at the upper levels,
+    then valid data may not be sent because it was effectlively hidden from the
+    serialization and evaluation code (see the documentatin for the serialize_leaf()
+    method).
+
+    The notion of the leaf Sequence needs to be modified to mean the lowest level
+    of a Sequence where data are to be sent. Suppose there's a two level Sequence,
+    but that only fields from the top level are to be sent. Then that top level
+    is also the leaf Sequence and should be marked as such. If the lower level is
+    marked as a leaf Sequence, then no values will ever be sent since the send_p
+    property will always be false for each field and it's the call to
+    serialize_leaf() that actually triggers transmission of values (because it's
+    not until the code makes it into serialize_leaf() that it knows there are
+    values to be sent.
+
+    @note This method \e must not be called before the CE is parsed.
+
+    @param lvl The current level of the Sequence. a \e lvl of 1 indicates the
+    topmost Sequence. The default value is 1.
+    @see Sequence::serialize_leaf() */
+void
+Sequence::set_leaf_sequence(int lvl)
+{
+    bool has_child_sequence = false;
+
+    if (lvl == 1) d_top_most = true;
+
+    DBG2(cerr << "Processing sequence " << name() << endl);
+
+    for (Vars_iter iter = _vars.begin(); iter != _vars.end(); iter++) {
+        // About the test for send_p(): Only descend into a sequence if it has
+        // fields that might be sent. Thus if, in a two-level sequence, nothing
+        // in the lower level is to be sent, the upper level is marked as the
+        // leaf sequence. This ensures that values _will_ be sent (see the comment
+        // in serialize_leaf() and serialize_parent_part_one()).
+        if ((*iter)->type() == dods_sequence_c && (*iter)->send_p()) {
+            if (has_child_sequence)
+                throw Error("This implementation does not support more than one nested sequence at a level. Contact the server administrator.");
+
+            has_child_sequence = true;
+            dynamic_cast<Sequence&>(**iter).set_leaf_sequence(++lvl);
+        }
+        else if ((*iter)->type() == dods_structure_c) {
+            dynamic_cast<Structure&>(**iter).set_leaf_sequence(lvl);
+        }
+    }
+
+    if (!has_child_sequence)
+        set_leaf_p(true);
+    else
+        set_leaf_p(false);
+
+    DBG2(cerr << "is_leaf_sequence(): " << is_leaf_sequence() << " (" << name() << ")" << endl);
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Sequence::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Sequence::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    Constructor::dump(strm) ;
+    strm << DapIndent::LMarg << "# rows deserialized: " << d_row_number
+         << endl ;
+    strm << DapIndent::LMarg << "bracket notation information:" << endl ;
+    DapIndent::Indent() ;
+    strm << DapIndent::LMarg << "starting row #: " << d_starting_row_number
+         << endl ;
+    strm << DapIndent::LMarg << "row stride: " << d_row_stride << endl ;
+    strm << DapIndent::LMarg << "ending row #: " << d_ending_row_number
+         << endl ;
+    DapIndent::UnIndent() ;
+
+    strm << DapIndent::LMarg << "data been sent? " << d_unsent_data << endl ;
+    strm << DapIndent::LMarg << "start of instance? " << d_wrote_soi << endl ;
+    strm << DapIndent::LMarg << "is leaf sequence? " << d_leaf_sequence
+         << endl ;
+    strm << DapIndent::LMarg << "top most in hierarchy? " << d_top_most
+         << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Sequence.h b/Sequence.h
new file mode 100644
index 0000000..0005641
--- /dev/null
+++ b/Sequence.h
@@ -0,0 +1,355 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the class Sequence. A sequence contains a single set
+// of variables, all at the same lexical level just like a structure
+// (and like a structure, it may contain other ctor types...). Unlike
+// a structure, a sequence defines a pattern that is repeated N times
+// for a sequence of N elements. Thus, Sequence { String name; Int32
+// age; } person; means a sequence of N persons where each contain a
+// name and age. The sequence can be arbitrarily long (i.e., you don't
+// know N by looking at the sequence declaration.
+//
+// jhrg 9/14/94
+
+#ifndef _sequence_h
+#define _sequence_h 1
+
+
+#include <stack>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _constructor_h
+#include "Constructor.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+// FIXME
+#include "XDRUtils.h"
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** The type BaseTypeRow is used to store single rows of values in an
+    instance of Sequence. Values are stored in instances of BaseType. */
+typedef vector<BaseType *> BaseTypeRow;
+
+/** This type holds all of the values of a Sequence. */
+typedef vector<BaseTypeRow *> SequenceValues;
+
+/** This is the interface for the class Sequence. A sequence contains
+    a single set of variables, all at the same lexical level just like
+    a Structure.  Like a Structure, a Sequence may contain other
+    compound types, including other Sequences.  Unlike a Structure, a
+    Sequence defines a pattern that is repeated N times for a sequence
+    of N elements. It is useful to think of a Sequence as representing
+    a table of values (like a relational database), with each row of
+    the table corresponding to a Sequence ``instance.''  (This usage
+    can be confusing, since ``instance'' also refers to a particular
+    item of class Sequence.)  For example:
+
+    <pre>
+    Sequence {
+      String name;
+      Int32 age;
+    } person;
+    </pre>
+
+    This represents a Sequence of ``person'' records, each instance of
+    which contains a name and an age:
+
+    <pre>
+    Fred       34
+    Ralph      23
+    Andrea     29
+    ...
+    </pre>
+
+    A Sequence can be arbitrarily long, which is to say that its
+    length is not part of its declaration.  A Sequence can contain
+    other Sequences:
+
+    <pre>
+    Sequence {
+      String name;
+      Int32 age;
+      Sequence {
+        String friend;
+      } friend_list;
+    } person;
+    </pre>
+
+    This is still represented as a single table, but each row contains
+    the elements of both the main Sequence and the nested one:
+
+    <pre>
+    Fred       34     Norman
+    Fred       34     Andrea
+    Fred       34     Ralph
+    Fred       34     Lisa
+    Ralph      23     Norman
+    Ralph      23     Andrea
+    Ralph      23     Lisa
+    Ralph      23     Marth
+    Ralph      23     Throckmorton
+    Ralph      23     Helga
+    Ralph      23     Millicent
+    Andrea     29     Ralph
+    Andrea     29     Natasha
+    Andrea     29     Norman
+    ...        ..     ...
+    </pre>
+
+    Internally, the Sequence is represented by a vector of vectors. The
+    members of the outer vector are the members of the Sequence. This
+    includes the nested Sequences, as in the above example.
+
+    NB: Note that in the past this class had a different behavior. It held
+    only one row at a time and the deserialize(...) method had to be called
+    from within a loop. This is <i>no longer true</i>. Now the
+    deserailize(...) method should be called once and will read the entire
+    sequence's values from the server. All the values are now stored in an
+    instance of Sequence, not just a single row's.
+
+    Because the length of a Sequence is indeterminate, there are
+    changes to the behavior of the functions to read this class of
+    data.  The <tt>read()</tt> function for Sequence must be written so that
+    successive calls return values for successive rows of the Sequence.
+
+    Similar to a C structure, you refer to members of Sequence
+    elements with a ``.'' notation.  For example, if the Sequence has
+    a member Sequence called ``Tom'' and Tom has a member Float32
+    called ``shoe_size'', you can refer to Tom's shoe size as
+    ``Tom.shoe_size''.
+
+    @note This class contains the 'logic' for both the server- and client-side
+    behavior. The field \e d_values is used by the client-side methods to store
+    the entire Sequence. On the server-side, the read() method uses an underlying
+    data system to read one row of data values which are then serialized using the
+    serialize() methods of each variable.
+
+    @todo Refactor along with Structure moving methods up into Constructor.
+
+    @todo Add an isEmpty() method which returns true if the Sequence is
+    empty. This should work before and after calling deserialize().
+
+    @brief Holds a sequence. */
+
+class Sequence: public Constructor
+{
+private:
+    // This holds the values read off the wire. Values are stored in
+    // instances of BaseTypeRow objects which hold instances of BaseType.
+    SequenceValues d_values;
+
+    // The number of the row that has just been deserialized. Before
+    // deserialized has been called, this field is -1.
+    int d_row_number;
+
+    // If a client asks for certain rows of a sequence using the bracket
+    // notation (<tt>[<start>:<stride>:<stop>]</tt>) primarily intended for
+    // arrays
+    // and grids, record that information in the next three fields. This
+    // information can be used by the translation software. s.a. the accessor
+    // and mutator methods for these members. Values of -1 indicate that
+    // these have not yet been set.
+    int d_starting_row_number;
+    int d_row_stride;
+    int d_ending_row_number;
+
+    // Used to track if data has not already been sent.
+    bool d_unsent_data;
+
+    // Track if the Start Of Instance marker has been written. Needed to
+    // properly send EOS for only the outer Sequence when a selection
+    // returns an empty Sequence.
+    bool d_wrote_soi;
+
+    // This signals whether the sequence is a leaf or parent.
+    bool d_leaf_sequence;
+
+    // In a hierarchy of sequences, is this the top most?
+    bool d_top_most;
+
+    void _duplicate(const Sequence &s);
+    BaseType *m_leaf_match(const string &name, btp_stack *s = 0);
+    BaseType *m_exact_match(const string &name, btp_stack *s = 0);
+
+    bool is_end_of_rows(int i);
+
+    friend class SequenceTest;
+
+protected:
+
+    typedef stack<SequenceValues*> sequence_values_stack_t;
+
+    virtual bool serialize_parent_part_one(DDS &dds,
+                                           ConstraintEvaluator &eval,
+					   Marshaller &m);
+    virtual void serialize_parent_part_two(DDS &dds,
+                                           ConstraintEvaluator &eval,
+					   Marshaller &m);
+    virtual bool serialize_leaf(DDS &dds,
+                                ConstraintEvaluator &eval,
+				Marshaller &m, bool ce_eval);
+
+    virtual void intern_data_private( ConstraintEvaluator &eval,
+                                      DDS &dds,
+                                      sequence_values_stack_t &sequence_values_stack);
+    virtual void intern_data_for_leaf(DDS &dds,
+                                      ConstraintEvaluator &eval,
+                                      sequence_values_stack_t &sequence_values_stack);
+
+    virtual void intern_data_parent_part_one(DDS &dds,
+            ConstraintEvaluator &eval,
+            sequence_values_stack_t &sequence_values_stack);
+
+    virtual void intern_data_parent_part_two(DDS &dds,
+            ConstraintEvaluator &eval,
+            sequence_values_stack_t &sequence_values_stack);
+
+public:
+
+    Sequence(const string &n);
+    Sequence(const string &n, const string &d);
+
+    Sequence(const Sequence &rhs);
+
+    virtual ~Sequence();
+
+    Sequence &operator=(const Sequence &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual string toString();
+
+    virtual int element_count(bool leaves = false);
+
+    virtual bool is_linear();
+
+    virtual void set_send_p(bool state);
+    virtual void set_read_p(bool state);
+    virtual void set_in_selection(bool state);
+
+    virtual unsigned int width();
+
+    virtual int length();
+
+    virtual int number_of_rows();
+
+    virtual bool read_row(int row, DDS &dds,
+                          ConstraintEvaluator &eval, bool ce_eval = true);
+
+    virtual void intern_data(ConstraintEvaluator &eval, DDS &dds);
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    /// Rest the row number counter
+    void reset_row_number();
+
+    int get_starting_row_number();
+
+    virtual int get_row_stride();
+
+    virtual int get_ending_row_number();
+
+    virtual void set_row_number_constraint(int start, int stop, int stride = 1);
+
+    /// Get the unsent data property
+    bool get_unsent_data()
+    {
+        return d_unsent_data;
+    }
+
+    /// Set the unsent data property
+    void set_unsent_data(bool usd)
+    {
+        d_unsent_data = usd;
+    }
+
+    // Move me!
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual void set_value(SequenceValues &values);
+    virtual SequenceValues value();
+
+    virtual BaseType *var(const string &name, bool exact_match = true,
+                          btp_stack *s = 0);
+    virtual BaseType *var(const string &n, btp_stack &s);
+
+    virtual BaseType *var_value(size_t row, const string &name);
+
+    virtual BaseType *var_value(size_t row, size_t i);
+
+    virtual BaseTypeRow *row_value(size_t row);
+
+    virtual void add_var(BaseType *, Part part = nil);
+    virtual void print_one_row(ostream &out, int row, string space,
+                               bool print_row_num = false);
+    virtual void print_val_by_rows(ostream &out, string space = "",
+                                   bool print_decl_p = true,
+                                   bool print_row_numbers = true);
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+#if FILE_METHODS
+    virtual void print_one_row(FILE *out, int row, string space,
+                               bool print_row_num = false);
+    virtual void print_val_by_rows(FILE *out, string space = "",
+                                   bool print_decl_p = true,
+                                   bool print_row_numbers = true);
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+
+    virtual bool check_semantics(string &msg, bool all = false);
+
+    virtual void set_leaf_p(bool state);
+
+    virtual bool is_leaf_sequence();
+
+    virtual void set_leaf_sequence(int lvl = 1);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif //_sequence_h
diff --git a/SignalHandler.cc b/SignalHandler.cc
new file mode 100644
index 0000000..5f8ad54
--- /dev/null
+++ b/SignalHandler.cc
@@ -0,0 +1,227 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-2002
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    { "$Id: SignalHandler.cc 22703 2010-05-11 18:10:01Z jimg $"
+    };
+
+#include <cstdlib>
+
+#include <signal.h>
+#include <pthread.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h> //for _exit
+#endif
+
+#include "SignalHandler.h"
+#include "util.h"
+
+namespace libdap {
+
+EventHandler *SignalHandler::d_signal_handlers[NSIG];
+Sigfunc *SignalHandler::d_old_handlers[NSIG];
+SignalHandler *SignalHandler::d_instance = 0;
+
+// instance_control is used to ensure that in a MT environment d_instance is
+// correctly initialized.
+static pthread_once_t instance_control = PTHREAD_ONCE_INIT;
+
+/// Private static void method.
+void
+SignalHandler::initialize_instance()
+{
+    // MT-Safe if called via pthread_once or similar
+    SignalHandler::d_instance = new SignalHandler;
+    atexit(SignalHandler::delete_instance);
+}
+
+/// Private static void method.
+void
+SignalHandler::delete_instance()
+{
+    if (SignalHandler::d_instance) {
+        for (int i = 0; i < NSIG; ++i) {
+        	// Fortify warns about a leak because the EventHandler objects
+        	// are not deleted, but that's OK - this is a singleton and
+        	// so the 'leak' is really just a constant amount of memory that
+        	// gets used.
+        	d_signal_handlers[i] = 0;
+            d_old_handlers[i] = 0;
+        }
+
+        delete SignalHandler::d_instance;
+        SignalHandler::d_instance = 0;
+    }
+}
+
+/** This private method is the adapter between the C-style interface of the
+    signal sub-system and C++'s method interface. This uses the lookup table
+    to find an instance of EventHandler and calls that instance's
+    handle_signal method.
+
+    @param signum The number of the signal. */
+void
+SignalHandler::dispatcher(int signum)
+{
+    // Perform a sanity check...
+    if (SignalHandler::d_signal_handlers[signum] != 0)
+        // Dispatch the handler's hook method.
+        SignalHandler::d_signal_handlers[signum]->handle_signal(signum);
+
+    Sigfunc *old_handler = SignalHandler::d_old_handlers[signum];
+    if (old_handler == SIG_IGN || old_handler == SIG_ERR)
+        return;
+    else if (old_handler == SIG_DFL) {
+        switch (signum) {
+#ifndef WIN32
+        case SIGHUP:
+        case SIGKILL:
+        case SIGUSR1:
+        case SIGUSR2:
+        case SIGPIPE:
+        case SIGALRM:
+#endif
+        case SIGINT:
+        case SIGTERM: _exit(EXIT_FAILURE);
+
+            // register_handler() should never allow any fiddling with
+            // signals other than those listed above.
+        default: abort();
+        }
+    }
+    else
+        old_handler(signum);
+}
+
+/** Get a pointer to the single instance of SignalHandler. */
+SignalHandler*
+SignalHandler::instance()
+{
+    pthread_once(&instance_control, initialize_instance);
+
+    return d_instance;
+}
+
+/** Register an event handler. By default run any previously registered
+    action/handler such as those installed using \c sigaction(). For signals
+    such as SIGALRM (the alarm signal) this may not be what you want; see the
+    \e override parameter. See also the class description.
+
+    @param signum Bind the event handler to this signal number. Limited to
+    those signals that, according to POSIX.1, cause process termination.
+    @param eh A pointer to the EventHandler for \c signum.
+    @param override If \c true, do not run the default handler/action.
+    Instead run \e eh and then treat the signal as if the original action was
+    SIG_IGN. Default is false.
+    @return A pointer to the old EventHandler or null. */
+EventHandler *
+SignalHandler::register_handler(int signum, EventHandler *eh, bool override)
+{
+    // Check first for improper use.
+    switch (signum) {
+#ifndef WIN32
+    case SIGHUP:
+    case SIGKILL:
+    case SIGUSR1:
+    case SIGUSR2:
+    case SIGPIPE:
+    case SIGALRM:
+#endif
+    case SIGINT:
+    case SIGTERM: break;
+
+    default: throw InternalErr(__FILE__, __LINE__,
+                                   string("Call to register_handler with unsupported signal (")
+                                   + long_to_string(signum) + string(")."));
+    }
+
+    // Save the old EventHandler
+    EventHandler *old_eh = SignalHandler::d_signal_handlers[signum];
+
+    SignalHandler::d_signal_handlers[signum] = eh;
+
+    // Register the dispatcher to handle this signal. See Stevens, Advanced
+    // Programming in the UNIX Environment, p.298.
+#ifndef WIN32
+    struct sigaction sa;
+    sa.sa_handler = dispatcher;
+    sigemptyset(&sa.sa_mask);
+    sa.sa_flags = 0;
+
+    // Try to suppress restarting system calls if we're handling an alarm.
+    // This lets alarms block I/O calls that would normally restart. 07/18/03
+    // jhrg
+    if (signum == SIGALRM) {
+#ifdef SA_INTERUPT
+        sa.sa_flags |= SA_INTERUPT;
+#endif
+    }
+    else {
+#ifdef SA_RESTART
+        sa.sa_flags |= SA_RESTART;
+#endif
+    }
+
+    struct sigaction osa; // extract the old handler/action
+
+    if (sigaction(signum, &sa, &osa) < 0)
+        throw InternalErr(__FILE__, __LINE__, "Could not register a signal handler.");
+
+    // Take care of the case where this interface is used to register a
+    // handler more than once. We want to make sure that the dispatcher is
+    // not installed as the 'old handler' because that results in an infinite
+    // loop. 02/10/04 jhrg
+    if (override)
+        SignalHandler::d_old_handlers[signum] = SIG_IGN;
+    else if (osa.sa_handler != dispatcher)
+        SignalHandler::d_old_handlers[signum] = osa.sa_handler;
+#endif
+
+    return old_eh;
+}
+
+/** Remove the event hander.
+    @param signum The signal number of the handler to remove.
+    @return The old event handler */
+EventHandler *
+SignalHandler::remove_handler(int signum)
+{
+    EventHandler *old_eh = SignalHandler::d_signal_handlers[signum];
+
+    SignalHandler::d_signal_handlers[signum] = 0;
+
+    return old_eh;
+}
+
+} // namespace libdap
diff --git a/SignalHandler.h b/SignalHandler.h
new file mode 100644
index 0000000..ef13015
--- /dev/null
+++ b/SignalHandler.h
@@ -0,0 +1,118 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef signal_handler_h
+#define signal_handler_h
+
+#include <signal.h>
+
+#include "EventHandler.h"
+#include "InternalErr.h"
+
+namespace libdap
+{
+
+typedef void Sigfunc(int); // Plauger, 1992
+
+/** Singleton to handle signals. This class adapts the C-style function call
+    interface to one suited for C++. This class records a signal's old
+    action/handler when it installs new handler. When a signal is caught, the
+    new handler (registered with this class) is run and then the old
+    action/handler is performed. This ensures that when libdap++ is embedded
+    in code which has a handler for a signal such as SIGINT which does
+    something other than the default, that thing, whatever it may be, gets
+    done.
+
+    This class treats signals it registers (using the EventHandler abstract
+    class) differently than ones registered using the \c signal() or \c
+    sigaction() system interfaces. If the register_handler() method is called
+    and an instance of EventHandler is already bound to \e signum, then the
+    old EventHandler is returned. However, if there's an existing handler
+    that was set up with \c sigaction(), ..., it won't be returned. Instead
+    it will either be run after the newly registered EventHandler or ignored,
+    depending on register_handler()'s \e override parameter. This feature may
+    be used only for POSIX.1 signals which cause process termination. They
+    are: SIGHUP, SIGINT, SIGKILL, SIGPIPE, SIGALRM, SIGTERM, SIGUSR1, and
+    SIGUSR2.
+
+    @note Based on "Applying Design Patterns to Simplify Signal Handling",
+    Douglas C. Schmidt, 1998,
+    http://www.cs.wustl.edu/~schmidt/signal-patterns.html.
+
+    @see EventHandler
+    @author James Gallagher <jgallagher at opendap.org> */
+class SignalHandler
+{
+private:
+    // Ensure we're a Singleton.
+    SignalHandler()
+    {}
+
+    // Singleton pointer.
+    static SignalHandler *d_instance;
+
+    // Table of pointers to instances of EventHandlers. Since EventHandler is
+    // abstract, the pointers will actually reference instances that are
+    // children of EventHandler. NSIG is defined in signal.h but this may be
+    // a portability issue.
+    static EventHandler *d_signal_handlers[NSIG];
+
+    // This array holds the old signal handlers. Once the handler in
+    // d_signal_handler[signum] is run, look here to see what the original
+    // action was. This is important since libdap++ is often embedded in code
+    // that already has a non-default signal handler for things like SIGINT.
+    static Sigfunc *d_old_handlers[NSIG];
+
+    // Entry point adapter installed into sigaction(). This must be static
+    // method (or a regular C-function) to conform to sigaction's interface.
+    // this is the part of SignalHandler that uses the Adapter pattern.
+    static void dispatcher(int signum);
+
+    // Delete the global instance. Call this with atexit().
+    static void delete_instance();
+
+    // Call this using pthread_once() to ensure there's only one instance
+    // when running in a MT world.
+    static void initialize_instance();
+
+    friend class SignalHandlerTest;
+    friend class HTTPCacheTest;
+
+public:
+    static SignalHandler *instance();
+
+    ///
+    virtual ~SignalHandler()
+    {}
+
+    EventHandler *register_handler(int signum, EventHandler *eh,
+                                   bool override = false);
+
+    EventHandler *remove_handler(int signum);
+};
+
+} // namespace libdap
+
+#endif // signal_handler_h
diff --git a/SignalHandlerRegisteredErr.h b/SignalHandlerRegisteredErr.h
new file mode 100644
index 0000000..5a6b8fb
--- /dev/null
+++ b/SignalHandlerRegisteredErr.h
@@ -0,0 +1,63 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2004 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _signal_handler_registered_err_h
+#define _signal_handler_registered_err_h 1
+
+#include <string>
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+namespace libdap
+{
+
+/** SignalHandlerRegisteredErr is thrown by HTTPCache::instance() if a signal
+    handler is already registered.
+
+    @author jhrg */
+
+class SignalHandlerRegisteredErr: public Error
+{
+
+public:
+    SignalHandlerRegisteredErr(const string &msg) : Error()
+    {
+        _error_code = unknown_error;
+        _error_message = "";
+        _error_message += "A caching error was encountered:\n";
+        _error_message += msg + "\n";
+    }
+
+    SignalHandlerRegisteredErr() : Error()
+    {
+        _error_code = unknown_error;
+    }
+};
+
+} // namespace libdap
+
+#endif // _signal_handler_registered_err_h
diff --git a/StdinResponse.h b/StdinResponse.h
new file mode 100644
index 0000000..333f0ff
--- /dev/null
+++ b/StdinResponse.h
@@ -0,0 +1,86 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef stdin_response_h
+#define stdin_response_h
+
+#include <cstdio>
+
+#ifndef response_h
+#include "Response.h"
+#endif
+
+#ifndef _debug_h
+#include "debug.h"
+#endif
+
+using namespace std;
+
+namespace libdap
+{
+
+/** @brief Encapsulate a response read from stdin.
+
+    This class holds stdin and provides an interface from which
+    Connect can read DAP2 information from standard input. Unlike the
+    other Response classes, StdinResponse does \e not close the input
+    stream when it's done reading. */
+class StdinResponse: public Response
+{
+private:
+    FILE *d_stdin;
+
+protected:
+
+public:
+    /** @brief Initialize with standard input.
+      
+        Create an instance initialized to standard input. When done, does
+        not close stdin.
+        
+        @see Response
+        
+        @param s Pointer to standard input.
+        */
+    StdinResponse(FILE *s) : Response(0), d_stdin(s)
+    {}
+
+    /** Destructor. Does not close standard input. */
+    virtual ~StdinResponse()
+    {}
+
+    virtual FILE *get_stream() const
+    {
+        return d_stdin;
+    }
+    virtual void set_stream(FILE *s)
+    {
+        d_stdin = s;
+    }
+};
+
+} // namespace libdap
+
+#endif // pipe_response_h
diff --git a/Str.cc b/Str.cc
new file mode 100644
index 0000000..d93507b
--- /dev/null
+++ b/Str.cc
@@ -0,0 +1,319 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Str.
+//
+// jhrg 9/7/94
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: Str.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "InternalErr.h"
+#include "escaping.h"
+#include "debug.h"
+
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The Str constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+
+*/
+Str::Str(const string &n) : BaseType(n, dods_str_c), _buf("")
+{}
+
+/** The Str server-side constructor accepts the name of the variable and the
+    dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+Str::Str(const string &n, const string &d)
+    : BaseType(n, d, dods_str_c), _buf("")
+{}
+
+Str::Str(const Str &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+Str::ptr_duplicate()
+{
+    return new Str(*this);
+}
+
+Str &
+Str::operator=(const Str &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    // Call BaseType::operator=.
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+Str::length()
+{
+    return _buf.length();
+}
+
+unsigned int
+Str::width()
+{
+    return sizeof(string);
+}
+
+bool
+Str::serialize(ConstraintEvaluator &eval, DDS &dds,
+               Marshaller &m, bool ce_eval)
+{
+
+    DBG(cerr << "Entering (" << this->name() << " [" << this << "])" << endl);
+
+    dds.timeout_on();
+
+    if (!read_p())
+        read();
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_str( _buf ) ;
+
+    DBG(cerr << "Exiting: buf = " << _buf << endl);
+
+    return true;
+}
+
+// deserialize the string on stdin and put the result in BUF.
+
+bool
+Str::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_str( _buf ) ;
+
+    return false;
+}
+
+/** Read the object's value and put a copy in the C++ string object
+    referenced by \e **val. If \e *val is null, this method will allocate
+    a string object using new and store the result there. If \e *val
+    is not null, it will assume that \e *val references a string object
+    and put the value there.
+
+    @param val A pointer to null or to a string object.
+    @return The sizeof(string*)
+    @exception InternalErr Thrown if \e val is null. */
+unsigned int
+Str::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "No place to store a reference to the data.");
+    // If *val is null, then the caller has not allocated storage for the
+    // value; we must. If there is storage there, assume it is a string and
+    // assign _buf's value to that storage.
+    if (!*val)
+        *val = new string(_buf);
+    else
+        *static_cast<string*>(*val) = _buf;
+
+    return sizeof(string*);
+}
+
+/** Store the value referenced by \e val in this object. Even though the
+    type of \e val is \c void*, this method assumes the type is \c string*.
+    Note that the value is copied so the caller if free to throw away/reuse
+    the actual parameter once this call has returned.
+
+    @param val A pointer to a C++ string object.
+    @param reuse Not used by this version of the method.
+    @exception IntenalErr if \e val is null.
+    @return The width of the pointer. */
+unsigned int
+Str::val2buf(void *val, bool)
+{
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogated library,
+    // thus if the pointer val is NULL, is an Internal Error.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    _buf = *static_cast<string*>(val);
+
+    return sizeof(string*);
+}
+
+/** Set the value of this instance.
+    @param value The value
+    @return Always returns true; the return type of bool is for compatibility
+    with the Passive* subclasses written by HAO. */
+bool
+Str::set_value(const string &value)
+{
+    _buf = value;
+    set_read_p(true);
+
+    return true;
+}
+
+/** Get the value of this instance.
+    @return The value. */
+string
+Str::value() const
+{
+    return _buf;
+}
+
+#if FILE_METHODS
+void
+Str::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = \"%s\";\n", escattr(_buf).c_str()) ;
+    }
+    else
+        fprintf(out, "\"%s\"", escattr(_buf).c_str()) ;
+}
+#endif
+
+void
+Str::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = \"" << escattr(_buf) << "\";\n" ;
+    }
+    else
+	out << "\"" << escattr(_buf) << "\"" ;
+}
+
+bool
+Str::ops(BaseType *b, int op)
+{
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value was not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b || !(b->read_p() || b->read())) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "Argument value was not read!");
+    }
+
+    switch (b->type()) {
+    case dods_str_c:
+        return rops<string, string, StrCmp<string, string> >
+               (_buf, dynamic_cast<Str *>(b)->_buf, op);
+    case dods_url_c:
+        return rops<string, string, StrCmp<string, string> >
+               (_buf, dynamic_cast<Url *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Str::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Str::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Str.h b/Str.h
new file mode 100644
index 0000000..1479e41
--- /dev/null
+++ b/Str.h
@@ -0,0 +1,113 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Str type.
+//
+// jhrg 9/7/94
+
+#ifndef _str_h
+#define _str_h 1
+
+#include <string>
+
+#include "dods-limits.h"
+#include "BaseType.h"
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+// max_str_len should be large since we always send strings with length bytes
+// as a prefix (so xdr_string will always know how much memory to malloc) but
+// if deserialize gets confused and thinks a ctor (in particular) is a string
+// xdr_string in turn will max_str_len if it cannot get a length byte. A long
+// term solution is to fix libdap, but strings should not routinely be > 32k
+// for the time being... jhrg 4/30/97
+
+const unsigned int max_str_len = DODS_USHRT_MAX - 1;
+
+/** @brief Holds character string data.
+
+    @see BaseType
+    @see Url
+    */
+
+class Str: public BaseType
+{
+
+protected:
+    string _buf;
+
+public:
+    Str(const string &n);
+    Str(const string &n, const string &d);
+
+    virtual ~Str()
+    {}
+
+    Str(const Str &copy_from);
+
+    Str &operator=(const Str &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual unsigned int width();
+
+    // Return the length of the stored string or zero if no string has been
+    // stored in the instance's internal buffer.
+    unsigned int length();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual bool set_value(const string &value);
+    virtual string value() const;
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _str_h
+
diff --git a/Structure.cc b/Structure.cc
new file mode 100644
index 0000000..02bd9d1
--- /dev/null
+++ b/Structure.cc
@@ -0,0 +1,535 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the class Structure
+//
+// jhrg 9/14/94
+
+//#define DODS_DEBUG
+
+#include "config.h"
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "util.h"
+#include "debug.h"
+#include "InternalErr.h"
+#include "escaping.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+void
+Structure::_duplicate(const Structure &s)
+{
+    Structure &cs = const_cast<Structure &>(s);
+
+    DBG(cerr << "Copying structure: " << name() << endl);
+
+    for (Vars_iter i = cs._vars.begin(); i != cs._vars.end(); i++) {
+        DBG(cerr << "Copying field: " << (*i)->name() << endl);
+        // Jose Garcia
+        // I think this assert here is part of a debugging
+        // process since it is going along with a DBG call
+        // I leave it here since it can be remove by defining NDEBUG.
+        // assert(*i);
+        BaseType *btp = (*i)->ptr_duplicate();
+        btp->set_parent(this);
+        _vars.push_back(btp);
+    }
+}
+
+/** The Structure constructor requires only the name of the variable
+    to be created. The name may be omitted, which will create a
+    nameless variable. This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+*/
+Structure::Structure(const string &n) : Constructor(n, dods_structure_c)
+{}
+
+/** The Structure server-side constructor requires the name of the variable
+    to be created and the dataset name from which this variable is being
+    created. Used on server-side handlers.
+
+    @param n A string containing the name of the variable to be
+    created.
+    @param d A string containing the name of the dataset from which this
+    variable is being created.
+*/
+Structure::Structure(const string &n, const string &d)
+    : Constructor(n, d, dods_structure_c)
+{}
+
+/** The Structure copy constructor. */
+Structure::Structure(const Structure &rhs) : Constructor(rhs)
+{
+    _duplicate(rhs);
+}
+
+Structure::~Structure()
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        BaseType *btp = *i ;
+        delete btp ;  btp = 0;
+    }
+}
+
+BaseType *
+Structure::ptr_duplicate()
+{
+    return new Structure(*this);
+}
+
+Structure &
+Structure::operator=(const Structure &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<Constructor &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+int
+Structure::element_count(bool leaves)
+{
+    if (!leaves)
+        return _vars.size();
+    else {
+        int i = 0;
+        for (Vars_iter j = _vars.begin(); j != _vars.end(); j++) {
+            j += (*j)->element_count(leaves);
+        }
+        return i;
+    }
+}
+
+bool
+Structure::is_linear()
+{
+    bool linear = true;
+    for (Vars_iter i = _vars.begin(); linear && i != _vars.end(); i++) {
+        if ((*i)->type() == dods_structure_c)
+            linear = linear && dynamic_cast<Structure*>((*i))->is_linear();
+        else
+            linear = linear && (*i)->is_simple_type();
+    }
+
+    return linear;
+}
+
+void
+Structure::set_send_p(bool state)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->set_send_p(state);
+    }
+
+    BaseType::set_send_p(state);
+}
+
+void
+Structure::set_read_p(bool state)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->set_read_p(state);
+    }
+
+    BaseType::set_read_p(state);
+}
+
+/** Set the \e in_selection property for this variable and all of its
+    children.
+
+    @brief Set the \e in_selection property.
+    @param state Set the property value to \e state. */
+void
+Structure::set_in_selection(bool state)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->set_in_selection(state);
+    }
+
+    BaseType::set_in_selection(state);
+}
+
+/** @brief Traverse Structure, set Sequence leaf nodes. */
+void
+Structure::set_leaf_sequence(int level)
+{
+    for (Vars_iter i = var_begin(); i != var_end(); i++) {
+        if ((*i)->type() == dods_sequence_c)
+            dynamic_cast<Sequence&>(**i).set_leaf_sequence(++level);
+        else if ((*i)->type() == dods_structure_c)
+            dynamic_cast<Structure&>(**i).set_leaf_sequence(level);
+    }
+}
+
+/** Adds an element to a Structure.
+
+    @param bt A pointer to the DAP2 type variable to add to this Structure.
+    @param part Not used by this class, defaults to nil */
+void
+Structure::add_var(BaseType *bt, Part)
+{
+    // Jose Garcia
+    // Passing and invalid pointer to an object is a developer's error.
+    if (!bt)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The BaseType parameter cannot be null.");
+
+    // Jose Garcia
+    // Now we add a copy of bt so the external user is able to destroy bt as
+    // he/she wishes. The policy is: "If it is allocated outside, it is
+    // deallocated outside, if it is allocated inside, it is deallocated
+    // inside"
+    BaseType *btp = bt->ptr_duplicate();
+    btp->set_parent(this);
+    _vars.push_back(btp);
+}
+
+/** Removed an element from a Structure.
+
+    @param n name of the variable to remove */
+void
+Structure::del_var(const string &n)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        if ((*i)->name() == n) {
+            BaseType *bt = *i ;
+            _vars.erase(i) ;
+            delete bt ; bt = 0;
+            return;
+        }
+    }
+}
+
+/** @brief simple implementation of reat that iterates through vars
+ *  and calls read on them
+ *
+ * @return returns false to signify all has been read
+ */
+bool
+Structure::read()
+{
+    if( !read_p() )
+    {
+	for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+	    (*i)->read() ;
+	}
+	set_read_p(true) ;
+    }
+
+    return false ;
+}
+
+unsigned int
+Structure::width()
+{
+    unsigned int sz = 0;
+
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        sz += (*i)->width();
+    }
+
+    return sz;
+}
+
+void
+Structure::intern_data(ConstraintEvaluator & eval, DDS & dds)
+{
+    DBG(cerr << "Structure::intern_data: " << name() << endl);
+    if (!read_p())
+        read();          // read() throws Error and InternalErr
+
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        if ((*i)->send_p()) {
+            (*i)->intern_data(eval, dds);
+        }
+    }
+}
+
+bool
+Structure::serialize(ConstraintEvaluator &eval, DDS &dds,
+                     Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        if ((*i)->send_p()) {
+            (*i)->serialize(eval, dds, m, false);
+        }
+    }
+
+    return true;
+}
+
+bool
+Structure::deserialize(UnMarshaller &um, DDS *dds, bool reuse)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        (*i)->deserialize(um, dds, reuse);
+    }
+
+    return false;
+}
+
+/**  @brief Never call this
+
+     This method cannot be used to change values of a Structure since
+     the values of a Constructor type must be set using methods in
+     Constructor. See the Constructor::var_begin() and related
+     methods.
+
+     @todo Make this throw an exception
+     @return Returns the size of the structure. */
+unsigned int
+Structure::val2buf(void *, bool)
+{
+    return sizeof(Structure);
+}
+
+/** @brief Never call this
+    @see val2buf()
+    @return Returns the size of the structure. */
+unsigned int
+Structure::buf2val(void **)
+{
+    return sizeof(Structure);
+}
+
+BaseType *
+Structure::var(const string &name, bool exact_match, btp_stack *s)
+{
+    string n = www2id(name);
+
+    if (exact_match)
+        return m_exact_match(n, s);
+    else
+        return m_leaf_match(n, s);
+}
+
+/** @deprecated See comment in BaseType */
+BaseType *
+Structure::var(const string &n, btp_stack &s)
+{
+    string name = www2id(n);
+
+    BaseType *btp = m_exact_match(name, &s);
+    if (btp)
+        return btp;
+
+    return m_leaf_match(name, &s);
+}
+
+// Private method to find a variable using the shorthand name. This
+// should be moved to Constructor.
+BaseType *
+Structure::m_leaf_match(const string &name, btp_stack *s)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        if ((*i)->name() == name) {
+            if (s) {
+                DBG(cerr << "Pushing " << this->name() << endl);
+                s->push(static_cast<BaseType *>(this));
+            }
+            return *i;
+        }
+        if ((*i)->is_constructor_type()) {
+            BaseType *btp = (*i)->var(name, false, s);
+            if (btp) {
+                if (s) {
+                    DBG(cerr << "Pushing " << this->name() << endl);
+                    s->push(static_cast<BaseType *>(this));
+                }
+                return btp;
+            }
+        }
+    }
+
+    return 0;
+}
+
+// Breadth-first search for NAME. If NAME contains one or more dots (.)
+BaseType *
+Structure::m_exact_match(const string &name, btp_stack *s)
+{
+    for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+        DBG(cerr << "Looking at " << (*i)->name() << " in: " << *i
+            << endl);
+        if ((*i)->name() == name) {
+            DBG(cerr << "Found " << (*i)->name() << " in: "
+                << *i << endl);
+            if (s) {
+                DBG(cerr << "Pushing " << this->name() << endl);
+                s->push(static_cast<BaseType *>(this));
+            }
+            return *i;
+        }
+    }
+
+    string::size_type dot_pos = name.find("."); // zero-based index of `.'
+    if (dot_pos != string::npos) {
+        string aggregate = name.substr(0, dot_pos);
+        string field = name.substr(dot_pos + 1);
+
+        BaseType *agg_ptr = var(aggregate);
+        if (agg_ptr) {
+            DBG(cerr << "Descending into " << agg_ptr->name() << endl);
+            if (s) {
+                DBG(cerr << "Pushing " << this->name() << endl);
+                s->push(static_cast<BaseType *>(this));
+            }
+            return agg_ptr->var(field, true, s); // recurse
+        }
+        else
+            return 0;  // qualified names must be *fully* qualified
+    }
+
+    return 0;
+}
+
+#if FILE_METHODS
+void
+Structure::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = ") ;
+    }
+
+    fprintf(out, "{ ") ;
+    for (Vars_citer i = _vars.begin(); i != _vars.end();
+         i++, (void)(i != _vars.end() && fprintf(out, ", "))) {
+        (*i)->print_val(out, "", false);
+    }
+
+    fprintf(out, " }") ;
+
+    if (print_decl_p)
+        fprintf(out, ";\n") ;
+}
+#endif
+
+void
+Structure::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " ;
+    }
+
+    out << "{ " ;
+    for (Vars_citer i = _vars.begin(); i != _vars.end();
+         i++, (void)(i != _vars.end() && out << ", ")) {
+        (*i)->print_val(out, "", false);
+    }
+
+    out << " }" ;
+
+    if (print_decl_p)
+	out << ";\n" ;
+}
+
+bool
+Structure::check_semantics(string &msg, bool all)
+{
+    if (!BaseType::check_semantics(msg))
+        return false;
+
+    bool status = true;
+
+    if (!unique_names(_vars, name(), type_name(), msg))
+        return false;
+
+    if (all) {
+        for (Vars_iter i = _vars.begin(); i != _vars.end(); i++) {
+            //assert(*i);
+            if (!(*i)->check_semantics(msg, true)) {
+                status = false;
+                goto exit;
+            }
+        }
+    }
+
+exit:
+    return status;
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Structure::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Structure::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    Constructor::dump(strm) ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Structure.h b/Structure.h
new file mode 100644
index 0000000..89b72b9
--- /dev/null
+++ b/Structure.h
@@ -0,0 +1,163 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the class Structure. A structure contains a single set of
+// variables, all at the same lexical level. Of course, a structure may
+// contain other structures... The variables contained in a structure are
+// stored by instances of this class in a SLList of BaseType pointers.
+//
+// jhrg 9/14/94
+
+#ifndef _structure_h
+#define _structure_h 1
+
+#ifndef __POWERPC__
+#endif
+
+#include <vector>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _constructor_h
+#include "Constructor.h"
+#endif
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** This data type is used to hold a collection of related data types,
+    in a manner roughly corresponding to a C structure.  The member
+    types can be simple or compound types, and can include other
+    Structures.
+
+    The DAP2 structure is defined as a singly-linked list.  This means
+    that Structure elements can be accessed either by name, with the
+    <tt>var()</tt> function, or by their position in the list, either with
+    the overloaded version of <tt>var()</tt>, or the combination of the
+    <tt>first_var()</tt> and <tt>next_var()</tt> functions.
+
+    The <tt>val2buf()</tt> and <tt>buf2val()</tt> functions only
+    return the size of
+    the structure.  To read parts of a DAP2 Structure into an
+    application program, use the <tt>buf2val()</tt> function of the element
+    of the Structure in question.
+
+    Note that the predicate-setting functions <tt>set_send_p()</tt> and
+    <tt>set_read_p()</tt> set their flags for the Structure as well as for
+    each of the Structure's member elements.
+
+    Similar to C, you can refer to members of Structure elements
+    with a ``.'' notation.  For example, if the Structure has a member
+    Structure called ``Tom'' and Tom has a member Float32 called
+    ``shoe_size'', then you can refer to Tom's shoe size as
+    ``Tom.shoe_size''.
+
+    @todo Refactor with Sequence moving methods up into Constructor.
+
+    @brief Holds a structure (aggregate) type.
+*/
+
+class Structure: public Constructor
+{
+private:
+    BaseType *m_leaf_match(const string &name, btp_stack *s = 0);
+    BaseType *m_exact_match(const string &name, btp_stack *s = 0);
+
+protected:
+    void _duplicate(const Structure &s);
+
+public:
+    Structure(const string &n);
+    Structure(const string &n, const string &d);
+
+    Structure(const Structure &rhs);
+    virtual ~Structure();
+
+    Structure &operator=(const Structure &rhs);
+    virtual BaseType *ptr_duplicate();
+
+    virtual int element_count(bool leaves = false);
+    virtual bool is_linear();
+
+    virtual void set_send_p(bool state);
+    virtual void set_read_p(bool state);
+    virtual void set_in_selection(bool state);
+    virtual void set_leaf_sequence(int level = 1);
+
+    virtual unsigned int width();
+
+    virtual void intern_data(ConstraintEvaluator &eval, DDS &dds);
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    // Do not store values in memory as for C; force users to work with the
+    // C++ objects as defined by the DAP.
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual BaseType *var(const string &name, bool exact_match = true,
+                          btp_stack *s = 0);
+
+    virtual BaseType *var(const string &n, btp_stack &s);
+
+    virtual void add_var(BaseType *bt, Part part = nil);
+    virtual void del_var(const string &name);
+
+    virtual bool read() ;
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool check_semantics(string &msg, bool all = false);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _structure_h
diff --git a/UInt16.cc b/UInt16.cc
new file mode 100644
index 0000000..c08cf1a
--- /dev/null
+++ b/UInt16.cc
@@ -0,0 +1,289 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Int32.
+//
+// jhrg 9/7/94
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: UInt16.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "dods-limits.h"
+#include "debug.h"
+#include "InternalErr.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The UInt16 constructor accepts the name of the variable to be created.
+
+    @param n A string containing the name of the variable to be created.
+*/
+UInt16::UInt16(const string &n)
+        : BaseType(n, dods_uint16_c)
+{}
+
+/** The UInt16 server-side constructor accepts the name of the variable to
+    be created and the dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+UInt16::UInt16(const string &n, const string &d)
+        : BaseType(n, d, dods_uint16_c)
+{}
+
+UInt16::UInt16(const UInt16 &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+UInt16::ptr_duplicate()
+{
+    return new UInt16(*this);
+}
+
+UInt16 &
+UInt16::operator=(const UInt16 &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+UInt16::width()
+{
+    return sizeof(dods_uint16);
+}
+
+bool
+UInt16::serialize(ConstraintEvaluator &eval, DDS &dds,
+                  Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_uint16( _buf ) ;
+
+    return true;
+}
+
+bool
+UInt16::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_uint16( _buf ) ;
+
+    return false;
+}
+
+unsigned int
+UInt16::val2buf(void *val, bool)
+{
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogated library,
+    // thus if the pointer val is NULL, is an Internal Error.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    _buf = *(dods_uint16 *)val;
+
+    return width();
+}
+
+unsigned int
+UInt16::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    if (!*val)
+        *val = new dods_uint16;
+
+    *(dods_uint16 *)*val = _buf;
+
+    return width();
+}
+
+dods_uint16
+UInt16::value() const
+{
+    return _buf;
+}
+
+bool
+UInt16::set_value(dods_uint16 i)
+{
+    _buf = i;
+    set_read_p(true);
+
+    return true;
+}
+
+#if FILE_METHODS
+void
+UInt16::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %u;\n", (unsigned int)_buf) ;
+    }
+    else
+        fprintf(out, "%u", (unsigned int)_buf) ;
+}
+#endif
+
+void
+UInt16::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << (unsigned int)_buf << ";\n" ;
+    }
+    else
+	out << (unsigned int)_buf ;
+}
+
+bool
+UInt16::ops(BaseType *b, int op)
+{
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value was not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b || !(b->read_p() || b->read())) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value was not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops<dods_uint16, dods_byte, Cmp<dods_uint16, dods_byte> >
+               (_buf, dynamic_cast<Byte *>(b)->_buf, op);
+    case dods_int16_c:
+        return rops<dods_uint16, dods_int16, USCmp<dods_uint16, dods_int16> >
+               (_buf, dynamic_cast<Int16 *>(b)->_buf, op);
+    case dods_uint16_c:
+        return rops<dods_uint16, dods_uint16, Cmp<dods_uint16, dods_uint16> >
+               (_buf, dynamic_cast<UInt16 *>(b)->_buf, op);
+    case dods_int32_c:
+        return rops<dods_uint16, dods_int32, USCmp<dods_uint16, dods_int32> >
+               (_buf, dynamic_cast<Int32 *>(b)->_buf, op);
+    case dods_uint32_c:
+        return rops<dods_uint16, dods_uint32, Cmp<dods_uint16, dods_uint32> >
+               (_buf, dynamic_cast<UInt32 *>(b)->_buf, op);
+    case dods_float32_c:
+        return rops<dods_uint16, dods_float32, Cmp<dods_uint16, dods_float32> >
+               (_buf, dynamic_cast<Float32 *>(b)->_buf, op);
+    case dods_float64_c:
+        return rops<dods_uint16, dods_float64, Cmp<dods_uint16, dods_float64> >
+               (_buf, dynamic_cast<Float64 *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+UInt16::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "UInt16::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/UInt16.h b/UInt16.h
new file mode 100644
index 0000000..56c1525
--- /dev/null
+++ b/UInt16.h
@@ -0,0 +1,114 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1996,1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for Int16 type.
+//
+// jhrg 9/7/94
+
+#ifndef _uint16_h
+#define _uint16_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** @brief Holds an unsigned 16-bit integer. */
+
+class UInt16: public BaseType
+{
+    /** This class allows Byte, ..., Float64 access to <tt>_buf</tt> to
+    simplify and speed up the relational operators.
+
+    NB: According to Stroustrup it does not matter where (public, private
+    or protected) friend classes are declared. */
+    friend class Byte;
+    friend class Int16;
+    friend class Int32;
+    friend class UInt32;
+    friend class Float32;
+    friend class Float64;
+
+protected:
+    dods_uint16 _buf;
+
+public:
+    UInt16(const string &n);
+    UInt16(const string &n, const string &d);
+    virtual ~UInt16()
+    {}
+
+    UInt16(const UInt16 &copy_from);
+
+    UInt16 &operator=(const UInt16 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual unsigned int width();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual dods_uint16 value() const;
+    virtual bool set_value(dods_uint16 val);
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _uint16_h
+
diff --git a/UInt32.cc b/UInt32.cc
new file mode 100644
index 0000000..8a90420
--- /dev/null
+++ b/UInt32.cc
@@ -0,0 +1,291 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Int32.
+//
+// jhrg 9/7/94
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: UInt32.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "util.h"
+#include "parser.h"
+#include "Operators.h"
+#include "dods-limits.h"
+#include "debug.h"
+#include "InternalErr.h"
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+/** The UInt32 constructor accepts the name of the variable to be created.
+
+    @param n A string containing the name of the variable to be created.
+    variable is created
+*/
+UInt32::UInt32(const string &n)
+        : BaseType(n, dods_uint32_c)
+{}
+
+/** The UInt32 server-side constructor accepts the name of the variable and
+    the dataset name from which this instance is created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is created
+*/
+UInt32::UInt32(const string &n, const string &d)
+        : BaseType(n, d, dods_uint32_c)
+{}
+
+UInt32::UInt32(const UInt32 &copy_from) : BaseType(copy_from)
+{
+    _buf = copy_from._buf;
+}
+
+BaseType *
+UInt32::ptr_duplicate()
+{
+    return new UInt32(*this);
+}
+
+UInt32 &
+UInt32::operator=(const UInt32 &rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast<BaseType &>(*this) = rhs;
+
+    _buf = rhs._buf;
+
+    return *this;
+}
+
+unsigned int
+UInt32::width()
+{
+    return sizeof(dods_uint32);
+}
+
+bool
+UInt32::serialize(ConstraintEvaluator &eval, DDS &dds,
+                  Marshaller &m, bool ce_eval)
+{
+    dds.timeout_on();
+
+    if (!read_p())
+        read();  // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    m.put_uint32( _buf ) ;
+
+    return true;
+}
+
+bool
+UInt32::deserialize(UnMarshaller &um, DDS *, bool)
+{
+    um.get_uint32( _buf ) ;
+
+    return false;
+}
+
+unsigned int
+UInt32::val2buf(void *val, bool)
+{
+
+    // Jose Garcia
+    // This method is public therefore and I believe it has being designed
+    // to be use by read which must be implemented on the surrogated library,
+    // thus if the pointer val is NULL, is an Internal Error.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    _buf = *(dods_uint32 *)val;
+
+    return width();
+}
+
+unsigned int
+UInt32::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment justifying throwing an Error in val2buf applies here.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    if (!*val)
+        *val = new dods_uint32;
+
+    *(dods_uint32 *)*val = _buf;
+
+    return width();
+}
+
+dods_uint32
+UInt32::value() const
+{
+    return _buf;
+}
+
+bool
+UInt32::set_value(dods_uint32 i)
+{
+    _buf = i;
+    set_read_p(true);
+
+    return true;
+}
+
+#if FILE_METHODS
+void
+UInt32::print_val(FILE *out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+        fprintf(out, " = %u;\n", (unsigned int)_buf) ;
+    }
+    else
+        fprintf(out, "%u", (unsigned int)_buf) ;
+}
+#endif
+
+void
+UInt32::print_val(ostream &out, string space, bool print_decl_p)
+{
+    if (print_decl_p) {
+        print_decl(out, space, false);
+	out << " = " << (unsigned int)_buf << ";\n" ;
+    }
+    else
+	out << (unsigned int)_buf ;
+}
+
+bool
+UInt32::ops(BaseType *b, int op)
+{
+    // Extract the Byte arg's value.
+    if (!read_p() && !read()) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value was not read!");
+    }
+
+    // Extract the second arg's value.
+    if (!b || !(b->read_p() || b->read())) {
+        // Jose Garcia
+        // Since the read method is virtual and implemented outside
+        // libdap++ if we cannot read the data that is the problem
+        // of the user or of whoever wrote the surrogate library
+        // implemeting read therefore it is an internal error.
+        throw InternalErr(__FILE__, __LINE__, "This value was not read!");
+    }
+
+    switch (b->type()) {
+    case dods_byte_c:
+        return rops<dods_uint32, dods_byte, Cmp<dods_uint32, dods_byte> >
+               (_buf, dynamic_cast<Byte *>(b)->_buf, op);
+    case dods_int16_c:
+        return rops<dods_uint32, dods_int16, USCmp<dods_uint32, dods_int16> >
+               (_buf, dynamic_cast<Int16 *>(b)->_buf, op);
+    case dods_uint16_c:
+        return rops<dods_uint32, dods_uint16, Cmp<dods_uint32, dods_uint16> >
+               (_buf, dynamic_cast<UInt16 *>(b)->_buf, op);
+    case dods_int32_c:
+        return rops<dods_uint32, dods_int32, USCmp<dods_uint32, dods_int32> >
+               (_buf, dynamic_cast<Int32 *>(b)->_buf, op);
+    case dods_uint32_c:
+        return rops<dods_uint32, dods_uint32, Cmp<dods_uint32, dods_uint32> >
+               (_buf, dynamic_cast<UInt32 *>(b)->_buf, op);
+    case dods_float32_c:
+        return rops<dods_uint32, dods_float32, Cmp<dods_uint32, dods_float32> >
+               (_buf, dynamic_cast<Float32 *>(b)->_buf, op);
+    case dods_float64_c:
+        return rops<dods_uint32, dods_float64, Cmp<dods_uint32, dods_float64> >
+               (_buf, dynamic_cast<Float64 *>(b)->_buf, op);
+    default:
+        return false;
+    }
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+UInt32::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "UInt32::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "value: " << _buf << endl ;
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/UInt32.h b/UInt32.h
new file mode 100644
index 0000000..9949b0d
--- /dev/null
+++ b/UInt32.h
@@ -0,0 +1,116 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the UInt32 (unsigned int 32) type.
+//
+// jhrg 9/7/94
+
+#ifndef _uint32_h
+#define _uint32_h 1
+
+
+#ifndef _dods_datatypes_h
+#include "dods-datatypes.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+#define FILE_METHODS 1
+
+namespace libdap
+{
+
+/** @brief Holds a 32-bit unsigned integer.
+
+    @see BaseType */
+
+class UInt32: public BaseType
+{
+    /** This class allows Byte, ..., Float64 access to <tt>_buf</tt> to
+    simplify and speed up the relational operators.
+
+    NB: According to Stroustrup it does not matter where (public, private
+    or protected) friend classes are declared. */
+    friend class Byte;
+    friend class Int16;
+    friend class UInt16;
+    friend class Int32;
+    friend class Float32;
+    friend class Float64;
+
+protected:
+    dods_uint32 _buf;
+
+public:
+    UInt32(const string &n);
+    UInt32(const string &n, const string &d);
+    virtual ~UInt32()
+    {}
+
+    UInt32(const UInt32 &copy_from);
+
+    UInt32 &operator=(const UInt32 &rhs);
+
+    virtual BaseType *ptr_duplicate() ;
+
+    virtual unsigned int width();
+
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    virtual dods_uint32 value() const;
+    virtual bool set_value(dods_uint32 val);
+#if FILE_METHODS
+    virtual void print_val(FILE *out, string space = "",
+                           bool print_decl_p = true);
+#endif
+    virtual void print_val(ostream &out, string space = "",
+                           bool print_decl_p = true);
+
+    virtual bool ops(BaseType *b, int op);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif // _uint32_h
+
diff --git a/UnMarshaller.h b/UnMarshaller.h
new file mode 100644
index 0000000..e575077
--- /dev/null
+++ b/UnMarshaller.h
@@ -0,0 +1,85 @@
+// UnMarshaller.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef A_UnMarshaller_h
+#define A_UnMarshaller_h 1
+
+#include <string>
+#include <vector>
+
+using std::string ;
+using std::vector ;
+
+#include "DapObj.h"
+
+#include "dods-datatypes.h"
+
+namespace libdap
+{
+
+class Vector ;
+
+/** @brief abstract base class used to unmarshall/deserialize dap data
+ * objects
+ */
+class UnMarshaller : public DapObj
+{
+public:
+    virtual void		get_byte( dods_byte &val ) = 0 ;
+
+    virtual void		get_int16( dods_int16 &val ) = 0 ;
+    virtual void		get_int32( dods_int32 &val ) = 0 ;
+
+    virtual void		get_float32( dods_float32 &val ) = 0 ;
+    virtual void		get_float64( dods_float64 &val ) = 0 ;
+
+    virtual void		get_uint16( dods_uint16 &val ) = 0 ;
+    virtual void		get_uint32( dods_uint32 &val ) = 0 ;
+
+    virtual void		get_str( string &val ) = 0 ;
+    virtual void		get_url( string &val ) = 0 ;
+
+    virtual void		get_opaque( char *val, unsigned int len ) = 0 ;
+    virtual void		get_int( int &val ) = 0 ;
+
+    virtual void		get_vector( char **val, unsigned int &num,
+                                            Vector &vec ) = 0 ;
+    virtual void		get_vector( char **val, unsigned int &num,
+					    int width, Vector &vec ) = 0 ;
+
+    virtual void		dump(ostream &strm) const = 0 ;
+} ;
+
+} // namespace libdap
+
+#endif // A_UnMarshaller_h
+
diff --git a/Url.cc b/Url.cc
new file mode 100644
index 0000000..70b5b73
--- /dev/null
+++ b/Url.cc
@@ -0,0 +1,73 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for Url.
+//
+// jhrg 9/7/94
+
+
+#include "Url.h"
+
+namespace libdap {
+
+/** The URL constructor requires only the name of the variable
+    to be created.  The name may be omitted, which will create a
+    nameless variable.  This may be adequate for some applications.
+
+    @param n A string containing the name of the variable to be
+    created.
+
+*/
+Url::Url(const string &n) : Str(n)
+{
+    set_type(dods_url_c);  // override the type set by Str
+}
+
+/** The URL server-side constructor requires the name of the variable
+    to be created and the name of the dataset from which this variable is
+    being created.
+
+    @param n A string containing the name of the variable to be created.
+    @param d A string containing the name of the dataset from which this
+    variable is being created.
+*/
+Url::Url(const string &n, const string &d) : Str(n, d)
+{
+    set_type(dods_url_c);  // override the type set by Str
+}
+
+BaseType *
+Url::ptr_duplicate()
+{
+    return new Url(*this);
+}
+
+} // namespace libdap
diff --git a/Url.h b/Url.h
new file mode 100644
index 0000000..cdef63d
--- /dev/null
+++ b/Url.h
@@ -0,0 +1,84 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher (jgallagher at gso.uri.edu)
+
+// Interface for Url type.
+//
+// jhrg 9/7/94
+
+#ifndef _url_h
+#define _url_h 1
+
+
+#include <string>
+
+#ifndef _dods_limits_h
+#include "dods-limits.h"
+#endif
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _str_h
+#include "Str.h"
+#endif
+
+namespace libdap
+{
+
+const unsigned int max_url_len = 255;
+
+/** @brief Holds an Internet address (URL).
+
+    @see BaseType
+    @see Str */
+class Url: public Str
+{
+
+private:
+    string _buf;
+
+    // This enables methods of Str to access _buf in this class.
+    friend class Str;
+
+public:
+    Url(const string &n);
+    Url(const string &n, const string &d);
+    virtual ~Url()
+    {}
+
+    virtual BaseType *ptr_duplicate();
+};
+
+} // namespace libdap
+
+#endif // _url_h
+
diff --git a/VCPP/BeforeInstall.txt b/VCPP/BeforeInstall.txt
new file mode 100644
index 0000000..18ccd45
--- /dev/null
+++ b/VCPP/BeforeInstall.txt
@@ -0,0 +1 @@
+In addition to installing libdap 3.8.2, this will also install other run-time libraries libdap uses. However, this will not install the software need to compile our source code on the Windows XP platform. For more information about building our software from source, see http://scm.opendap.org/trac/wiki/XP or contact us at support at opendap.org.
diff --git a/VCPP/License.txt b/VCPP/License.txt
new file mode 100644
index 0000000..b713790
--- /dev/null
+++ b/VCPP/License.txt
@@ -0,0 +1,177 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE		       
+                     Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.     
+ 59 Temple Place, Suite 330, 
+ Boston, MA  02111-1307  USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away yourfreedom to share and change it.  By contrast, the GNU General PublicLicenses are intended to guarantee your freedom to share and changefree software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to somespecially designated software packages--typically libraries--of theFree Software Foundation and other authors who decide to use it.  Youcan use it too, but we suggest you first think carefully about whetherthis license or the ordinary General Public License is the betterstrategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,not price.  Our General Public Licenses are designed to make sure thatyou have the freedom to distribute copies of free software (and chargefor this service if you wish); that you receive source code or can getit if you want it; that you can change the software and use pieces ofit in new free programs; and that you are informed that you can dothese things.
+
+  To protect your rights, we need to make restrictions that forbiddistributors to deny you these rights or to ask you to surrender theserights.  These restrictions translate to certain responsibilities foryou if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratisor for a fee, you must give the recipients all the rights that we gaveyou.  You must make sure that they, too, receive or can get the sourcecode.  If you link other code with the library, you must providecomplete object files to the recipients, so that they can relink themwith the library after making changes to the library and recompilingit.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright thelibrary, and (2) we offer you this license, which gives you legalpermission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear thatthere is no warranty for the free library.  Also, if the library ismodified by someone else and passed on, the recipients should knowthat what they have is not the original version, so that the originalauthor's reputation will not be affected by problems that might beintroduced by others.
+
+  Finally, software patents pose a constant threat to the existence ofany free program.  We wish to make sure that a company cannoteffectively restrict the users of a free program by obtaining arestrictive license from a patent holder.  Therefore, we insist thatany patent license obtained for a version of the library must beconsistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by theordinary GNU General Public License.  This license, the GNU LesserGeneral Public License, applies to certain designated libraries, andis quite different from the ordinary General Public License.  We usethis license for certain libraries in order to permit linking thoselibraries into non-free programs.
+
+  When a program is linked with a library, whether statically or usinga shared library, the combination of the two is legally speaking acombined work, a derivative of the original library.  The ordinaryGeneral Public License therefore permits such linking only if theentire combination fits its criteria of freedom.  The Lesser GeneralPublic License permits more lax criteria for linking other code withthe library.
+
+  We call this license the "Lesser" General Public License because itdoes Less to protect the user's freedom than the ordinary GeneralPublic License.  It also provides other free software developers Lessof an advantage over competing non-free programs.  These disadvantagesare the reason we use the ordinary General Public License for manylibraries.  However, the Lesser license provides advantages in certainspecial circumstances.
+
+  For example, on rare occasions, there may be a special need toencourage the widest possible use of a certain library, so that it becomesa de-facto standard.  To achieve this, non-free programs must beallowed to use the library.  A more frequent case is that a freelibrary does the same job as widely used non-free libraries.  In thiscase, there is little to gain by limiting the free library to freesoftware only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-freeprograms enables a greater number of people to use a large body offree software.  For example, permission to use the GNU C Library innon-free programs enables many more people to use the whole GNUoperating system, as well as its variant, the GNU/Linux operatingsystem.
+
+  Although the Lesser General Public License is Less protective of theusers' freedom, it does ensure that the user of a program that islinked with the Library has the freedom and the wherewithal to runthat program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution andmodification follow.  Pay close attention to the difference between a"work based on the library" and a "work that uses the library".  Theformer contains code derived from the library, whereas the latter mustbe combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or otherprogram which contains a notice placed by the copyright holder orother authorized party saying it may be distributed under the terms ofthis Lesser General Public License (also called "this License").Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or dataprepared so as to be conveniently linked with application programs(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or workwhich has been distributed under these terms.  A "work based on theLibrary" means either the Library or any derivative work undercopyright law: that is to say, a work containing the Library or aportion of it, either verbatim or with modifications and/or translatedstraightforwardly into another language.  (Hereinafter, translation isincluded without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work formaking modifications to it.  For a library, complete source code meansall the source code for all modules it contains, plus any associatedinterface definition files, plus the scripts used to control compilationand installation of the library.
+
+  Activities other than copying, distribution and modification are notcovered by this License; they are outside its scope.  The act ofrunning a program using the Library is not restricted, and output fromsuch a program is covered only if its contents constitute a work basedon the Library (independent of the use of the Library in a tool forwriting it).  Whether that is true depends on what the Library doesand what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library'scomplete source code as you receive it, in any medium, provided thatyou conspicuously and appropriately publish on each copy anappropriate copyright notice and disclaimer of warranty; keep intactall the notices that refer to this License and to the absence of anywarranty; and distribute a copy of this License along with theLibrary.
+
+  You may charge a fee for the physical act of transferring a copy,and you may at your option offer warranty protection in exchange for afee.
+
+  2. You may modify your copy or copies of the Library or any portionof it, thus forming a work based on the Library, and copy anddistribute such modifications or work under the terms of Section 1above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a    table of data to be supplied by an application program that uses    the facility, other than as an argument passed when the facility    is invoked, then you must make a good faith effort to ensure that,    in the event an application does not supply such function or    table, the facility still operates, and performs whatever part of    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has    a purpose that is entirely well-defined independent of the    application.  Therefore, Subsection 2d requires that any    application-supplied function or table used by this function must    be optional: if the application does not supply it, the square    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  Ifidentifiable sections of that work are not derived from the Library,and can be reasonably considered independent and separate works inthemselves, then this License, and its terms, do not apply to thosesections when you distribute them as separate works.  But when youdistribute the same sections as part of a whole which is a work basedon the Library, the distribution of the whole must be on the terms ofthis License, whose permis [...]
+
+Thus, it is not the intent of this section to claim rights or contestyour rights to work written entirely by you; rather, the intent is toexercise the right to control the distribution of derivative orcollective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Librarywith the Library (or with a work based on the Library) on a volume ofa storage or distribution medium does not bring the other work underthe scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General PublicLicense instead of this License to a given copy of the Library.  To dothis, you must alter all the notices that refer to this License, sothat they refer to the ordinary GNU General Public License, version 2,instead of to this License.  (If a newer version than version 2 of theordinary GNU General Public License has appeared, then you can specifythat version instead if you wish.)  Do not make any other change inthese notices.
+
+  Once this change is made in a given copy, it is irreversible forthat copy, so the ordinary GNU General Public License applies to allsubsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code ofthe Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion orderivative of it, under Section 2) in object code or executable formunder the terms of Sections 1 and 2 above provided that you accompanyit with the complete corresponding machine-readable source code, whichmust be distributed under the terms of Sections 1 and 2 above on amedium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copyfrom a designated place, then offering equivalent access to copy thesource code from the same place satisfies the requirement todistribute the source code, even though third parties are notcompelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of theLibrary, but is designed to work with the Library by being compiled orlinked with it, is called a "work that uses the Library".  Such awork, in isolation, is not a derivative work of the Library, andtherefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Librarycreates an executable that is a derivative of the Library (because itcontains portions of the Library), rather than a "work that uses thelibrary".  The executable is therefore covered by this License.Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header filethat is part of the Library, the object code for the work may be aderivative work of the Library even though the source code is not.Whether this is true is especially significant if the work can belinked without the Library, or if the work is itself a library.  Thethreshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, datastructure layouts and accessors, and small macros and small inlinefunctions (ten lines or less in length), then the use of the objectfile is unrestricted, regardless of whether it is legally a derivativework.  (Executables containing this object code plus portions of theLibrary will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you maydistribute the object code for the work under the terms of Section 6.Any executables containing that work also fall under Section 6,whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine orlink a "work that uses the Library" with the Library to produce awork containing portions of the Library, and distribute that workunder terms of your choice, provided that the terms permitmodification of the work for the customer's own use and reverseengineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that theLibrary is used in it and that the Library and its use are covered bythis License.  You must supply a copy of this License.  If the workduring execution displays copyright notices, you must include thecopyright notice for the Library among them, as well as a referencedirecting the user to the copy of this License.  Also, you must do oneof these things:
+
+    a) Accompany the work with the complete corresponding    machine-readable source code for the Library including whatever    changes were used in the work (which must be distributed under    Sections 1 and 2 above); and, if the work is an executable linked    with the Library, with the complete machine-readable "work that    uses the Library", as object code and/or source code, so that the    user can modify the Library and then relink to produce a modified    executable containing th [...]
+
+    b) Use a suitable shared library mechanism for linking with the    Library.  A suitable mechanism is one that (1) uses at run time a    copy of the library already present on the user's computer system,    rather than copying library functions into the executable, and (2)    will operate properly with a modified version of the library, if    the user installs one, as long as the modified version is    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at    least three years, to give the same user the materials    specified in Subsection 6a, above, for a charge no more    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy    from a designated place, offer equivalent access to copy the above    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses theLibrary" must include any data and utility programs needed forreproducing the executable from it.  However, as a special exception,the materials to be distributed need not include anything that isnormally distributed (in either source or binary form) with the majorcomponents (compiler, kernel, and so on) of the operating system onwhich the executable runs, unless that component itself accompaniesthe executable.
+
+  It may happen that this requirement contradicts the licenserestrictions of other proprietary libraries that do not normallyaccompany the operating system.  Such a contradiction means you cannotuse both them and the Library together in an executable that youdistribute.
+
+  7. You may place library facilities that are a work based on theLibrary side-by-side in a single library together with other libraryfacilities not covered by this License, and distribute such a combinedlibrary, provided that the separate distribution of the work based onthe Library and of the other library facilities is otherwisepermitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work    based on the Library, uncombined with any other library    facilities.  This must be distributed under the terms of the    Sections above.
+
+    b) Give prominent notice with the combined library of the fact    that part of it is a work based on the Library, and explaining    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distributethe Library except as expressly provided under this License.  Anyattempt otherwise to copy, modify, sublicense, link with, ordistribute the Library is void, and will automatically terminate yourrights under this License.  However, parties who have received copies,or rights, from you under this License will not have their licensesterminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have notsigned it.  However, nothing else grants you permission to modify ordistribute the Library or its derivative works.  These actions areprohibited by law if you do not accept this License.  Therefore, bymodifying or distributing the Library (or any work based on theLibrary), you indicate your acceptance of this License to do so, andall its terms and conditions for copying, distributing or modifyingthe Library or works base [...]
+
+  10. Each time you redistribute the Library (or any work based on theLibrary), the recipient automatically receives a license from theoriginal licensor to copy, distribute, link with or modify the Librarysubject to these terms and conditions.  You may not impose any furtherrestrictions on the recipients' exercise of the rights granted herein.You are not responsible for enforcing compliance by third parties withthis License.
+
+  11. If, as a consequence of a court judgment or allegation of patentinfringement or for any other reason (not limited to patent issues),conditions are imposed on you (whether by court order, agreement orotherwise) that contradict the conditions of this License, they do notexcuse you from the conditions of this License.  If you cannotdistribute so as to satisfy simultaneously your obligations under thisLicense and any other pertinent obligations, then as a consequence youmay not distrib [...]
+
+If any portion of this section is held invalid or unenforceable under anyparticular circumstance, the balance of the section is intended to apply,and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe anypatents or other property right claims or to contest validity of anysuch claims; this section has the sole purpose of protecting theintegrity of the free software distribution system which isimplemented by public license practices.  Many people have madegenerous contributions to the wide range of software distributedthrough that system in reliance on consistent application of thatsystem; it is up to the author/donor to de [...]
+
+This section is intended to make thoroughly clear what is believed tobe a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted incertain countries either by patents or by copyrighted interfaces, theoriginal copyright holder who places the Library under this License may addan explicit geographical distribution limitation excluding those countries,so that distribution is permitted only in or among countries not thusexcluded.  In such case, this License incorporates the limitation as ifwritten in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or newversions of the Lesser General Public License from time to time.Such new versions will be similar in spirit to the present version,but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Libraryspecifies a version number of this License which applies to it and"any later version", you have the option of following the terms andconditions either of that version or of any later version published bythe Free Software Foundation.  If the Library does not specify alicense version number, you may choose any version ever published bythe Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other freeprograms whose distribution conditions are incompatible with these,write to the author to ask for permission.  For software which iscopyrighted by the Free Software Foundation, write to the FreeSoftware Foundation; we sometimes make exceptions for this.  Ourdecision will be guided by the two goals of preserving the free statusof all derivatives of our free software and of promoting the sharingand reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NOWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OROTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANYKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THEIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULARPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THELIBRARY IS WITH YOU.  SHO [...]
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO INWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFYAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOUFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL ORCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THELIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEINGRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR AFAILURE OF THE LIBRARY TO OPERA [...]
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatestpossible use to the public, we recommend making it free software thateveryone can redistribute and change.  You can do so by permittingredistribution under these terms (or, alternatively, under the terms of theordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It issafest to attach them to the start of each source file to most effectivelyconvey the exclusion of warranty; and each file should have at least the"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Lesser General Public    License as published by the Free Software Foundation; either    version 2.1 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    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser 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
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or yourschool, if any, to sign a "copyright disclaimer" for the library, ifnecessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
+
diff --git a/VCPP/Makefile b/VCPP/Makefile
new file mode 100644
index 0000000..304c890
--- /dev/null
+++ b/VCPP/Makefile
@@ -0,0 +1,543 @@
+# Makefile for libdap (under VC++ on win32)
+
+# Source code, samples, docs and target build areas
+OBJDIR			= .\objects
+SRCDIR			= ..
+DOCDIR			= .\doc
+SAMPLEDIR		= .\sample
+
+# This is the prepackaging area.  Contents should never be on the build path.
+# Fill in the VERSION (e.g., "= 3.7.3") to generate a final, version stamped
+# release of the product.
+PRODUCT			= libdap
+VERSION			=
+PKGDIR			= ..\..\prepkg\opendap\$(PRODUCT)$(VERSION)
+PKGLIBDIR		= $(PKGDIR)\lib
+PKGDLLDIR		= $(PKGDIR)\dll
+PKGBINDIR		= $(PKGDIR)\bin
+PKGETCDIR		= $(PKGDIR)\etc
+PKGINCDIR		= $(PKGDIR)\include
+PKGSAMPLEDIR	= $(PKGDIR)\sample
+
+# This is the installation area.  It should never be on the build path either
+# (except when building other, non-core components).
+INSTALLDIR		= ..\..
+INSTALLLIBDIR	= $(INSTALLDIR)\lib
+INSTALLDLLDIR	= $(INSTALLDIR)\dll
+INSTALLBINDIR	= $(INSTALLDIR)\bin
+INSTALLETCDIR	= $(INSTALLDIR)\etc
+INSTALLINCDIR	= $(INSTALLDIR)\include
+
+# Headers only come from the source distribution itself.  Neither the
+# Prepackaging or installation areas should be on any path for building
+# the OPeNDAP Core.
+INCLUDEDIR		= $(SRCDIR)
+
+# Compiler, Linker
+CC		= cl
+LINK	= link
+
+# Compiler tools
+LEX	= flex
+YACC	= bison
+
+# We suppress #line directives under win32 to prevent warnings resulting
+# when a "\" followed by some char is interpreted as an escape sequence.
+YACCFLAGS	= --no-lines -d -v
+
+# MT = Static Link Multi-Threaded Model
+# MD = Dynamic Link Multi-Threaded DLL Model
+
+# Setup compiler flags
+MTCFLAGS	= /MT /D HAVE_PTHREAD_H
+MDCFLAGS	= /MD /D HAVE_PTHREAD_H
+CFLAGS		= /nologo /W0 /GR /EHsc /c
+
+# Setup linker flags for libdap
+DAP_MTLFLAGS	= -lib /nologo -libpath:$(OBJDIR)\MT
+DAP_MDLFLAGS	= /nologo -libpath:$(OBJDIR)\MD /dll /def:libdap.def /map /fixed:NO /base:0x06000000 /NODEFAULTLIB:LIBCMT.lib
+
+# Setup linker flags for libdapclient
+CLIENT_MTLFLAGS	= -lib /nologo -libpath:$(OBJDIR)\MT
+CLIENT_MDLFLAGS	= /nologo -libpath:$(OBJDIR)\MD /dll /def:libdapclient.def /map /fixed:NO /base:0x07000000 /NODEFAULTLIB:LIBCMT.lib
+
+# Setup linker flags for libdapserver
+SERVER_MTLFLAGS	= -lib /nologo -libpath:$(OBJDIR)\MT
+SERVER_MDLFLAGS	= /nologo -libpath:$(OBJDIR)\MD /dll /def:libdapserver.def /map /fixed:NO /base:0x08000000 /NODEFAULTLIB:LIBCMT.lib
+
+# Setup link libraries for libdap
+DAP_MTLIBS		=
+DAP_MDLIBS		= libdirent.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+
+# Setup link libraries for libdapclient
+CLIENT_MTLIBS	=
+CLIENT_MDLIBS	= libdapMD.lib libdirent.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+
+# Setup link libraries for libdapserver
+SERVER_MTLIBS	=
+SERVER_MDLIBS	= libdapMD.lib libdirent.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+
+# Setup linker flags for executables
+EMTLFLAGS		= /nologo /libpath:$(OBJDIR)\MT /NODEFAULTLIB:MSVCRT.lib
+EMDLFLAGS		= /nologo /libpath:$(OBJDIR)\MD /NODEFAULTLIB:LIBCMT.lib
+
+# Setup link libraries for executables
+EMTLLIBS		= libdapclientMT.lib libdapserverMT.lib libdapMT.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+EMDLLIBS		= libdapclientMD.lib libdapserverMD.lib libdapMD.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+
+# Setup compiler includes and defines
+INCS		= /I . /I .. /I ..\GNU /I ..\win32\gl /I $(INCLUDEDIR)
+DEFS		= /D WIN32 /D WIN32_LEAN_AND_MEAN /D HAVE_CONFIG_H
+CPPFLAGS	= $(DEFS) $(INCS)
+
+default:
+	@echo "usage: nmake all; nmake install; nmake package"
+
+all:	setup modelMT modelMD
+
+modelMT:
+	@-md $(OBJDIR)\MT
+	@echo "Building MT model libraries for the Core"
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MTCFLAGS)" LFLAGS="$(DAP_MTLFLAGS)" LIBS="$(DAP_MTLIBS)" OBJDIR=$(OBJDIR)\MT libdapMT.lib
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MTCFLAGS)" LFLAGS="$(CLIENT_MTLFLAGS)" LIBS="$(CLIENT_MTLIBS)" OBJDIR=$(OBJDIR)\MT libdapclientMT.lib
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MTCFLAGS)" LFLAGS="$(SERVER_MTLFLAGS)" LIBS="$(SERVER_MTLIBS)" OBJDIR=$(OBJDIR)\MT libdapserverMT.lib
+
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MTCFLAGS)" LFLAGS="$(EMTLFLAGS)" LIBS="$(EMTLLIBS)" OBJDIR=$(OBJDIR)\MT getdap
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MTCFLAGS)" LFLAGS="$(EMTLFLAGS)" LIBS="$(EMTLLIBS)" OBJDIR=$(OBJDIR)\MT deflate
+	@echo "MT model libraries for the Core are complete"
+
+modelMD:
+	@-md $(OBJDIR)\MD
+	@echo "Building MD model libraries for the Core"
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MDCFLAGS)" LFLAGS="$(DAP_MDLFLAGS)" LIBS="$(DAP_MDLIBS)" OBJDIR=$(OBJDIR)\MD libdapMD.dll	
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MDCFLAGS)" LFLAGS="$(CLIENT_MDLFLAGS)" LIBS="$(CLIENT_MDLIBS)" OBJDIR=$(OBJDIR)\MD libdapclientMD.dll
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MDCFLAGS)" LFLAGS="$(SERVER_MDLFLAGS)" LIBS="$(SERVER_MDLIBS)" OBJDIR=$(OBJDIR)\MD libdapserverMD.dll
+
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MDCFLAGS)" LFLAGS="$(EMDLFLAGS)" LIBS="$(EMDLLIBS)" OBJDIR=$(OBJDIR)\MD getdap
+	@nmake /NOLOGO CFLAGS="$(CFLAGS) $(MDCFLAGS)" LFLAGS="$(EMDLFLAGS)" LIBS="$(EMDLLIBS)" OBJDIR=$(OBJDIR)\MD deflate
+	@echo "MD model libraries for the Core are complete"
+
+# Clear built-in rules and set new ones
+.SUFFIXES :
+.SUFFIXES :	.obj .c .cc .exe
+
+# Rules for library objects, both the .c and .cc's are C++
+{$(SRCDIR)}.c{$(OBJDIR)}.obj:
+	$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $<
+
+{$(SRCDIR)}.cc{$(OBJDIR)}.obj:
+	$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $<
+
+# Rule for linking executables
+{$(OBJDIR)}.obj{$(OBJDIR)}.exe:
+	$(LINK) $(LFLAGS) /out:$@ $< $(LIBS)
+
+GNU_OBJS = $(OBJDIR)\GetOpt.obj \
+		$(OBJDIR)\GNURegex.obj \
+		$(OBJDIR)\regex.obj \
+		$(OBJDIR)\strcasecmp.obj \
+		$(OBJDIR)\strncasecmp.obj \
+		$(OBJDIR)\strnlen1.obj \
+		$(OBJDIR)\localcharset.obj
+
+GRAM_OBJS = $(OBJDIR)\lex.das.obj \
+		$(OBJDIR)\das.tab.obj \
+		$(OBJDIR)\lex.dds.obj \
+		$(OBJDIR)\dds.tab.obj \
+		$(OBJDIR)\lex.ce_expr.obj \
+		$(OBJDIR)\ce_expr.tab.obj \
+		$(OBJDIR)\lex.Error.obj \
+		$(OBJDIR)\Error.tab.obj
+
+DAP_OBJS = $(GRAM_OBJS) \
+		$(OBJDIR)\AttrTable.obj \
+		$(OBJDIR)\ConstraintEvaluator.obj \
+		$(OBJDIR)\DAS.obj \
+		$(OBJDIR)\DDS.obj \
+		$(OBJDIR)\DataDDS.obj \
+		$(OBJDIR)\DDXParser.obj \
+		$(OBJDIR)\BaseType.obj \
+		$(OBJDIR)\Byte.obj \
+		$(OBJDIR)\Error.obj \
+		$(OBJDIR)\Int32.obj \
+		$(OBJDIR)\Float64.obj \
+		$(OBJDIR)\Str.obj \
+		$(OBJDIR)\Url.obj \
+		$(OBJDIR)\Vector.obj \
+		$(OBJDIR)\Array.obj \
+		$(OBJDIR)\Structure.obj \
+		$(OBJDIR)\Sequence.obj \
+		$(OBJDIR)\Grid.obj \
+		$(OBJDIR)\UInt32.obj \
+		$(OBJDIR)\Int16.obj \
+		$(OBJDIR)\UInt16.obj \
+		$(OBJDIR)\Float32.obj \
+		$(OBJDIR)\GeoConstraint.obj \
+		$(OBJDIR)\GridGeoConstraint.obj \
+		$(OBJDIR)\Constructor.obj \
+		$(OBJDIR)\BaseTypeFactory.obj \
+		$(OBJDIR)\SignalHandler.obj \
+		$(OBJDIR)\InternalErr.obj \
+		$(OBJDIR)\util.obj \
+		$(OBJDIR)\xdrutil_ppc.obj \
+		$(OBJDIR)\XDRUtils.obj	 \
+		$(OBJDIR)\XDRFileMarshaller.obj	\
+		$(OBJDIR)\XDRFileUnMarshaller.obj	\
+		$(OBJDIR)\XDRStreamMarshaller.obj	 \
+		$(OBJDIR)\parser-util.obj \
+		$(OBJDIR)\escaping.obj \
+		$(OBJDIR)\Clause.obj \
+		$(OBJDIR)\RValue.obj \
+		$(OBJDIR)\gse.tab.obj \
+		$(OBJDIR)\ce_functions.obj \
+		$(OBJDIR)\GSEClause.obj \
+		$(OBJDIR)\lex.gse_.obj \
+		$(OBJDIR)\ArrayGeoConstraint.obj \
+		$(OBJDIR)\DapIndent.obj
+
+CLIENT_OBJS = $(OBJDIR)\RCReader.obj \
+		$(OBJDIR)\Connect.obj \
+		$(OBJDIR)\HTTPConnect.obj \
+		$(OBJDIR)\HTTPCache.obj \
+		$(OBJDIR)\HTTPCacheTable.obj \
+		$(OBJDIR)\AISResources.obj \
+		$(OBJDIR)\AISDatabaseParser.obj \
+		$(OBJDIR)\AISMerge.obj \
+		$(OBJDIR)\AISConnect.obj \
+		$(OBJDIR)\util_mit.obj \
+		$(OBJDIR)\ResponseTooBigErr.obj
+
+SERVER_OBJS = $(OBJDIR)\DODSFilter.obj \
+		$(OBJDIR)\Ancillary.obj \
+		$(OBJDIR)\cgi_util.obj
+
+# Convenience dependancies
+libdapMT.lib:		$(OBJDIR)\libdapMT.lib
+libdapclientMT.lib:	$(OBJDIR)\libdapclientMT.lib
+libdapserverMT.lib:	$(OBJDIR)\libdapserverMT.lib
+libdapMD.dll:		$(OBJDIR)\libdapMD.dll
+libdapclientMD.dll:	$(OBJDIR)\libdapclientMD.dll
+libdapserverMD.dll:	$(OBJDIR)\libdapserverMD.dll
+
+getdap:		$(OBJDIR)\getdap.exe
+deflate:	$(OBJDIR)\deflate.exe
+
+# Build the static-link core libraries
+$(OBJDIR)\libdapMT.lib: $(DAP_OBJS) $(GNU_OBJS)
+	$(LINK) $(LFLAGS) /out:$@ $** $(LIBS)
+	
+$(OBJDIR)\libdapserverMT.lib: $(SERVER_OBJS)
+	$(LINK) $(LFLAGS) /out:$@ $** $(LIBS)
+
+$(OBJDIR)\libdapclientMT.lib: $(CLIENT_OBJS)
+	$(LINK) $(LFLAGS) /out:$@ $** $(LIBS)
+	
+############################################################################
+# The song and dances before the link lines below are to get a legitimate
+# module export definition (.def) for the dll's.  We use lib, dumpbin and
+# a 3rd-party awk to do this automatically in a rather round-about way.
+#
+# The $$ reduces to just $ as make evaluates that.  The \? to awk tells it
+# to be looking for a literal "?".  A textual description of the awk command
+# is as follows: "Find all second fields (2nd whitespace delimited groups of
+# characters) in the text lines that begin with ? and do not begin with ??_
+# (i.e., all C++ code originating methods minus the destructors which should
+# not be exposed do to how dll's work) and output those in the module export
+# definition file."  These are the methods that will be exposed to programs
+# that use the dll in question.  C code references begins with just "_" and
+# we need not expose those.
+############################################################################
+	
+# Build the dynamic-link core libraries
+$(OBJDIR)\libdapMD.dll: $(DAP_OBJS) $(GNU_OBJS)
+	@lib /NOLOGO /out:$(OBJDIR)\tmp.lib $** > $(OBJDIR)\devnull
+	@dumpbin /OUT:$(OBJDIR)\tmp.def /linkermember:2 $(OBJDIR)\tmp.lib > $(OBJDIR)\devnull
+	@echo EXPORTS > libdap.def
+	@gawk "{ if ($$2 ~ /^[\?].*/ && $$2 !~ /^\?\?_.*/) print $$2 }" < $(OBJDIR)\tmp.def >> libdap.def
+	$(LINK) $(LFLAGS) /out:$@ $** $(LIBS)
+	@del libdap.def $(OBJDIR)\tmp.lib $(OBJDIR)\tmp.def $(OBJDIR)\devnull
+
+$(OBJDIR)\libdapclientMD.dll: $(CLIENT_OBJS)
+	@lib /NOLOGO /out:$(OBJDIR)\tmp.lib $** > $(OBJDIR)\devnull
+	@dumpbin /OUT:$(OBJDIR)\tmp.def /linkermember:2 $(OBJDIR)\tmp.lib > $(OBJDIR)\devnull
+	@echo EXPORTS > libdapclient.def
+	@gawk "{ if ($$2 ~ /^[\?].*/ && $$2 !~ /^\?\?_.*/) print $$2 }" < $(OBJDIR)\tmp.def >> libdapclient.def
+	$(LINK) $(LFLAGS) /out:$@ $** $(LIBS)
+	@del libdapclient.def $(OBJDIR)\tmp.lib $(OBJDIR)\tmp.def $(OBJDIR)\devnull
+
+$(OBJDIR)\libdapserverMD.dll: $(SERVER_OBJS)
+	@lib /NOLOGO /out:$(OBJDIR)\tmp.lib $** > $(OBJDIR)\devnull
+	@dumpbin /OUT:$(OBJDIR)\tmp.def /linkermember:2 $(OBJDIR)\tmp.lib > $(OBJDIR)\devnull
+	@echo EXPORTS > libdapserver.def
+	@gawk "{ if ($$2 ~ /^[\?].*/ && $$2 !~ /^\?\?_.*/) print $$2 }" < $(OBJDIR)\tmp.def >> libdapserver.def
+	$(LINK) $(LFLAGS) /out:$@ $** $(LIBS)
+	@del libdapserver.def $(OBJDIR)\tmp.lib $(OBJDIR)\tmp.def $(OBJDIR)\devnull
+
+# Libdap with the gram objs
+$(OBJDIR)\lex.das.obj					: $(SRCDIR)\lex.das.cc
+$(OBJDIR)\das.tab.obj					: $(SRCDIR)\das.tab.cc
+$(OBJDIR)\lex.dds.obj					: $(SRCDIR)\lex.dds.cc
+$(OBJDIR)\dds.tab.obj					: $(SRCDIR)\dds.tab.cc
+$(OBJDIR)\lex.ce_expr.obj				: $(SRCDIR)\lex.ce_expr.cc
+$(OBJDIR)\ce_expr.tab.obj				: $(SRCDIR)\ce_expr.tab.cc
+$(OBJDIR)\lex.Error.obj					: $(SRCDIR)\lex.Error.cc
+$(OBJDIR)\Error.obj						: $(SRCDIR)\Error.cc
+$(OBJDIR)\Error.tab.obj					: $(SRCDIR)\Error.tab.cc
+$(OBJDIR)\AttrTable.obj					: $(SRCDIR)\AttrTable.cc
+$(OBJDIR)\ConstraintEvaluator.obj 		: $(SRCDIR)\ConstraintEvaluator.cc
+$(OBJDIR)\DapIndent.obj					: $(SRCDIR)\DapIndent.cc
+$(OBJDIR)\DAS.obj						: $(SRCDIR)\DAS.cc
+$(OBJDIR)\DDS.obj						: $(SRCDIR)\DDS.cc
+$(OBJDIR)\DataDDS.obj					: $(SRCDIR)\DataDDS.cc
+$(OBJDIR)\DDXParser.obj					: $(SRCDIR)\DDXParser.cc
+$(OBJDIR)\BaseType.obj					: $(SRCDIR)\BaseType.cc
+$(OBJDIR)\Byte.obj						: $(SRCDIR)\Byte.cc
+$(OBJDIR)\Int32.obj						: $(SRCDIR)\Int32.cc
+$(OBJDIR)\Float64.obj					: $(SRCDIR)\Float64.cc
+$(OBJDIR)\GeoConstraint.obj				: $(SRCDIR)\GeoConstraint.cc
+$(OBJDIR)\GridGeoConstraint.obj			: $(SRCDIR)\GridGeoConstraint.cc
+$(OBJDIR)\Str.obj						: $(SRCDIR)\Str.cc
+$(OBJDIR)\Url.obj						: $(SRCDIR)\Url.cc
+$(OBJDIR)\Vector.obj					: $(SRCDIR)\Vector.cc
+$(OBJDIR)\Array.obj						: $(SRCDIR)\Array.cc
+$(OBJDIR)\Structure.obj					: $(SRCDIR)\Structure.cc
+$(OBJDIR)\Sequence.obj					: $(SRCDIR)\Sequence.cc
+$(OBJDIR)\Grid.obj						: $(SRCDIR)\Grid.cc
+$(OBJDIR)\UInt32.obj					: $(SRCDIR)\UInt32.cc
+$(OBJDIR)\Int16.obj						: $(SRCDIR)\Int16.cc
+$(OBJDIR)\UInt16.obj					: $(SRCDIR)\UInt16.cc
+$(OBJDIR)\Float32.obj					: $(SRCDIR)\Float32.cc
+$(OBJDIR)\Constructor.obj				: $(SRCDIR)\Constructor.cc
+$(OBJDIR)\PassiveInt32.obj				: $(SRCDIR)\PassiveInt32.cc
+$(OBJDIR)\PassiveFloat64.obj			: $(SRCDIR)\PassiveFloat64.cc
+$(OBJDIR)\PassiveStr.obj				: $(SRCDIR)\PassiveStr.cc
+$(OBJDIR)\PassiveUrl.obj				: $(SRCDIR)\PassiveUrl.cc
+$(OBJDIR)\PassiveUInt32.obj				: $(SRCDIR)\PassiveUInt32.cc
+$(OBJDIR)\PassiveInt16.obj				: $(SRCDIR)\PassiveInt16.cc
+$(OBJDIR)\PassiveUInt16.obj				: $(SRCDIR)\PassiveUInt16.cc
+$(OBJDIR)\PassiveFloat32.obj			: $(SRCDIR)\PassiveFloat32.cc
+$(OBJDIR)\PassiveArray.obj				: $(SRCDIR)\PassiveArray.cc
+$(OBJDIR)\PassiveStructure.obj			: $(SRCDIR)\PassiveStructure.cc
+$(OBJDIR)\BaseTypeFactory.obj			: $(SRCDIR)\BaseTypeFactory.cc
+$(OBJDIR)\SignalHandler.obj				: $(SRCDIR)\SignalHandler.cc
+$(OBJDIR)\InternalErr.obj				: $(SRCDIR)\InternalErr.cc
+$(OBJDIR)\util.obj						: $(SRCDIR)\util.cc
+$(OBJDIR)\xdrutil_ppc.obj				: $(SRCDIR)\Xdrutil_ppc.c
+$(OBJDIR)\XDRUtils.obj					: $(SRCDIR)\XDRUtils.cc
+$(OBJDIR)\XDRFileMarshaller.obj			: $(SRCDIR)\XDRFileMarshaller.cc
+$(OBJDIR)\XDRFileUnMarshaller.obj		: $(SRCDIR)\XDRFileUnMarshaller.cc	
+$(OBJDIR)\XDRStreamMarshaller.obj		: $(SRCDIR)\XDRStreamMarshaller.cc
+$(OBJDIR)\parser-util.obj				: $(SRCDIR)\parser-util.cc
+$(OBJDIR)\escaping.obj					: $(SRCDIR)\escaping.cc
+$(OBJDIR)\Clause.obj					: $(SRCDIR)\Clause.cc
+$(OBJDIR)\RValue.obj					: $(SRCDIR)\RValue.cc
+$(OBJDIR)\gse.tab.obj					: $(SRCDIR)\gse.tab.cc
+$(OBJDIR)\ce_functions.obj				: $(SRCDIR)\ce_functions.cc
+$(OBJDIR)\GSEClause.obj					: $(SRCDIR)\GSEClause.cc
+$(OBJDIR)\lex.gse_.obj					: $(SRCDIR)\lex.gse_.cc
+$(OBJDIR)\ArrayGeoConstraint.obj		: $(SRCDIR)\ArrayGeoConstraint.cc
+
+# Libdap client
+$(OBJDIR)\RCReader.obj					: $(SRCDIR)\RCReader.cc
+$(OBJDIR)\Connect.obj					: $(SRCDIR)\Connect.cc
+$(OBJDIR)\HTTPConnect.obj				: $(SRCDIR)\HTTPConnect.cc
+$(OBJDIR)\HTTPCache.obj					: $(SRCDIR)\HTTPCache.cc
+$(OBJDIR)\HTTPCacheTable.obj			: $(SRCDIR)\HTTPCacheTable.cc
+$(OBJDIR)\AISResources.obj				: $(SRCDIR)\AISResources.cc
+$(OBJDIR)\AISDatabaseParser.obj			: $(SRCDIR)\AISDatabaseParser.cc
+$(OBJDIR)\AISMerge.obj					: $(SRCDIR)\AISMerge.cc
+$(OBJDIR)\AISConnect.obj				: $(SRCDIR)\AISConnect.cc
+$(OBJDIR)\util_mit.obj					: $(SRCDIR)\util_mit.cc
+$(OBJDIR)\ResponseTooBigErr.obj			: $(SRCDIR)\ResponseTooBigErr.cc
+
+# libdap server
+$(OBJDIR)\DODSFilter.obj				: $(SRCDIR)\DODSFilter.cc
+$(OBJDIR)\Ancillary.obj					: $(SRCDIR)\Ancillary.cc
+$(OBJDIR)\cgi_util.obj					: $(SRCDIR)\cgi_util.cc
+
+# Regular expression code
+$(OBJDIR)\GetOpt.obj		: $(SRCDIR)\GNU\GetOpt.cc
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $(SRCDIR)\GNU\GetOpt.cc
+$(OBJDIR)\GNURegex.obj		: $(SRCDIR)\GNU\GNURegex.cc
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $(SRCDIR)\GNU\GNURegex.cc
+$(OBJDIR)\regex.obj		: $(SRCDIR)\win32\gl\regex.c
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tc $(SRCDIR)\win32\gl\regex.c
+$(OBJDIR)\strcasecmp.obj	: $(SRCDIR)\win32\gl\strcasecmp.c
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tc $(SRCDIR)\win32\gl\strcasecmp.c
+$(OBJDIR)\strncasecmp.obj	: $(SRCDIR)\win32\gl\strncasecmp.c
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tc $(SRCDIR)\win32\gl\strncasecmp.c
+$(OBJDIR)\strnlen1.obj	: $(SRCDIR)\win32\gl\strnlen1.c
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tc $(SRCDIR)\win32\gl\strnlen1.c
+$(OBJDIR)\localcharset.obj	: $(SRCDIR)\win32\gl\localcharset.c
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tc $(SRCDIR)\win32\gl\localcharset.c
+
+# Source generated by compiler tools
+$(SRCDIR)\lex.das.cc:	$(SRCDIR)\das.lex $(SRCDIR)\das.tab.cc $(SRCDIR)\das.tab.hh
+	$(LEX) -8 $(SRCDIR)\das.lex
+	@move lex.das.cc $(SRCDIR)\lex.das.cc
+#	@del lex.das.c
+
+$(SRCDIR)\das.tab.cc $(SRCDIR)\das.tab.hh: $(SRCDIR)\das.y $(SRCDIR)\DAS.h
+	$(YACC) $(YACCFLAGS) -p das -o $(SRCDIR)\das.tab.cc $(SRCDIR)\das.y
+#	@move $(SRCDIR)\das.tab.cc.h $(SRCDIR)\das.tab.hh
+#	@del $(SRCDIR)\das.tab.cc.h
+
+$(SRCDIR)\lex.dds.cc:	$(SRCDIR)\dds.lex $(SRCDIR)\dds.tab.cc $(SRCDIR)\dds.tab.hh
+	$(LEX) -8 $(SRCDIR)\dds.lex
+	@move lex.dds.cc $(SRCDIR)\lex.dds.cc
+#	@del lex.dds.c
+
+$(SRCDIR)\dds.tab.cc $(SRCDIR)\dds.tab.hh: $(SRCDIR)\dds.y
+	$(YACC) $(YACCFLAGS) -p dds -o $(SRCDIR)\dds.tab.cc $(SRCDIR)\dds.y
+	@move $(SRCDIR)\dds.tab.cc.h $(SRCDIR)\dds.tab.hh
+#	@del $(SRCDIR)\dds.tab.c
+
+$(SRCDIR)\lex.ce_expr.cc: $(SRCDIR)\ce_expr.lex $(SRCDIR)\ce_expr.tab.cc $(SRCDIR)\ce_expr.tab.hh
+	$(LEX) -8 $(SRCDIR)\ce_expr.lex
+	@move lex.ce_expr.cc $(SRCDIR)\lex.ce_expr.cc
+#	@del lex.ce_expr.c
+
+$(SRCDIR)\ce_expr.tab.cc $(SRCDIR)\ce_expr.tab.hh: $(SRCDIR)\ce_expr.y
+	$(YACC) $(YACCFLAGS) -p ce_expr -o $(SRCDIR)\ce_expr.tab.cc $(SRCDIR)\ce_expr.y
+	@move $(SRCDIR)\ce_expr.tab.cc.h $(SRCDIR)\ce_expr.tab.hh
+#	@del $(SRCDIR)\ce_expr.tab.c
+
+$(SRCDIR)\lex.Error.cc:	$(SRCDIR)\Error.lex $(SRCDIR)\Error.tab.cc $(SRCDIR)\Error.tab.hh
+	$(LEX) -8 $(SRCDIR)\Error.lex
+	@move lex.Error.cc $(SRCDIR)\lex.Error.cc
+#	@del lex.Error.c
+
+$(SRCDIR)\Error.tab.cc $(SRCDIR)\Error.tab.hh: $(SRCDIR)\Error.y
+	$(YACC) $(YACCFLAGS) -p Error -o $(SRCDIR)\Error.tab.cc $(SRCDIR)\Error.y
+	@move $(SRCDIR)\Error.tab.cc.h $(SRCDIR)\Error.tab.hh
+#	@del $(SRCDIR)\Error.tab.c
+
+$(SRCDIR)\lex.gse_.cc:	$(SRCDIR)\gse.lex $(SRCDIR)\gse.tab.cc $(SRCDIR)\gse.tab.hh
+	$(LEX) -8 $(SRCDIR)\gse.lex
+	@move lex.gse_.cc $(SRCDIR)\lex.gse_.cc
+#	@del lex.gse_.c
+
+$(SRCDIR)\gse.tab.cc $(SRCDIR)\gse.tab.hh: $(SRCDIR)\gse.y
+	$(YACC) $(YACCFLAGS) -p gse_ -o $(SRCDIR)\gse.tab.cc $(SRCDIR)\gse.y
+	@move $(SRCDIR)\gse.tab.cc.h $(SRCDIR)\gse.tab.hh
+#	@del $(SRCDIR)\gse.tab.c
+
+$(OBJDIR)\getdap.exe: $(OBJDIR)\getdap.obj
+
+$(OBJDIR)\deflate.exe: $(OBJDIR)\deflate.obj 
+
+# Command-Line Client and select utils in console mode
+$(OBJDIR)\getdap.obj    : $(SRCDIR)\getdap.cc
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $(SRCDIR)\getdap.cc
+
+$(OBJDIR)\deflate.obj    : $(SRCDIR)\deflate.c
+	@$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tc $(SRCDIR)\deflate.c
+
+# We have to create a temporary unistd.h because bison
+# and/or flex create source that includes that - even though
+# there is no such header under win32 and it is unnecessary there
+# (that is, even though these utils can run under win32 - by definition
+# they generate output for the UNIX world).  This stupid pet trick
+# also properly defines isatty() for the generated source under win32.
+setup:
+	@-echo /*  Dummy patch header to get win32 flex/bison generated  */ > unistd.h
+	@-echo /*  source code to compile under win32.  If you see this  */ >> unistd.h
+	@-echo /*  temp file, feel free to scratch it.                   */ >> unistd.h
+	@-echo #include "io.h" >> unistd.h
+
+# Win32 libnc-dap requires the win32\gl\regex.h.  Under unix builds, it is simply
+# assumed to be on the machine already.
+install: all mkinstdirs
+	copy $(OBJDIR)\MT\libdapMT.lib $(INSTALLLIBDIR)
+	copy $(OBJDIR)\MT\libdapclientMT.lib $(INSTALLLIBDIR)
+	copy $(OBJDIR)\MT\libdapserverMT.lib $(INSTALLLIBDIR)
+
+	copy $(OBJDIR)\MD\libdapMD.dll* $(INSTALLDLLDIR)
+	mt -nologo -manifest $(INSTALLDLLDIR)\libdapMD.dll.manifest -outputresource:$(INSTALLDLLDIR)\libdapMD.dll;2
+	del $(INSTALLDLLDIR)\libdapMD.dll.manifest
+	copy $(OBJDIR)\MD\libdapMD.lib $(INSTALLLIBDIR)
+	copy $(OBJDIR)\MD\libdapclientMD.dll* $(INSTALLDLLDIR)
+	mt -nologo -manifest $(INSTALLDLLDIR)\libdapclientMD.dll.manifest -outputresource:$(INSTALLDLLDIR)\libdapclientMD.dll;2
+	del $(INSTALLDLLDIR)\libdapclientMD.dll.manifest
+	copy $(OBJDIR)\MD\libdapclientMD.lib $(INSTALLLIBDIR)
+	copy $(OBJDIR)\MD\libdapserverMD.dll* $(INSTALLDLLDIR)
+	mt -nologo -manifest $(INSTALLDLLDIR)\libdapserverMD.dll.manifest -outputresource:$(INSTALLDLLDIR)\libdapserverMD.dll;2
+	del $(INSTALLDLLDIR)\libdapserverMD.dll.manifest
+	copy $(OBJDIR)\MD\libdapserverMD.lib $(INSTALLLIBDIR)
+
+	copy $(OBJDIR)\MD\getdap.exe* $(INSTALLBINDIR)
+	mt -nologo -manifest $(INSTALLBINDIR)\getdap.exe.manifest -outputresource:$(INSTALLBINDIR)\getdap.exe;1
+	del $(INSTALLBINDIR)\getdap.exe.manifest
+	copy $(OBJDIR)\MD\deflate.exe* $(INSTALLETCDIR)
+	mt -nologo -manifest $(INSTALLETCDIR)\deflate.exe.manifest -outputresource:$(INSTALLETCDIR)\deflate.exe;1
+	del $(INSTALLETCDIR)\deflate.exe.manifest
+	copy dods-datatypes.h $(INSTALLINCDIR)
+	copy xdr-datatypes.h $(INSTALLINCDIR)
+	copy $(SRCDIR)\*.h $(INSTALLINCDIR)
+	copy $(SRCDIR)\GNU\*.h $(INSTALLINCDIR)\GNU
+	copy $(SRCDIR)\win32\gl\regex.h $(INSTALLINCDIR)
+	
+package: all mkpkgdirs document
+	copy $(OBJDIR)\MT\libdapMT.lib $(PKGLIBDIR)
+	copy $(OBJDIR)\MT\libdapclientMT.lib $(PKGLIBDIR)
+	copy $(OBJDIR)\MT\libdapserverMT.lib $(PKGLIBDIR)
+
+	copy $(OBJDIR)\MD\libdapMD.dll* $(PKGDLLDIR)
+	mt -nologo -manifest $(PKGDLLDIR)\libdapMD.dll.manifest -outputresource:$(PKGDLLDIR)\libdapMD.dll;2
+	del $(PKGDLLDIR)\libdapMD.dll.manifest
+	copy $(OBJDIR)\MD\libdapMD.lib $(PKGLIBDIR)
+	copy $(OBJDIR)\MD\libdapclientMD.dll* $(PKGDLLDIR)
+	mt -nologo -manifest $(PKGDLLDIR)\libdapclientMD.dll.manifest -outputresource:$(PKGDLLDIR)\libdapclientMD.dll;2
+	del $(PKGDLLDIR)\libdapclientMD.dll.manifest
+	copy $(OBJDIR)\MD\libdapclientMD.lib $(PKGLIBDIR)
+	copy $(OBJDIR)\MD\libdapserverMD.dll* $(PKGDLLDIR)
+	mt -nologo -manifest $(PKGDLLDIR)\libdapserverMD.dll.manifest -outputresource:$(PKGDLLDIR)\libdapserverMD.dll;2
+	del $(PKGDLLDIR)\libdapserverMD.dll.manifest
+	copy $(OBJDIR)\MD\libdapserverMD.lib $(PKGLIBDIR)
+
+	copy $(OBJDIR)\MD\getdap.exe* $(PKGBINDIR)
+	mt -nologo -manifest $(PKGBINDIR)\getdap.exe.manifest -outputresource:$(PKGBINDIR)\getdap.exe;1
+	del $(PKGBINDIR)\getdap.exe.manifest
+	copy $(OBJDIR)\MD\deflate.exe* $(PKGETCDIR)
+	mt -nologo -manifest $(PKGETCDIR)\deflate.exe.manifest -outputresource:$(PKGETCDIR)\deflate.exe;1
+	del $(PKGETCDIR)\deflate.exe.manifest
+	copy dods-datatypes.h $(PKGINCDIR)
+	copy xdr-datatypes.h $(PKGINCDIR)
+	copy $(SRCDIR)\*.h $(PKGINCDIR)
+	copy $(SRCDIR)\GNU\*.h $(PKGINCDIR)\GNU
+	copy $(SRCDIR)\win32\gl\regex.h $(PKGINCDIR)
+	
+mkinstdirs:	
+	@-md $(INSTALLLIBDIR)
+	@-md $(INSTALLBINDIR)
+	@-md $(INSTALLETCDIR)
+	@-md $(INSTALLDLLDIR)
+	@-md $(INSTALLINCDIR)
+	@-md $(INSTALLINCDIR)\GNU
+	
+mkpkgdirs:	
+	@-md $(PKGLIBDIR)
+	@-md $(PKGBINDIR)
+	@-md $(PKGETCDIR)
+	@-md $(PKGDLLDIR)
+	@-md $(PKGINCDIR)
+	@-md $(PKGINCDIR)\GNU
+	
+document:
+	@-md $(PKGSAMPLEDIR)
+	copy $(SAMPLEDIR)\* $(PKGSAMPLEDIR)
+	copy $(DOCDIR)\readme.txt $(PKGDIR)
+
+clean:
+	@-rd /Q /S $(OBJDIR) $(PKGDIR)
+	@-del unistd.h
+
+grammarclean: clean
+	@-del $(SRCDIR)\*.tab.cc
+	@-del $(SRCDIR)\*.tab.hh
+	@-del $(SRCDIR)\lex.*.cc
+
+!INCLUDE "dependancies"
+
+
+
diff --git a/VCPP/config.h b/VCPP/config.h
new file mode 100644
index 0000000..728287c
--- /dev/null
+++ b/VCPP/config.h
@@ -0,0 +1,53 @@
+/*  config.h.  Generated by hand for MS VC++ 7.x.  ROM - 11/2006  */
+#ifndef _config_h
+#define _config_h
+
+#define CNAME "libdap"
+#define CVER "3.8.2"
+#define DAP_PROTOCOL_VERSION "3.1"
+#define DVR "libdap/3.8.2"
+#define PACKAGE "libdap"
+#define PACKAGE_NAME "libdap"
+#define PACKAGE_STRING "libdap 3.8.2"
+#define PACKAGE_VERSION "3.8.2"
+
+#define HAVE_ALLOCA 1
+#define HAVE_MKTIME 1
+#define STDC_HEADERS 1
+#define CNAME "DODS"
+#define CVER "$VERSION"
+
+#define SIZEOF_CHAR 1
+#define SIZEOF_DOUBLE 8
+#define SIZEOF_FLOAT 4
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 4
+
+#define HAVE_STRDUP 1
+
+#define HAVE_FCNTL_H 1
+#define HAVE_LIMITS_H 1
+
+/*  Replaces dods-deployed stat.h defines only found on unixes  */
+/*  Need of this reconfirmed 11/2006 - ROM.                     */
+#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+
+#define XDR_FLOAT32 xdr_float
+#define XDR_FLOAT64 xdr_double
+#define XDR_INT16 xdr_short
+#define XDR_INT32 xdr_long
+#define XDR_UINT16 xdr_u_short
+#define XDR_UINT32 xdr_u_long
+
+#ifndef LIBDAP_ROOT
+#define LIBDAP_ROOT "C:/opendap"
+#endif
+
+#undef LIBXML_ICONV_ENABLED
+
+#define not_used
+
+#endif
+
+
diff --git a/VCPP/dependancies b/VCPP/dependancies
new file mode 100644
index 0000000..e69de29
diff --git a/VCPP/doc/readme.txt b/VCPP/doc/readme.txt
new file mode 100644
index 0000000..ec7c334
--- /dev/null
+++ b/VCPP/doc/readme.txt
@@ -0,0 +1,131 @@
+
+Note: This code was built on WIndows XP using libdap 3.7.10 in Feb 2008 with
+only minor modifications to the VCPP/Makefile. 
+
+James Gallagher
+22 Feb 2008
+--------------------------
+
+These are the instructions that accompany each Windows release of the OPeNDAP
+Core Library known as "libdap".
+
+Introduction
+------------
+
+This is the 3.7.3 release of libdap for MS Windows XP (or later) on 32-bit
+machines.  It was built using Visual C++ 8.x.  Both static and dynamic
+versions of the Core libraries are provided.
+
+You must have the prerequisites for this distribution installed before
+installing this distribution.  The prerequisites are contained in the
+libdap-prerequisites3.7.3.zip file available from http://opendap.org.
+
+
+Purposes of this Distribution
+-----------------------------
+
+This distribution serves three purposes:
+
+1)  The Dynamic-link libraries necessary for running executables based
+    upon this version of libdap are provided.
+
+2)  The export libraries and the associated headers that are required
+    to OPeNDAP enable 3rd-party applications that are to be based upon this
+    specific version of libdap are provided.  Dynamic-link libraries necessary
+    to run such applications are also provided.  These are the tools that
+    experienced developers require to OPeNDAP-enable their applications.
+
+    The documentation that specifies the interface to the OPeNDAP Core Library
+    is not provided with this release.  With this distriubution, an experienced
+    developer should be able to link their software with libdap to OPeNDAP-enable
+    it.
+
+    See the 'sample' subdirectory for a makefile that details how to compile and
+    link.  Sample code is also provided.
+
+3)  Provides instructions for rebuilding this version of libdap from source
+    code.
+
+Contents
+--------
+
+  bin/       - Contains a basic OPeNDAP client "getdap"
+  dll/       - Provides the run-time dynamic link libraries
+  etc/       - Contains the 'deflate' program
+  include/   - Contains the headers necessary to compile
+  lib/       - Contains the libraries needed to link.  Both a static and
+               dynamic version of the OPeNDAP Core library (libdapMT.lib
+               and libdapMD.lib respectively) are provided.
+  sample/    - Contains sample code and a sample makefile
+  readme.txt - This readme file
+
+
+
+Installation Instruction
+------------------------
+
+   1)  Install the prerequisites outlined above
+
+   2)  Drag-n-drop the 'bin', 'dll', 'include', 'lib', 'etc' and 'sample' directories
+       found in this distriubution to C:\opendap.  If prompted to over write the
+       existing directory structure, choose 'Yes to all'.
+
+   3)  Place C:\opendap\bin and C:\opendap\dll on your execution path.
+
+   Test the Install:
+
+   1)  Open a DOS window
+
+   2)  Issue the following command
+
+       C:\> getdap --help
+
+       If the install is successful, you should see the usage message for the getdap
+       utility.
+
+
+
+Rebuilding from source code
+---------------------------
+
+
+  To Rebuild libdap 3.7.3 from source code using MS Visual C++ 8.x,
+  the subversion command-line utility and the installed prerequisite package
+  outlined above:
+  
+  1)  Add BISON_HAIRY environment var and set to C:\opendap\include\bison.hairy
+  2)  Add BISON_SIMPLE and set to C:\opendap\include\bison.simple
+  3)  Add INCLUDE environment variable if necessary and add following to it:
+
+         C:\opendap\include
+         C:\opendap\include\pthreads
+         C:\opendap\include\libxml
+         C:\opendap\include\curl
+
+  4)  Add LIB environment variable if necessary and add the following to it:
+
+         C:\opendap\lib
+
+  
+  Note: Microsoft provides a means of opening a command prompt where compiler
+  command-line tools can be conveniently executed.  Under Visual Studio,
+  this is available via the "Visual Studio 2005 Command Prompt" located
+  underneath the start->programs menu.  In Visual C++ 8.x an identical
+  mechanism is provided.  When we refer to a "command-line" window in the below
+  instructions, we are referring to this Microsoft-provided compiler command
+  prompt.  We are not referring to a simple DOS Command Prompt.
+
+  Open a command-line window and:
+
+  C:\> cd C:\opendap
+  C:\> svn co http://scm.opendap.org:8090/svn/tags/libdap/3.7.3 libdap3.7.3
+  C:\> cd libdap3.7.3\VCPP
+  C:\> nmake grammarclean
+  C:\> nmake all
+
+
+December 10, 2006
+Robert O. Morris
+
+
+
diff --git a/VCPP/dods-datatypes.h b/VCPP/dods-datatypes.h
new file mode 100644
index 0000000..333bdd9
--- /dev/null
+++ b/VCPP/dods-datatypes.h
@@ -0,0 +1,42 @@
+/*  This file is typically generated during configuation      */
+/*  time, but that is not the case under win32.  This file    */
+/*  was generated under linux on an x86 and then stripped     */
+/*  down to the bare essentials and modified where necessary  */
+/*  to form something appropriate for win32.                  */
+
+#ifndef __DODS_DATATYPES__
+#define __DODS_DATATYPES__
+
+#include <xdr.h>
+
+#define DINT32 long
+typedef DINT32 dods_int32;
+
+#define DUINT32 unsigned long
+typedef DUINT32 dods_uint32;
+
+#define XDR_INT32 xdr_long
+#define XDR_UINT32 xdr_u_long
+
+#define DINT16 short
+typedef DINT16 dods_int16;
+
+#define DUINT16 unsigned short
+typedef DUINT16 dods_uint16;
+
+#define XDR_INT16 xdr_short
+#define XDR_UINT16 xdr_u_short
+
+#define DBYTE unsigned char
+typedef DBYTE dods_byte;
+
+#define DFLOAT64 double
+typedef DFLOAT64 dods_float64;
+
+#define DFLOAT32 float
+typedef DFLOAT32 dods_float32;
+
+#define XDR_FLOAT64 xdr_double
+#define XDR_FLOAT32 xdr_float
+
+#endif /* __DODS_DATATYPES__ */
diff --git a/VCPP/libdap.iss b/VCPP/libdap.iss
new file mode 100644
index 0000000..dfe819a
--- /dev/null
+++ b/VCPP/libdap.iss
@@ -0,0 +1,53 @@
+;; This builds an installer for libdap - it assumes that you have the
+;; OPeNDAP Tools 1.0 (or later) package installed in the default location,
+;; that you have just built libdap from source and that the users of this
+;; installer are interested in a binary distribution of libdap and will
+;; build libdap itself.
+;;
+;; jhrg 24 April 2008
+
+[Setup]
+AppName=OPeNDAP libdap
+AppVerName=OPeNDAP libdap 3.8.2
+AppPublisher=OPeNDAP
+DefaultDirName={sd}\opendap
+DefaultGroupName=OPeNDAP libdap
+AllowNoIcons=yes
+InfoBeforeFile=BeforeInstall.txt
+OutputBaseFilename=libdap_3.8.2
+Compression=lzma/ultra
+SolidCompression=yes
+LicenseFile=License.txt
+AlwaysRestart=yes
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Files]
+;; This grabs the newly built libdap code _assuming_ that the libdap.iss file is run from within libdap/VCPP and
+;; that the 'nmake package' target has just been run.
+Source: "..\..\prepkg\opendap\libdap\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
+
+;; Put all of the DLLs in the opendap\bin directory - I have no idea why putting the DLLs in a \dll directory
+;; doesn't work, but on a non-development machine I set up it definitely does not work while putting them in
+;; the \bin directory does.
+Source: "..\..\prepkg\opendap\libdap\dll\*"; DestDir: "{app}\bin"; Flags: ignoreversion
+
+;; DLLs needed to run our code that are usually not part of win32. Developers should get the OPeNDAP-Tools dist
+;; too. I spilt this up because I figure developers can handle two installs and so that we can update the tools
+;; (bison, et c.) and libdap separately.
+Source: "C:\opendap-tools\dll\*"; DestDir: "{app}\bin"; Flags: ignoreversion
+
+;; These are the VC++ DLLs needed to actually run the code
+Source: "C:\Program Files\Microsoft Visual Studio 9.0\VC\redist\x86\*"; DestDir: "{app}\bin"; Flags: ignoreversion recursesubdirs createallsubdirs
+
+;; This somewhat inscrutable code sets the 'Path' environment variable so users can run getdap, et c.,
+;; in a shell (cmd.exe).
+[Registry]
+Root: HKLM; Subkey: "SYSTEM\CurrentControlSet\Control\Session Manager\Environment"; ValueType: string; ValueName: "Path"; ValueData: "{olddata};{app}\bin"
+
+[Icons]
+Name: "{group}\{cm:UninstallProgram,libdap 3.8.2}"; Filename: "{uninstallexe}"
+
+
+
diff --git a/VCPP/sample/Makefile b/VCPP/sample/Makefile
new file mode 100644
index 0000000..b12837e
--- /dev/null
+++ b/VCPP/sample/Makefile
@@ -0,0 +1,74 @@
+# Sample Makefile to illustrate how to compile and link with
+# libdap (under VC++ 8.x)
+
+OBJDIR		= .\objects
+SRCDIR		= .
+
+# Compiler, Linker
+CC		= cl
+LINK		= link
+
+# Setup compiler flags
+MTCFLAGS	= /MT
+MDCFLAGS	= /MD
+CFLAGS		= /nologo /W0 /GR /EHsc /c
+
+# Setup linker flags
+EMTLFLAGS	= /nologo /libpath:..\..\lib /NODEFAULTLIB:MSVCRT.lib
+EMDLFLAGS	= /nologo /libpath:..\..\lib
+
+# Setup link libraries
+EMTLLIBS	= libdapMT.lib libdapclientMT.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+EMDLLIBS	= libdapMD.lib libdapclientMD.lib libxml2.lib libcurl.lib zlib.lib libxdr.lib pthreadVC.lib
+
+# Setup compiler includes and defines
+INCS		= /I . /I ..\..\include /I ..\..\include\GNU /I ..\..\include\gl /I ..\..\include\xdr /I ..\..\include\curl /I ..\..\include\pthreads
+CPPUNITINCS	= $(INCS) /I $(INCLUDEDIR)/cppunit
+DEFS		= /D WIN32 /D WIN32_LEAN_AND_MEAN
+CPPFLAGS	= $(DEFS) $(INCS)
+
+default:
+	@echo "usage: nmake model<MT|MD>; nmake all"
+
+all:
+	nmake modelMT
+	nmake modelMD
+
+modelMT: setup
+	-md $(OBJDIR)\MT
+	nmake CFLAGS="$(CFLAGS) $(MTCFLAGS)" LFLAGS="$(EMTLFLAGS)" LIBS="$(EMTLLIBS)" OBJDIR=$(OBJDIR)\MT getdap
+
+modelMD: setup
+	-md $(OBJDIR)\MD
+	nmake CFLAGS="$(CFLAGS) $(MDCFLAGS)" LFLAGS="$(EMDLFLAGS)" LIBS="$(EMDLLIBS)" OBJDIR=$(OBJDIR)\MD getdap
+
+# Clear built-in rules and set new ones
+.SUFFIXES :
+.SUFFIXES :	.obj .cc .exe
+
+{$(SRCDIR)}.cc{$(OBJDIR)}.obj:
+	$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $<
+
+# Rule for linking executables.  See Microsoft's "mt" command for
+# embedding external .manifests as necessary.
+{$(OBJDIR)}.obj{$(OBJDIR)}.exe:
+	$(LINK) $(LFLAGS) /out:$@ $< $(LIBS)
+
+getdap:		$(OBJDIR)\getdap.exe
+
+$(OBJDIR)\getdap.exe: $(OBJDIR)\getdap.obj
+
+# Command-Line Client and select utils in console mode
+$(OBJDIR)\getdap.obj    : $(SRCDIR)\getdap.cc
+	$(CC) $(CFLAGS) $(CPPFLAGS) /Fo$@ /Tp $(SRCDIR)\getdap.cc
+
+setup:
+	-mkdir $(OBJDIR)
+
+clean:
+	-rmdir /Q /S $(OBJDIR)
+
+
+
+
+
diff --git a/VCPP/sample/getdap.cc b/VCPP/sample/getdap.cc
new file mode 100644
index 0000000..7e76391
--- /dev/null
+++ b/VCPP/sample/getdap.cc
@@ -0,0 +1,430 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// This is the source to `geturl'; a simple tool to exercise the Connect
+// class. It can be used to get naked URLs as well as the DAP2 DAS and DDS
+// objects.  jhrg.
+
+#define not_used
+
+static char rcsid[] not_used =
+    { "$Id: getdap.cc 15497 2007-01-07 11:05:13Z jimg $" };
+
+#include <stdio.h>
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#include <GetOpt.h>
+#include <string>
+
+#include "AISConnect.h"
+#include "Response.h"
+#include "StdinResponse.h"
+
+using std::cerr;
+using std::endl;
+
+const char *version = "$Revision: 15497 $";
+
+extern int dods_keep_temps;     // defined in HTTPResponse.h
+
+void usage(string name)
+{
+    cerr << "Usage: " << name << endl;
+    cerr <<
+        " [idDaxAVvks] [-B <db>][-c <expr>][-m <num>] <url> [<url> ...]" <<
+        endl;
+    cerr << " [Vvks] <file> [<file> ...]" << endl;
+    cerr << endl;
+    cerr << "In the first form of the command, dereference the URL and"
+        << endl;
+    cerr << "perform the requested operations. This includes routing" <<
+        endl;
+    cerr << "the returned information through the DAP processing" << endl;
+    cerr << "library (parsing the returned objects, et c.). If none" <<
+        endl;
+    cerr << "of a, d, or D are used with a URL, then the DAP library" <<
+        endl;
+    cerr << "routines are NOT used and the URLs contents are dumped" <<
+        endl;
+    cerr << "to standard output." << endl;
+    cerr << endl;
+    cerr << "In the second form of the command, assume the files are" <<
+        endl;
+    cerr << "DataDDS objects (stored in files or read from pipes)" << endl;
+    cerr << "and process them as if -D were given. In this case the" <<
+        endl;
+    cerr << "information *must* contain valid MIME header in order" <<
+        endl;
+    cerr << "to be processed." << endl;
+    cerr << endl;
+    cerr << "Options:" << endl;
+    cerr << "        i: For each URL, get the server version." << endl;
+    cerr << "        d: For each URL, get the the DDS." << endl;
+    cerr << "        a: For each URL, get the the DAS." << endl;
+    cerr << "        A: Use the AIS for DAS objects." << endl;
+    cerr << "        D: For each URL, get the the DataDDS." << endl;
+    cerr <<
+        "        x: For each URL, get the DDX object. Does not get data."
+        << endl;
+    cerr << "        B: <AIS xml dataBase>. Overrides .dodsrc." << endl;
+    cerr << "        v: Verbose." << endl;
+    cerr << "        V: Version." << endl;
+    cerr << "        c: <expr> is a contraint expression. Used with -D." <<
+        endl;
+    cerr << "           NB: You can use a `?' for the CE also." << endl;
+    cerr << "        k: Keep temporary files created by libdap core\n" <<
+        endl;
+    cerr << "        m: Request the same URL <num> times." << endl;
+    cerr << "        z: Ask the server to compress data." << endl;
+    cerr << "        s: Print Sequences using numbered rows." << endl;
+}
+
+bool read_data(FILE * fp)
+{
+    if (!fp) {
+        fprintf(stderr, "geturl: Whoa!!! Null stream pointer.\n");
+        return false;
+    }
+    // Changed from a loop that used getc() to one that uses fread(). getc()
+    // worked fine for transfers of text information, but *not* for binary
+    // transfers. fread() will handle both.
+    char c;
+    while (fp && !feof(fp) && fread(&c, 1, 1, fp))
+        printf("%c", c);        // stick with stdio 
+
+    return true;
+}
+
+static void print_data(DDS & dds, bool print_rows = false)
+{
+    fprintf(stdout, "The data:\n");
+
+    for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
+        BaseType *v = *i;
+        if (print_rows && (*i)->type() == dods_sequence_c)
+            dynamic_cast < Sequence * >(*i)->print_val_by_rows(stdout);
+        else
+            v->print_val(stdout);
+    }
+
+    fprintf(stdout, "\n");
+    fflush(stdout);
+}
+
+int main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, "idaDxAVvkB:c:m:zsh?");
+    int option_char;
+
+    bool get_das = false;
+    bool get_dds = false;
+    bool get_data = false;
+    bool get_ddx = false;
+    bool get_version = false;
+    bool cexpr = false;
+    bool verbose = false;
+    bool multi = false;
+    bool accept_deflate = false;
+    bool print_rows = false;
+    bool use_ais = false;
+    int times = 1;
+    string expr = "";
+    string ais_db = "";
+
+#ifdef WIN32
+    _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            get_dds = true;
+            break;
+        case 'a':
+            get_das = true;
+            break;
+        case 'D':
+            get_data = true;
+            break;
+        case 'x':
+            get_ddx = true;
+            break;
+        case 'A':
+            use_ais = true;
+            break;
+        case 'V':
+            fprintf(stderr, "geturl version: %s\n", version);
+            exit(0);
+        case 'i':
+            get_version = true;
+            break;
+        case 'v':
+            verbose = true;
+            break;
+        case 'k':
+            dods_keep_temps = 1;
+            break;              // keep_temp is in Connect.cc
+        case 'c':
+            cexpr = true;
+            expr = getopt.optarg;
+            break;
+        case 'm':
+            multi = true;
+            times = atoi(getopt.optarg);
+            break;
+        case 'B':
+            use_ais = true;
+            ais_db = getopt.optarg;
+            break;
+        case 'z':
+            accept_deflate = true;
+            break;
+        case 's':
+            print_rows = true;
+            break;
+        case 'h':
+        case '?':
+        default:
+            usage(argv[0]);
+            exit(1);
+            break;
+        }
+
+    try {
+        // If after processing all the command line options there is nothing
+        // left (no URL or file) assume that we should read from stdin.
+        for (int i = getopt.optind; i < argc; ++i) {
+            if (verbose)
+                fprintf(stderr, "Fetching: %s\n", argv[i]);
+
+            string name = argv[i];
+            Connect *url = 0;;
+            if (use_ais) {
+                if (!ais_db.empty())
+                    url = new AISConnect(name, ais_db);
+                else
+                    url = new AISConnect(name);
+            } else {
+                url = new Connect(name);
+            }
+
+            // This overrides the value set in the .dodsrc file.
+            if (accept_deflate)
+                url->set_accept_deflate(accept_deflate);
+
+            if (url->is_local()) {
+                if (verbose) {
+                    fprintf(stderr,
+"Assuming that the argument %s is a file that contains a DAP2 data object; decoding.\n", argv[i]);
+                }
+
+                Response *r = 0;
+                BaseTypeFactory factory;
+                DataDDS dds(&factory);
+
+                try {
+                    if (strcmp(argv[i], "-") == 0) {
+                        r = new StdinResponse(stdin);
+
+                        if (!r->get_stream())
+                            throw Error("Could not open standard input.");
+
+                        url->read_data(dds, r);
+                    } else {
+                        r = new Response(fopen(argv[i], "r"));
+
+                        if (!r->get_stream())
+                            throw Error(string("The input source: ")
+                                        + string(argv[i])
+                                        + string(" could not be opened"));
+
+                        url->read_data_no_mime(dds, r);
+                    }
+                }
+                catch(Error & e) {
+                    cerr << e.get_error_message() << endl;
+                    delete r;
+                    r = 0;
+                    delete url;
+                    url = 0;
+                    break;
+                }
+
+                if (verbose)
+                    fprintf(stderr, "Server version: %s\n",
+                            url->get_version().c_str());
+
+                print_data(dds, print_rows);
+
+            }
+
+            else if (get_version) {
+                fprintf(stderr, "Server version: %s\n",
+                        url->request_version().c_str());
+            }
+
+            else if (get_das) {
+                for (int j = 0; j < times; ++j) {
+                    DAS das;
+                    try {
+                        url->request_das(das);
+                    }
+                    catch(Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "Server version: %s\n",
+                                url->get_version().c_str());
+                        fprintf(stderr, "DAS:\n");
+                    }
+
+                    das.print(stdout);
+                }
+            }
+
+            else if (get_dds) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DDS dds(&factory);
+                    try {
+                        url->request_dds(dds);
+                    }
+                    catch(Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;       // Goto the next URL or exit the loop.
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "Server version: %s\n",
+                                url->get_version().c_str());
+                        fprintf(stderr, "DDS:\n");
+                    }
+
+                    dds.print(stdout);
+                }
+            }
+
+            else if (get_ddx) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DDS dds(&factory);
+                    try {
+                        url->request_dds(dds);
+                    }
+                    catch(Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        continue;       // Goto the next URL or exit the loop.
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "Server version: %s\n",
+                                url->get_version().c_str());
+                        fprintf(stderr, "DDS:\n");
+                    }
+
+                    dds.print_xml(stdout, false, "geturl; no blob yet");
+                }
+            }
+
+            else if (get_data) {
+                if (expr.empty() && name.find('?') == string::npos)
+                    expr = "";
+
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DataDDS dds(&factory);
+                    try {
+                        DBG(cerr << "URL: " << url->URL(false) << endl);
+                        DBG(cerr << "CE: " << expr << endl);
+                        url->request_data(dds, expr);
+
+                        if (verbose)
+                            fprintf(stderr, "Server version: %s\n",
+                                    url->get_version().c_str());
+
+                        print_data(dds, print_rows);
+                    }
+                    catch(Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;
+                    }
+                }
+            }
+
+            else {              // if (!get_das && !get_dds && !get_data)
+                // This code uses HTTPConnect::fetch_url which cannot be
+                // accessed using an instance of Connect. So some of the
+                // options supported by other URLs won't work here (e.g., the
+                // verbose option doesn't show the server version number).
+                HTTPConnect http(RCReader::instance());
+
+                // This overrides the value set in the .dodsrc file.
+                if (accept_deflate)
+                    http.set_accept_deflate(accept_deflate);
+
+                string url_string = argv[i];
+                for (int j = 0; j < times; ++j) {
+                    try {
+                        Response *r = http.fetch_url(url_string);
+                        if (!read_data(r->get_stream())) {
+                            continue;
+                        }
+                        delete r;
+                        r = 0;
+                    }
+                    catch(Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        continue;
+                    }
+                }
+            }
+
+            delete url;
+            url = 0;
+        }
+    }
+    catch(Error & e) {
+        cerr << e.get_error_message() << endl;
+    }
+
+    return 0;
+}
diff --git a/VCPP/unistd.h b/VCPP/unistd.h
new file mode 100644
index 0000000..4bc7657
--- /dev/null
+++ b/VCPP/unistd.h
@@ -0,0 +1,4 @@
+/* Dummy patch header to get win32 flex/bison generated */ 
+/* source code to compile under win32. If you see this */ 
+/* temp file, feel free to scratch it. */ 
+#include "io.h" 
diff --git a/VCPP/xdr-datatypes.h b/VCPP/xdr-datatypes.h
new file mode 100644
index 0000000..80a16e8
--- /dev/null
+++ b/VCPP/xdr-datatypes.h
@@ -0,0 +1,48 @@
+/* dods-datatypes.h.  Generated from dods-datatypes.h.in by configure.  */
+
+/*
+  Determine at compile-time the sizes of various datatypes. This uses symbols
+  defined by configure (See configure.in).
+  jhrg 10/24/94
+
+  This header is included by all of the DODS DAP library header files which
+  make use of the dods_* typedefs. C or C++ files can either include
+  config_dap.h, use their own configure script which defines SIZEOF_LONG,
+  _INT, _CHAR and _DOUBLE or set these preprocessor symbols themselves in a
+  Makefile, etc.
+
+  This used to be part of the config_dap.h header, but including that in the
+  DAP library headers introduced problems when the DAP was used in conjunction
+  with other libraries. 8/1/2000 jhrg
+*/
+
+#ifndef __XDR_DATATYPES__
+#define __XDR_DATATYPES__
+
+#ifdef WIN32
+#include <rpc.h>
+#include <winsock2.h>
+#include <xdr.h>
+#else
+#include <rpc/types.h>
+#include <netinet/in.h>
+#include <rpc/xdr.h>
+#endif
+
+/* The typedefs are done using a preprocessor symbol so that autoconf's
+   `CONFIG_HEADER' can be used. The configure script will then only modify
+   the dods-datatypes.h header when its contents change. This saves on
+   compilation since the header is used by many files in the dap++ library.
+   The downside is that the typedefs are so ugly... 2/14/2001 jhrg */
+
+#define XDR_INT32 xdr_long
+#define XDR_UINT32 xdr_u_long
+
+#define XDR_INT16 xdr_short
+#define XDR_UINT16 xdr_u_short
+
+#define XDR_FLOAT64 xdr_double
+#define XDR_FLOAT32 xdr_float
+
+#endif /* __XDR_DATATYPES__ */
+
diff --git a/Vector.cc b/Vector.cc
new file mode 100644
index 0000000..10bbc8c
--- /dev/null
+++ b/Vector.cc
@@ -0,0 +1,1648 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for class Vector. This class is the basis for all the
+// vector-type classes in libdap's <Array, List>.
+//
+// 11/21/95 jhrg
+
+#include "config.h"
+
+#include <cstring>
+
+static char rcsid[] not_used =
+    { "$Id: Vector.cc 24281 2011-03-09 00:22:31Z jimg $"
+    };
+
+//#define DODS_DEBUG
+
+#include <algorithm>
+
+#include "Vector.h"
+#include "escaping.h"
+#include "util.h"
+#include "debug.h"
+#include "InternalErr.h"
+#include <sstream>
+
+using std::cerr;
+using std::endl;
+
+namespace libdap {
+
+void Vector::_duplicate(const Vector & v)
+{
+    _length = v._length;
+
+    // _var holds the type of the elements. That is, it holds a BaseType
+    // which acts as a template for the type of each element.
+    if (v._var) {
+        _var = v._var->ptr_duplicate(); // use ptr_duplicate()
+        _var->set_parent(this); // ptr_duplicate does not set d_parent.
+    }
+    else {
+        _var = 0;
+    }
+
+    // _vec and _buf (further down) hold the values of the Vector. The field
+    // _vec is used when the Vector holds non-numeric data (including strings
+    // although it used to be that was not the case jhrg 2/10/05) while _buf
+    // holds numeric values.
+    if (v._vec.empty()) {
+        _vec = v._vec;
+    }
+    else {
+        // Failure to set the size will make the [] operator barf on the LHS
+        // of the assignment inside the loop.
+        _vec.resize(_length);
+        for (int i = 0; i < _length; ++i) {
+            // There's no need to call set_parent() for each element; we
+            // maintain the back pointer using the _var member. These
+            // instances are used to hold _values_ only while the _var
+            // field holds the type of the elements.
+            _vec[i] = v._vec[i]->ptr_duplicate();
+        }
+    }
+
+    // copy the strings. This copies the values.
+    d_str = v.d_str;
+
+    // copy numeric values if there are any.
+    _buf = 0;                   // init to null
+    if (v._buf)                 // only copy if data present
+        val2buf(v._buf);        // store v's value in this's _BUF.
+
+    _capacity = v._capacity;
+}
+
+/**
+ * @return whether the type of this Vector is a cardinal type
+ * (ie stored in _buf)
+ */
+bool
+Vector::is_cardinal_type() const
+{
+  // Not cardinal if no _var at all!
+  if (!_var) {
+    return false;
+  }
+
+  switch (_var->type()) {
+     case dods_byte_c:
+     case dods_int16_c:
+     case dods_uint16_c:
+     case dods_int32_c:
+     case dods_uint32_c:
+     case dods_float32_c:
+     case dods_float64_c: {
+       return true;
+       break;
+     }
+
+     // These must be handled differently.
+     case dods_str_c:
+     case dods_url_c:
+     case dods_array_c:
+     case dods_structure_c:
+     case dods_sequence_c:
+     case dods_grid_c:
+       return false;
+       break;
+
+     default:
+       cerr << "Vector::var: Unrecognized type" << endl;
+       return false;
+  } // switch
+}
+
+/**
+ * Create _buf so that it can store numElts of the
+ * (assumed) cardinal type.  This create storage for
+ * width() * numElts bytes.
+ * If _buf already exists, this DELETES IT and creates a new one.
+ * So don't use this if you want to keep the original _buf data around.
+ * This also sets the valueCapacity().
+ * @param numEltsOfType the number of elements of the cardinal type in var()
+                  that we want storage for.
+ * @return the size of the buffer created.
+ * @exception if the Vector's type is not cardinal type.
+ */
+unsigned int
+Vector::create_cardinal_data_buffer_for_type(unsigned int numEltsOfType)
+{
+  // Make sure we HAVE a _var, or we cannot continue.
+  if (!_var) {
+    throw InternalErr(__FILE__, __LINE__,
+        "create_cardinal_data_buffer_for_type: Logic error: _var is null!");
+  }
+
+  // Make sure we only do this for the correct data types.
+  if (!is_cardinal_type()) {
+      throw InternalErr(__FILE__, __LINE__,
+          "create_cardinal_data_buffer_for_type: incorrectly used on Vector whose type was not a cardinal (simple data types).");
+  }
+
+  delete_cardinal_data_buffer();
+
+  // Actually new up the array with enough bytes to hold numEltsOfType of the actual type.
+  unsigned int bytesPerElt = _var->width();
+  unsigned int bytesNeeded = bytesPerElt * numEltsOfType;
+  _buf = new char[bytesNeeded];
+  if (!_buf) {
+    ostringstream oss;
+    oss << "create_cardinal_data_buffer_for_type: new char[] failed to allocate " <<
+           bytesNeeded <<
+           " bytes!  Out of memory or too large a buffer required!";
+    throw InternalErr(__FILE__, __LINE__, oss.str());
+  }
+  _capacity = numEltsOfType;
+  return bytesNeeded;
+}
+
+/** Delete _buf and zero it and _capacity out */
+void
+Vector::delete_cardinal_data_buffer()
+{
+  if (_buf) {
+     delete[] _buf;
+     _buf = 0;
+     _capacity = 0;
+   }
+}
+
+/** Helper to reduce cut and paste in the virtual's.
+ *
+ */
+template <class CardType>
+void
+Vector::set_cardinal_values_internal(const CardType* fromArray, int numElts)
+{
+  if (numElts < 0) {
+     throw InternalErr(__FILE__, __LINE__,
+                 "Logic error: Vector::set_cardinal_values_internal() called with negative numElts!");
+  }
+  if (!fromArray) {
+    throw InternalErr(__FILE__, __LINE__,
+        "Logic error: Vector::set_cardinal_values_internal() called with null fromArray!");
+  }
+  set_length(numElts);
+  create_cardinal_data_buffer_for_type(numElts);
+  memcpy(_buf, fromArray, numElts * sizeof(CardType) );
+  set_read_p(true);
+}
+
+
+/** The Vector constructor requires the name of the variable to be
+    created, and a pointer to an object of the type the Vector is to
+    hold.  The name may be omitted, which will create a nameless
+    variable.  The template object may not be omitted.
+
+    @param n A string containing the name of the variable to be
+    created.
+    @param v A pointer to a variable of the type to be included
+    in the Vector.
+    @param t The type of the resulting Vector object, from the Type
+    enum list.  There is no DAP2 Vector object, so all uses of this
+    method will be from the List or Array classes.  This defaults to
+    <tt>dods_null_c</tt>.
+
+    @see Type
+    @brief The Vector constructor.  */
+Vector::Vector(const string & n, BaseType * v, const Type & t)
+        : BaseType(n, t), _length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
+{
+    if (v)
+        add_var(v);
+
+    DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
+    if (_var)
+        _var->set_parent(this);
+}
+
+/** The Vector server-side constructor requires the name of the variable
+    to be created, the dataset name from which this Vector is created, and
+    a pointer to an object of the type the Vector is to hold.  The
+    name may be omitted, which will create a nameless variable.
+    The template object may not be omitted.
+
+    @param n A string containing the name of the variable to be
+    created.
+    @param d A string containing the dataset name from which the variable is
+    being created.
+    @param v A pointer to a variable of the type to be included
+    in the Vector.
+    @param t The type of the resulting Vector object, from the Type
+    enum list.  There is no DAP2 Vector object, so all uses of this
+    method will be from the List or Array classes.  This defaults to
+    <tt>dods_null_c</tt>.
+
+    @see Type
+    @brief The Vector constructor.  */
+Vector::Vector(const string & n, const string &d, BaseType * v, const Type & t)
+        : BaseType(n, d, t), _length(-1), _var(0), _buf(0), _vec(0), _capacity(0)
+{
+    if (v)
+        add_var(v);
+
+    DBG2(cerr << "Entering Vector ctor for object: " << this << endl);
+    if (_var)
+        _var->set_parent(this);
+}
+
+/** The Vector copy constructor. */
+Vector::Vector(const Vector & rhs): BaseType(rhs)
+{
+    DBG2(cerr << "Entering Vector const ctor for object: " << this <<
+         endl);
+    DBG2(cerr << "RHS: " << &rhs << endl);
+
+    _duplicate(rhs);
+}
+
+Vector::~Vector()
+{
+    DBG2(cerr << "Entering ~Vector (" << this << ")" << endl);
+
+    delete _var;
+    _var = 0;
+
+    // Clears all buffers
+    clear_local_data();
+
+    DBG2(cerr << "Exiting ~Vector" << endl);
+}
+
+Vector & Vector::operator=(const Vector & rhs)
+{
+    if (this == &rhs)
+        return *this;
+
+    dynamic_cast < BaseType & >(*this) = rhs;
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+void
+Vector::set_name(const std::string& name)
+{
+  BaseType::set_name(name);
+  // We need to set the template variable name as well since
+  // this is what gets output in the dds!  Otherwise, there's a mismatch.
+  if (_var) {
+      _var->set_name(name);
+  }
+}
+
+int Vector::element_count(bool leaves)
+{
+    if (!leaves)
+        return 1;
+    else
+        // var() only works for simple types!
+        return var(0)->element_count(leaves);
+}
+
+// These mfuncs set the _send_p and _read_p fields of BaseType. They differ
+// from BaseType's version in that they set both the Vector object's copy of
+// _send_p (_read_p) but also _VAR's copy. This does not matter much when _VAR
+// is a scalar, but does matter when it is an aggregate.
+
+/** This function sets the <tt>send_p</tt> flag for both the Vector itself
+    and its element template.  This does not matter much when the
+    Vector contains simple data types, but does become significant
+    when the Vector contains compound types.
+
+    @brief Indicates that the data is ready to send. */
+void Vector::set_send_p(bool state)
+{
+    _var->set_send_p(state);
+    BaseType::set_send_p(state);
+}
+
+/** This function sets the <tt>read_p</tt> flag for both the Vector itself
+    and its element template.  This does not matter much when the
+    Vector contains simple data types, but does become significant
+    when the Vector contains compound types.
+
+    @brief Indicates that the data is ready to send.  */
+void Vector::set_read_p(bool state)
+{
+    if (_var) {
+      _var->set_read_p(state);
+    }
+    BaseType::set_read_p(state);
+}
+
+/** Returns a copy of the template array element. If the Vector contains
+    simple data types, the template will contain the value of the last
+    vector element accessed with the <code>Vector::var(int i)</code> function,
+    if any. If no such access has been made, or if the Vector contains
+    compound data types, the value held by the template instance is
+    undefined.
+
+    Note that the parameter <i>exact_match</i> is not used by this mfunc.
+
+    @param n The name of the variable to find.
+    @param exact Unused.
+    @param s Pointer to a BaseType Pointer Stack. Use this stack to record
+    the path to the variable. By default this pointer is null, in which case
+    it is not used.
+
+    @return A pointer to the BaseType if found, otherwise null.
+    @see Vector::var */
+BaseType *Vector::var(const string & n, bool exact, btp_stack * s)
+{
+    string name = www2id(n);
+    DBG(cerr << "Vector::var: Looking for " << n << endl);
+
+    // Make sure to check for the case where name is the default (the empty
+    // string). 9/1/98 jhrg
+    if (_var->is_constructor_type()) {
+        if (name == "" || _var->name() == name) {
+            if (s)
+                s->push(this);
+            return _var;
+        }
+        else {
+            BaseType * result = _var->var(name, exact, s);
+            if (result && s)
+                s->push(this);
+            return result;
+        }
+    }
+    else {
+        return _var; // I don't see why this isn't return 0 *** jhrg 10/9/08
+    }
+}
+
+/** This version of var(...) searches for <i>name</i> and returns a
+    pointer to the BaseType object if found. It uses the same search
+    algorithm as above when <i>exact_match</i> is false. In addition to
+    returning a pointer to the variable, it pushes onto <i>s</i> a
+    BaseType pointer to each constructor type that ultimately contains
+    <i>name</i>.
+
+    @param n Find the variable whose name is <i>name</i>.
+    @param s Record the path to <i>name</i>.
+    @return A pointer to the named variable. */
+BaseType *Vector::var(const string & n, btp_stack & s)
+{
+    string name = www2id(n);
+
+    if (_var->is_constructor_type())
+        return _var->var(name, s);
+    else {
+        s.push((BaseType *) this);
+        return _var;
+    }
+}
+
+// Return a pointer the the BaseType object for element I. If the Vector is
+// of a cardinal type, store the ith element's value in the BaseType
+// object. If it is a Vector of a non-cardinal type, then this mfunc returns
+// _vec[i].
+//
+// NB: I defaults to zero.
+//
+// Returns: A BaseType pointer to the ith element of the Vector.
+
+/** Returns a pointer to the specified Vector element.  The return
+    pointer will reference the element itself, so multiple calls to this
+    method should save each value before making the next call.
+
+    @todo Is this method thread safe? If 'apartment threading' is used, I
+    think so. But if the library is running in more than one thread, then
+    this is not thread safe.
+
+    @param i The index of the desired Vector element.  Zero
+    indicates the first element of the Vector.
+    @return A pointer to a BaseType class instance containing
+    the value of the indicated element. The BaseType pointer is locally
+    maintained and should not be deleted or referenced. Extract the value
+    right after the method returns.
+    @see BaseType::var */
+BaseType *Vector::var(unsigned int i)
+{
+
+    switch (_var->type()) {
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c: {
+            // Transfer the ith value to the BaseType *_var; There are more
+            // efficient ways to get a whole array using buf2val() but this is
+            // an OK way to get a single value or several non-contiguous values.
+            unsigned int sz = _var->width();
+            _var->val2buf((char *) _buf + (i * sz));
+            return _var;
+            break;
+        }
+
+    case dods_str_c:
+    case dods_url_c:
+        _var->val2buf(&d_str[i]);
+        return _var;
+        break;
+
+    case dods_array_c:
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+        return _vec[i];
+        break;
+
+    default:
+        cerr << "Vector::var: Unrecognized type" << endl;
+    }
+
+    return 0;
+}
+
+// Return: The number of bytes required to store the vector `in a C
+// program'. For an array of cardinal types this is the same as the storage
+// used by _BUF. For anything else, it is the product of length() and the
+// element width(). It turns out that both values can be computed the same
+// way.
+//
+// Returns: The number of bytes used to store the vector.
+
+/** Returns the number of bytes needed to hold the <i>entire</i>
+    array.  This is equal to <tt>length()</tt> times the width of each
+    element.
+
+    @brief Returns the width of the data, in bytes. */
+unsigned int Vector::width()
+{
+    // Jose Garcia
+    if (!_var) {
+        throw InternalErr(__FILE__, __LINE__,
+                          "Cannot get width since *this* object is not holding data.");
+    }
+
+    return length() * _var->width();
+}
+
+// Returns: the number of elements in the vector.
+
+/** Returns the number of elements in the vector. Note that some
+    child classes of Vector use the length of -1 as a flag value.
+
+    @see Vector::append_dim */
+int Vector::length() const
+{
+    return _length;
+}
+
+// set the number of elements in the vector.
+//
+// Returns: void
+
+/** Sets the length of the vector.  This function does not allocate
+any new space. */
+void Vector::set_length(int l)
+{
+    _length = l;
+}
+
+// \e l is the number of elements the vector can hold (e.g., if l == 20, then
+// the vector can hold elements 0, .., 19).
+
+/** Resizes a Vector.  If the input length is greater than the
+    current length of the Vector, new memory is allocated (the
+    Vector moved if necessary), and the new entries are appended to
+    the end of the array and padded with Null values.  If the input
+    length is shorter, the tail values are discarded. */
+void Vector::vec_resize(int l)
+{
+    _vec.resize((l > 0) ? l : 0, 0);    // Fill with NULLs
+    _capacity = l; // capacity in terms of number of elements.
+}
+
+/** @brief read data into a variable for later use
+
+    Most uses of a variable are to either serialize its data to a stream of
+    some sort or to read values from some stream and intern those in the
+    variable for later use. These operations are perform by serialize()
+    and deserialize() which follow. This function performs essentially both
+    of these operations without actually using a stream device. The data are
+    read using the read() method(s) and loaded into the variables directly.
+
+    This method is intended to be used by objects which transform DAP objects
+    like the DataDDS into an ASCII CSV representation.
+
+    the data source.
+    @param eval A reference to a constraint evaluator
+    @param dds The complete DDS to which this variable belongs */
+void
+Vector::intern_data(ConstraintEvaluator &eval, DDS &dds)
+{
+    DBG(cerr << "Vector::intern_data: " << name() << endl);
+    if (!read_p())
+        read();          // read() throws Error and InternalErr
+
+    // length() is not capacity; it must be set explicitly in read().
+    int num = length();
+
+    switch (_var->type()) {
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+        // For these cases, read() puts the data into _buf, which is what we
+        // need to do 'stuff' with the data.
+        break;
+
+    case dods_str_c:
+    case dods_url_c:
+        // For these cases, read() will put the data into d_str[], which is
+        // what the transformation classes need.
+        break;
+
+    case dods_array_c:
+        // I think this is an error since there can never be an Array of
+        // Array.
+        throw InternalErr(__FILE__, __LINE__, "Array of Array not supported.");
+        break;
+
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+        DBG(cerr << "Vector::intern_data: found ctor" << endl);
+        // For these cases, we need to call read() for each of the 'num'
+        // elements in the '_vec[]' array of BaseType object pointers.
+        if (_vec.capacity() == 0)
+            throw InternalErr(__FILE__, __LINE__,
+                              "The capacity of *this* vector is 0.");
+
+        for (int i = 0; i < num; ++i)
+            _vec[i]->intern_data(eval, dds);
+
+        break;
+
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
+        break;
+    }
+}
+
+/** @brief Serialize a Vector.
+
+    This uses the Marshaler class to encode each element of a cardinal
+    array. For Arrays of Str and Url types, send the element count over
+    as a prefix to the data so that deserialize will know how many elements
+    to read.
+
+    NB: Arrays of cardinal types must already be in BUF (in the local machine's
+    representation) <i>before</i> this call is made.
+*/
+
+
+bool Vector::serialize(ConstraintEvaluator & eval, DDS & dds,
+		       Marshaller &m, bool ce_eval)
+{
+    int i = 0;
+
+    dds.timeout_on();
+
+    if (!read_p())
+        read();          // read() throws Error and InternalErr
+
+#if EVAL
+    if (ce_eval && !eval.eval_selection(dds, dataset()))
+        return true;
+#endif
+
+    dds.timeout_off();
+
+    // length() is not capacity; it must be set explicitly in read().
+    int num = length();
+
+    switch (_var->type()) {
+    case dods_byte_c:
+	m.put_vector( _buf, num, *this ) ;
+	break ;
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+	m.put_vector( _buf, num, _var->width(), *this ) ;
+        break;
+
+    case dods_str_c:
+    case dods_url_c:
+        if (d_str.capacity() == 0)
+            throw InternalErr(__FILE__, __LINE__,
+                              "The capacity of the string vector is 0");
+
+	m.put_int( num ) ;
+
+        for (i = 0; i < num; ++i)
+	    m.put_str( d_str[i] ) ;
+
+        break;
+
+    case dods_array_c:
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+        //Jose Garcia
+        // Not setting the capacity of _vec is an internal error.
+        if (_vec.capacity() == 0)
+            throw InternalErr(__FILE__, __LINE__,
+                              "The capacity of *this* vector is 0.");
+
+	m.put_int( num ) ;
+
+        for (i = 0; i < num; ++i)
+            _vec[i]->serialize(eval, dds, m, false);
+
+        break;
+
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Unknown datatype.");
+        break;
+    }
+
+    return true;
+}
+
+// Read an object from the network and internalize it. For a Vector this is
+// handled differently for a `cardinal' type. Vectors of Cardinals are
+// stored using the `C' representations because these objects often are used
+// to build huge arrays (e.g., an array of 1024 by 1024 bytes). However,
+// arrays of non-cardinal types are stored as Vectors of the C++ objects or
+// DAP2 objects (Str and Url are vectors of the string class, Structure, ...,
+// Grid are vectors of the libdap Structure, ... classes).
+//
+// The boolean parameter REUSE determines whether internal storage is reused
+// or not. If true, the _buf member is assumed to be large enough to hold the
+// incoming cardinal data and is *not* reallocated. If false, new storage is
+// allocated. If the internal buffer has not yet been allocated, then this
+// parameter has no effect (i.e., storage is allocated). This parameter
+// effects storage for cardinal data only.
+//
+// Returns: True is successful, false otherwise.
+
+bool Vector::deserialize(UnMarshaller &um, DDS * dds, bool reuse)
+{
+    unsigned int num;
+    unsigned i = 0;
+
+    switch (_var->type()) {
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+        if (_buf && !reuse) {
+            delete_cardinal_data_buffer();
+        }
+
+	um.get_int( (int &)num ) ;
+
+        DBG(cerr << "Vector::deserialize: num = " << num << endl);
+        DBG(cerr << "Vector::deserialize: length = " << length() << endl);
+
+        if (length() == -1)
+            set_length(num);
+
+        if (num != (unsigned int) length())
+            throw InternalErr(__FILE__, __LINE__, "The server sent declarations and data with mismatched sizes.");
+
+        if (!_buf) {
+            // Make _buf be large enough for length() elements of _var->type()
+            create_cardinal_data_buffer_for_type(length());
+            DBG(cerr << "Vector::deserialize: allocating "
+                << width() << " bytes for an array of "
+                << length() << " " << _var->type_name() << endl);
+        }
+
+        if (_var->type() == dods_byte_c)
+	    um.get_vector( (char **)&_buf, num, *this ) ;
+        else
+	    um.get_vector( (char **)&_buf, num, _var->width(), *this ) ;
+
+        DBG(cerr << "Vector::deserialize: read " << num << " elements\n");
+
+        break;
+
+    case dods_str_c:
+    case dods_url_c:
+	um.get_int( (int &)num ) ;
+
+        if (length() == -1)
+            set_length(num);
+
+        if (num != (unsigned int) length())
+            throw InternalErr(__FILE__, __LINE__,
+                              "The client sent declarations and data with mismatched sizes.");
+
+        d_str.resize((num > 0) ? num : 0);      // Fill with NULLs
+        _capacity = num; // capacity is number of strings we can fit.
+
+        for (i = 0; i < num; ++i) {
+            string str;
+	    um.get_str( str ) ;
+            d_str[i] = str;
+
+        }
+
+        break;
+
+    case dods_array_c:
+    case dods_structure_c:
+    case dods_sequence_c:
+    case dods_grid_c:
+	um.get_int( (int &)num ) ;
+
+        if (length() == -1)
+            set_length(num);
+
+        if (num != (unsigned int) length())
+            throw InternalErr(__FILE__, __LINE__, "The client sent declarations and data with mismatched sizes.");
+
+        vec_resize(num);
+
+        for (i = 0; i < num; ++i) {
+            _vec[i] = _var->ptr_duplicate();
+            _vec[i]->deserialize(um, dds);
+        }
+
+        break;
+
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Unknown type!");
+        break;
+    }
+
+    return false;
+}
+
+/** Copies data into the class instance buffer.  This function
+    assumes that the input \e val points to memory which
+    contains, in row major order, enough elements of the correct
+    type to fill the array. For an array of a cardinal type the
+    memory is simply copied in whole into the Vector buffer.
+
+    If the variable has already been constrained, this method will load only
+    number of values/bytes specified by that constraint and will load them
+    into the 'front' of the object's internal buffer. This is where serialize()
+    expects to find the data.
+
+    For a Vector of Str (OPeNDAP Strings), this assumes \e val points to an
+    array of C++ strings.
+
+    This method should not be used for Structure, Sequence or Grid.
+
+    @brief Reads data into the Vector buffer.
+    @exception InternalErr Thrown if called for Structure, Sequence or
+    Grid.
+    @return The number of bytes used by the array.
+    @param val A pointer to the input data.
+    @param reuse A boolean value, indicating whether the class
+    internal data storage can be reused or not.  If this argument is
+    TRUE, the class buffer is assumed to be large enough to hold the
+    incoming data, and it is <i>not</i> reallocated.  If FALSE, new
+    storage is allocated.  If the internal buffer has not been
+    allocated at all, this argument has no effect. */
+unsigned int Vector::val2buf(void *val, bool reuse)
+{
+    // Jose Garcia
+
+    // I *think* this method has been mainly designed to be use by read which
+    // is implemented in the surrogate library. Passing NULL as a pointer to
+    // this method will be an error of the creator of the surrogate library.
+    // Even though I recognize the fact that some methods inside libdap++ can
+    // call val2buf, I think by now no coding bugs such as misusing val2buf
+    // will be in libdap++, so it will be an internal error from the
+    // surrogate library.
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "The incoming pointer does not contain any data.");
+
+    switch (_var->type()) {
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c: {
+            // width() returns the size given the constraint
+            unsigned int array_wid = width();
+            if (_buf && !reuse) {
+               delete_cardinal_data_buffer();
+            }
+
+            if (!_buf) {        // First time or no reuse (free'd above)
+              create_cardinal_data_buffer_for_type(length());
+            }
+
+            memcpy(_buf, val, array_wid);
+            break;
+        }
+
+    case dods_str_c:
+    case dods_url_c: {
+            // Assume val points to an array of C++ string objects. Copy
+            // them into the vector<string> field of this object.
+            d_str.resize(_length);
+            _capacity = _length;
+            for (int i = 0; i < _length; ++i)
+                d_str[i] = *(static_cast < string * >(val) + i);
+
+            break;
+        }
+
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Vector::val2buf: bad type");
+
+    }
+
+    return width();
+}
+
+/** Copies data from the Vector buffer.  This function assumes that
+    <i>val</i> points to an array large enough to hold N instances of
+    the `C' representation of the \e numeric element type or C++ string
+    objects. Never call this method for constructor types Structure,
+    Sequence or Grid.
+
+    When reading data out of a variable that has been constrained, this method
+    assumes the N values/bytes of constrained data start at the beginning
+    of the object's internal buffer. For example, do not load an entire
+    Vector's data using val2buf(), constrain and then use this method to
+    get the data. Unless your constraint starts with the [0]th element, the
+    result will not be the correct values.
+
+    In the case of a Vector of Str objects, this method will return an array
+    of C++ std::string objects.
+
+    @note It's best to define the pointer to reference the data as
+    'char *data' and then call this method using '..->buf2val((void**)&data)'.
+    Then free the storage once you're done using 'delete[] data'. It's not
+    correct C++ to use 'delete[]' on a void pointer and the allocated memory
+    \e is an array of char, so 'delete[]' is needed.
+
+    @return The number of bytes used to store the array.
+    @param val A pointer to a pointer to the memory into which the
+    class data will be copied.  If the value pointed to is NULL,
+    memory will be allocated to hold the data, and the pointer value
+    modified accordingly.  The calling program is responsible for
+    deallocating the memory indicated by this pointer.
+    @exception InternalErr Thrown if \e val is null.
+    @see Vector::set_vec */
+unsigned int Vector::buf2val(void **val)
+{
+    // Jose Garcia
+    // The same comment in Vector::val2buf applies here!
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__, "NULL pointer.");
+
+    unsigned int wid = static_cast<unsigned int>(width());
+    // This is the width computed using length(). The
+    // length() property is changed when a projection
+    // constraint is applied. Thus this is the number of
+    // bytes in the buffer given the current constraint.
+
+    switch (_var->type()) {
+    case dods_byte_c:
+    case dods_int16_c:
+    case dods_uint16_c:
+    case dods_int32_c:
+    case dods_uint32_c:
+    case dods_float32_c:
+    case dods_float64_c:
+        if (!*val) {
+            *val = new char[wid];
+        }
+        // avoid bus error if _buf is null and this is called improperly.
+        if (!_buf) {
+          throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: Logic error: called when _buf was null!");
+        }
+
+        (void) memcpy(*val, _buf, wid);
+
+        break;
+
+    case dods_str_c:
+    case dods_url_c: {
+            if (!*val)
+                *val = new string[_length];
+
+            for (int i = 0; i < _length; ++i)
+                *(static_cast < string * >(*val) + i) = d_str[i];
+
+            break;
+        }
+
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Vector::buf2val: bad type");
+        return 0;
+    }
+
+    return wid;
+}
+
+/** Sets an element of the vector to a given value.  If the type of
+    the input and the type of the Vector do not match, an error
+    condition is returned.
+
+    Use this function only with Vectors containing compound DAP2
+    types.  See <tt>buf2val()</tt> to access members of Vectors containing
+    simple types.
+
+    @note This method copies \e val; the caller is responsible for deleting
+    instance passed as the actual parameter.
+
+    @brief Sets element <i>i</i> to value <i>val</i>.
+    @return void
+    @exception InternalErr Thrown if \e i is out of range, \e val is null or
+    there was a type mismatch between the BaseType referenced by \e val and
+    the \e ith element of this Vector.
+    @param i The index of the element to be changed.
+    @param val A pointer to the value to be inserted into the
+    array.
+    @see Vector::buf2val */
+void Vector::set_vec(unsigned int i, BaseType * val)
+{
+    // Jose Garcia
+    // This is a public method which allows users to set the elements
+    // of *this* vector. Passing an invalid index, a NULL pointer or
+    // mismatching the vector type are internal errors.
+    if (i >= static_cast < unsigned int >(_length))
+        throw InternalErr(__FILE__, __LINE__,
+                          "Invalid data: index too large.");
+    if (!val)
+        throw InternalErr(__FILE__, __LINE__,
+                          "Invalid data: null pointer to BaseType object.");
+    if (val->type() != _var->type())
+        throw InternalErr(__FILE__, __LINE__,
+                          "invalid data: type of incoming object does not match *this* vector type.");
+
+    if (i >= _vec.capacity())
+        vec_resize(i + 10);
+
+    _vec[i] = val->ptr_duplicate();
+}
+
+/**
+ * Remove any read or set data in the private data of this Vector,
+ * setting read_p() to false.
+ * Essentially clears the _buf, d_str, and _vec of any data.
+ * Useful for tightening up memory when the data is no longer needed,
+ * but the object cannot yet be destroyed.
+ * NOTE: this is not virtual, and only affects the data in Vector itself!
+ * On exit: get_value_capacity() == 0 && !read_p()
+ */
+void
+Vector::clear_local_data()
+{
+  if (_buf) {
+    delete[]_buf;
+    _buf = 0;
+  }
+
+  for (unsigned int i = 0; i < _vec.size(); ++i) {
+    delete _vec[i];
+    _vec[i] = 0;
+  }
+
+  // Force memory to be reclaimed.
+  _vec.resize(0);
+  d_str.resize(0);
+
+  _capacity = 0;
+  set_read_p(false);
+}
+
+
+/**
+ * Return the capacity of the Vector in terms of number of
+ * elements of its data type that it CAN currently hold (i.e. not bytes).
+ * For example, this could be
+ * the size of the _buf array in bytes / sizeof(T) for the cardinal
+ * types T, or the capacity of the d_str vector if T is string or url type.
+*/
+unsigned int
+Vector::get_value_capacity() const
+{
+  return _capacity;
+}
+
+
+/**
+ * Allocate enough memory for the Vector to contain
+ * numElements data elements of the Vector's type.
+ * Must be used before set_value_slice_from_row_major_vector
+ * to ensure memory exists.
+ * @param numElements  the number of elements of the Vector's type
+ *                     to preallocate storage for.
+ * @exception if the memory cannot be allocated
+ */
+void
+Vector::reserve_value_capacity(unsigned int numElements)
+{
+  if (!_var) {
+   throw InternalErr(__FILE__, __LINE__,
+       "reserve_value_capacity: Logic error: _var is null!");
+  }
+  switch (_var->type()) {
+     case dods_byte_c:
+     case dods_int16_c:
+     case dods_uint16_c:
+     case dods_int32_c:
+     case dods_uint32_c:
+     case dods_float32_c:
+     case dods_float64_c: {
+         // Make _buf be the right size and set _capacity
+         create_cardinal_data_buffer_for_type(numElements);
+       }
+       break;
+
+     case dods_str_c:
+     case dods_url_c: {
+         // Make sure the d_str has enough room for all the strings.
+         // Technically not needed, but it will speed things up for large arrays.
+         d_str.reserve(numElements);
+         _capacity = numElements;
+       }
+       break;
+
+
+     case dods_array_c:
+     case dods_structure_c:
+     case dods_sequence_c:
+     case dods_grid_c: {
+         // not clear anyone will go this path, but best to be complete.
+         _vec.reserve(numElements);
+         _capacity = numElements;
+       }
+      break;
+
+     default: {
+         throw InternalErr(__FILE__, __LINE__, "reserve_value_capacity: Unknown type!");
+       }
+     break;
+
+  } // switch
+
+}
+
+/**
+ * Make sure there's storage allocated for the current length()
+ * of the Vector.
+ * Same as reserveValueCapacity(length())
+ */
+void
+Vector::reserve_value_capacity()
+{
+  // Use the current length of the vector as the reserve amount.
+  reserve_value_capacity(length());
+}
+
+/**
+ * Copy rowMajorData.length() elements currently in a rowMajorData buffer
+ * into this value buffer starting at element index startElement and
+ * continuing up to startElement+rowMajorData.length()-1
+ *
+ * This is used for aggregating together smaller rowMajor vectors
+ * into a larger one.
+ *
+ * Note: unlike the other set_value calls, this does NOT set read_p()
+ *       since it is assumed to be used as a partial read and the caller
+ *       is expected to set_read_p() when the data is complete.
+ *
+ * ASSUMES: rowMajorData.read_p() so that the data is valid!
+ * ASSUMES: this Vector has enough value_capacity() to contain
+ *          all the elements such that:
+ *          startElement + rowMajorData.length()
+ *          <= this->value_capacity().
+ * ASSUMES: the data type of this->var() and rowMajorData.var()
+ *          MUST be non-NULL and be the same!
+ *
+ * @param rowMajorDataC the vector from which to copy data,
+ *                     assumed already read in or set.
+ * @param startElement the element index
+ *                     (NOT byte, but rather data type element)
+ *                     to place the first data value.
+ * @return the number of elements added, such that:
+ *         startElement + the return value is the next "free" element.
+ */
+unsigned int
+Vector::set_value_slice_from_row_major_vector(const Vector& rowMajorDataC, unsigned int startElement)
+{
+  static const string funcName = "set_value_slice_from_row_major_vector:";
+
+  // semantically const from the caller's viewpoint, but some calls are not syntactic const.
+  Vector& rowMajorData = const_cast<Vector&>(rowMajorDataC);
+
+  bool typesMatch = rowMajorData.var() && _var && (rowMajorData.var()->type() == _var->type());
+  if (!typesMatch) {
+    throw InternalErr(__FILE__, __LINE__,
+        funcName + "Logic error: types do not match so cannot be copied!");
+  }
+
+  // Make sure the data exists
+  if (!rowMajorData.read_p()) {
+    throw InternalErr(__FILE__, __LINE__,
+        funcName + "Logic error: the Vector to copy data from has !read_p() and should have been read in!");
+  }
+
+  // Check this otherwise the static_cast<unsigned int> below will do the wrong thing.
+  if (rowMajorData.length() < 0) {
+    throw InternalErr(__FILE__, __LINE__,
+            funcName + "Logic error: the Vector to copy data from has length() < 0 and was probably not initialized!");
+  }
+
+  // The read-in capacity had better be at least the length (the amountt we will copy) or we'll memcpy into bad memory
+  // I imagine we could copy just the capacity rather than throw, but I really think this implies a problem to be addressed.
+  if (rowMajorData.get_value_capacity() < static_cast<unsigned int>(rowMajorData.length())) {
+    throw InternalErr(__FILE__, __LINE__,
+        funcName + "Logic error: the Vector to copy from has a data capacity less than its length, can't copy!");
+  }
+
+  // Make sure there's enough room in this Vector to store all the elements requested.  Again,
+  // better to throw than just copy what we can since it implies a logic error that needs to be solved.
+  if (_capacity < (startElement + rowMajorData.length())) {
+    throw InternalErr(__FILE__, __LINE__,
+        funcName + "Logic error: the capacity of this Vector cannot hold all the data in the from Vector!");
+  }
+
+  // OK, at this point we're pretty sure we can copy the data, but we have to do it differently depending on type.
+  switch (_var->type()) {
+      case dods_byte_c:
+      case dods_int16_c:
+      case dods_uint16_c:
+      case dods_int32_c:
+      case dods_uint32_c:
+      case dods_float32_c:
+      case dods_float64_c: {
+        if (!_buf) {
+          throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: this->_buf was unexpectedly null!");
+        }
+        if (!rowMajorData._buf) {
+          throw InternalErr(__FILE__, __LINE__, funcName + "Logic error: rowMajorData._buf was unexpectedly null!");
+        }
+        // memcpy the data into this, taking care to do ptr arithmetic on bytes and not sizeof(element)
+        int varWidth = _var->width();
+        char* pFromBuf = rowMajorData._buf;
+        int numBytesToCopy = rowMajorData.width();
+        char* pIntoBuf = _buf + (startElement * varWidth);
+        memcpy(pIntoBuf,
+               pFromBuf,
+               numBytesToCopy );
+      }
+      break;
+
+      case dods_str_c:
+      case dods_url_c: {
+        // Strings need to be copied directly
+        for (unsigned int i = 0; i < static_cast<unsigned int>(rowMajorData.length()); ++i) {
+          d_str[startElement + i] = rowMajorData.d_str[i];
+        }
+      }
+      break;
+
+      case dods_array_c:
+      case dods_structure_c:
+      case dods_sequence_c:
+      case dods_grid_c: {
+        // Not sure that this function will be used for these type of nested objects, so I will throw here.
+        // TODO impl and test this path if it's ever needed.
+        throw InternalErr(__FILE__, __LINE__,
+            funcName + "Unimplemented method for Vectors of type: dods_array_c, dods_structure_c, dods_sequence_c and dods_grid_c.");
+      }
+      break;
+
+      default: {
+        throw InternalErr(__FILE__, __LINE__, funcName + ": Unknown type!");
+      }
+      break;
+
+  } // switch (_var->type())
+
+  // This is how many elements we copied.
+  return (unsigned int)rowMajorData.length();
+}
+
+//@{
+/** @brief set the value of a byte array */
+bool
+Vector::set_value(dods_byte *val, int sz)
+{
+    if (var()->type() == dods_byte_c && val) {
+      set_cardinal_values_internal<dods_byte>(val, sz);
+      return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a byte array */
+bool
+Vector::set_value(vector<dods_byte> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a int16 array */
+bool
+Vector::set_value(dods_int16 *val, int sz)
+{
+    if (var()->type() == dods_int16_c && val) {
+      set_cardinal_values_internal<dods_int16>(val, sz);
+      return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a int16 array */
+bool
+Vector::set_value(vector<dods_int16> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a int32 array */
+bool
+Vector::set_value(dods_int32 *val, int sz)
+{
+    if (var()->type() == dods_int32_c && val) {
+       set_cardinal_values_internal<dods_int32>(val, sz);
+       return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a int32 array */
+bool
+Vector::set_value(vector<dods_int32> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a uint16 array */
+bool
+Vector::set_value(dods_uint16 *val, int sz)
+{
+    if (var()->type() == dods_uint16_c && val) {
+      set_cardinal_values_internal<dods_uint16>(val, sz);
+      return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a uint16 array */
+bool
+Vector::set_value(vector<dods_uint16> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a uint32 array */
+bool
+Vector::set_value(dods_uint32 *val, int sz)
+{
+    if (var()->type() == dods_uint32_c && val) {
+        set_cardinal_values_internal<dods_uint32>(val, sz);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a uint32 array */
+bool
+Vector::set_value(vector<dods_uint32> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a float32 array */
+bool
+Vector::set_value(dods_float32 *val, int sz)
+{
+    if (var()->type() == dods_float32_c && val) {
+        set_cardinal_values_internal<dods_float32>(val, sz);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a float32 array */
+bool
+Vector::set_value(vector<dods_float32> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a float64 array */
+bool
+Vector::set_value(dods_float64 *val, int sz)
+{
+    if (var()->type() == dods_float64_c && val) {
+      set_cardinal_values_internal<dods_float64>(val, sz);
+      return true;
+    }
+    else {
+      return false;
+    }
+}
+
+/** @brief set the value of a float64 array */
+bool
+Vector::set_value(vector<dods_float64> &val, int sz)
+{
+    return set_value(&val[0], sz);
+}
+
+/** @brief set the value of a string or url array */
+bool
+Vector::set_value(string *val, int sz)
+{
+    if ((var()->type() == dods_str_c || var()->type() == dods_url_c) && val) {
+        d_str.resize(sz);
+        _capacity = sz;
+        for (register int t = 0; t < sz; t++) {
+            d_str[t] = val[t] ;
+        }
+        set_length(sz) ;
+        set_read_p(true);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+
+/** @brief set the value of a string or url array */
+bool
+Vector::set_value(vector<string> &val, int sz)
+{
+    if (var()->type() == dods_str_c || var()->type() == dods_url_c) {
+        d_str.resize(sz);
+        _capacity = sz;
+        for (register int t = 0; t < sz; t++) {
+            d_str[t] = val[t] ;
+        }
+        set_length(sz) ;
+        set_read_p(true);
+        return true;
+    }
+    else {
+        return false;
+    }
+}
+//@}
+
+//@{
+/** @brief Get a copy of the data held by this variable.
+    Read data from this variable's internal storage and load it into the
+    memory referenced by \c b. The argument \c b must point to enough memory
+    to hold length() Bytes.
+
+    @param b A pointer to the memory to hold the data; must be at least
+    length() * sizeof(dods_byte) in size.*/
+void Vector::value(dods_byte *b) const
+{
+    if (b && _var->type() == dods_byte_c) {
+        memcpy(b, _buf, length() * sizeof(dods_byte));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_uint16 *b) const
+{
+    if (b && _var->type() == dods_uint16_c) {
+        memcpy(b, _buf, length() * sizeof(dods_uint16));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_int16 *b) const
+{
+    if (b && _var->type() == dods_int16_c) {
+        memcpy(b, _buf, length() * sizeof(dods_int16));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_uint32 *b) const
+{
+    if (b && _var->type() == dods_uint32_c) {
+        memcpy(b, _buf, length() * sizeof(dods_uint32));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_int32 *b) const
+{
+    if (b && _var->type() == dods_int32_c) {
+        memcpy(b, _buf, length() * sizeof(dods_int32));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_float32 *b) const
+{
+    if (b && _var->type() == dods_float32_c) {
+        memcpy(b, _buf, length() * sizeof(dods_float32));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(dods_float64 *b) const
+{
+    if (b && _var->type() == dods_float64_c) {
+        memcpy(b, _buf, length() * sizeof(dods_float64));
+    }
+}
+
+/** @brief Get a copy of the data held by this variable. */
+void Vector::value(vector<string> &b) const
+{
+    if (_var->type() == dods_byte_c || _var->type() == dods_url_c)
+        b = d_str;
+}
+
+/** Allocated memory and copy data into the new buffer. Return the new
+    buffer's pointer. The caller must delete the storage. */
+void *Vector::value()
+{
+    void *buffer = new char[width()];
+
+    memcpy(buffer, _buf, width());
+
+    return buffer;
+}
+//@}
+
+/** @brief Add the BaseType pointer to this constructor type
+    instance.
+
+    Propagate the name of the BaseType instance to this instance. This
+    ensures that variables at any given level of the DDS table have
+    unique names (i.e., that Arrays do not have their default name ""). If
+    <tt>v</tt>'s name is null, then assume that the array \e is named and
+    don't overwrite it with <tt>v</tt>'s null name.
+
+    @param v The template variable for the array
+    @param p The Part parameter defaults to nil and is ignored by this method.
+*/
+void Vector::add_var(BaseType * v, Part)
+{
+    // Delete the current template variable
+    if( _var )
+    {
+	delete _var;
+	_var = 0 ;
+    }
+
+    // if 'v' is null, just set _var to null and exit.
+    if (!v) {
+        _var = 0;
+    }
+    else {
+        // Jose Garcia
+        // By getting a copy of this object to be assigned to _var
+        // we let the owner of 'v' to deallocate it as necessary.
+        _var = v->ptr_duplicate();
+
+        // If 'v' has a name, use it as the name of the array. If it *is*
+        // empty, then make sure to copy the array's name to the template
+        // so that software which uses the template's name will still work.
+        if (!v->name().empty())
+            set_name(v->name());
+        else
+            _var->set_name(name());
+
+        _var->set_parent(this); // Vector --> child
+
+        DBG(cerr << "Vector::add_var: Added variable " << v << " ("
+            << v->name() << " " << v->type_name() << ")" << endl);
+    }
+}
+
+bool Vector::check_semantics(string & msg, bool)
+{
+    return BaseType::check_semantics(msg);
+}
+
+/** @brief dumps information about this object
+ *
+ * Displays the pointer value of this instance and information about this
+ * instance.
+ *
+ * @param strm C++ i/o stream to dump the information to
+ * @return void
+ */
+void
+Vector::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "Vector::dump - ("
+    << (void *)this << ")" << endl ;
+    DapIndent::Indent() ;
+    BaseType::dump(strm) ;
+    strm << DapIndent::LMarg << "# elements in vector: " << _length << endl ;
+    if (_var) {
+        strm << DapIndent::LMarg << "base type:" << endl ;
+        DapIndent::Indent() ;
+        _var->dump(strm) ;
+        DapIndent::UnIndent() ;
+    }
+    else {
+        strm << DapIndent::LMarg << "base type: not set" << endl ;
+    }
+    strm << DapIndent::LMarg << "vector contents:" << endl ;
+    DapIndent::Indent() ;
+    for (unsigned i = 0; i < _vec.size(); ++i) {
+        if (_vec[i])
+            _vec[i]->dump(strm) ;
+        else
+            strm << DapIndent::LMarg << "vec[" << i << "] is null" << endl ;
+    }
+    DapIndent::UnIndent() ;
+    strm << DapIndent::LMarg << "strings:" << endl ;
+    DapIndent::Indent() ;
+    for (unsigned i = 0; i < d_str.size(); i++) {
+        strm << DapIndent::LMarg << d_str[i] << endl ;
+    }
+    DapIndent::UnIndent() ;
+    if( _buf )
+    {
+	switch( _var->type() )
+	{
+	    case dods_byte_c:
+	    {
+		strm << DapIndent::LMarg << "_buf: " ;
+		strm.write( _buf, _length ) ;
+		strm << endl ;
+	    }
+	    break ;
+	    default:
+	    {
+		strm << DapIndent::LMarg << "_buf: " << (void *)_buf << endl ;
+	    }
+	    break ;
+	}
+    }
+    else
+    {
+	strm << DapIndent::LMarg << "_buf: EMPTY" << endl ;
+    }
+    DapIndent::UnIndent() ;
+}
+
+} // namespace libdap
+
diff --git a/Vector.h b/Vector.h
new file mode 100644
index 0000000..a27f25c
--- /dev/null
+++ b/Vector.h
@@ -0,0 +1,190 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// This is the interface definition file for the abstract class
+// Vector. Vector is the parent class for List and Array.
+
+#ifndef _vector_h
+#define _vector_h 1
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef constraint_evaluator_h
+#include "ConstraintEvaluator.h"
+#endif
+
+namespace libdap
+{
+
+/** Holds a one-dimensional array of DAP2 data types.  This class
+    takes two forms, depending on whether the elements of the vector
+    are themselves simple or compound objects. This class contains
+    common functionality for the List and Array classes, and should
+    rarely be used directly.
+
+    When each element of the class is a simple data type, the Vector
+    is implemented as a simple array of C types, rather than as an
+    array of BaseType data types.  A single private ``template''
+    BaseType instance (<tt>_var</tt>) is used to hold information in common
+    to all the members of the array.  The template is also used as a
+    container to pass values back and forth to an application
+    program, as in <tt>var()</tt>.
+
+    If the elements of the vector are themselves compound data
+    types, the array is stored as a vector of BaseType pointers (see
+    the libdap class <b>BaseTypePtrVec</b>). The template is still used to
+    hold information in common to all the members of the array, but
+    is not used to pass information to and from the application
+    program.
+
+    @brief Holds a one-dimensional collection of DAP2 data types.
+    @see BaseType
+    @see Array
+*/
+class Vector: public BaseType
+{
+private:
+    int _length;  // number of elements in the vector
+    BaseType *_var;  // base type of the Vector
+
+    // _buf was a pointer to void; delete[] complained. 6/4/2001 jhrg
+    char *_buf;   // array which holds cardinal data
+    vector<string> d_str;       // special storage for strings. jhrg 2/11/05
+    vector<BaseType *> _vec; // array for other data
+
+    // the number of elements we have allocated memory to store.
+    // This should be either the sizeof(buf)/width() for cardinal data
+    // or the capacity of d_str for strings or capacity of _vec.
+    unsigned int _capacity;
+
+protected:
+    // This function copies the private members of Vector.
+    void _duplicate(const Vector &v);
+
+    bool is_cardinal_type() const;
+    unsigned int create_cardinal_data_buffer_for_type(unsigned int numEltsOfType);
+    void delete_cardinal_data_buffer();
+
+    template <class CardType> void set_cardinal_values_internal(const CardType* fromArray, int numElts);
+
+public:
+    Vector(const string &n, BaseType *v, const Type &t);
+    Vector(const string &n, const string &d, BaseType *v, const Type &t);
+    Vector(const Vector &rhs);
+
+    virtual ~Vector();
+
+    Vector &operator=(const Vector &rhs);
+    virtual BaseType *ptr_duplicate() = 0;
+
+    virtual void set_name(const std::string& name);
+
+    virtual int element_count(bool leaves);
+
+    virtual void set_send_p(bool state);
+
+    virtual void set_read_p(bool state);
+
+    virtual unsigned int width();
+
+    virtual int length() const;
+
+    virtual void set_length(int l);
+
+    virtual void intern_data(ConstraintEvaluator &eval, DDS &dds);
+    virtual bool serialize(ConstraintEvaluator &eval, DDS &dds,
+			   Marshaller &m, bool ce_eval = true);
+    virtual bool deserialize(UnMarshaller &um, DDS *dds, bool reuse = false);
+
+    virtual unsigned int val2buf(void *val, bool reuse = false);
+    virtual unsigned int buf2val(void **val);
+
+    void set_vec(unsigned int i, BaseType *val);
+
+    void vec_resize(int l);
+
+    void clear_local_data();
+
+    virtual unsigned int get_value_capacity() const;
+    virtual void reserve_value_capacity(unsigned int numElements);
+    virtual void reserve_value_capacity();
+
+    virtual unsigned int set_value_slice_from_row_major_vector
+      (const Vector& rowMajorData, unsigned int startElement);
+
+    virtual bool set_value(dods_byte *val, int sz);
+    virtual bool set_value(vector<dods_byte> &val, int sz);
+    virtual bool set_value(dods_int16 *val, int sz);
+    virtual bool set_value(vector<dods_int16> &val, int sz);
+    virtual bool set_value(dods_uint16 *val, int sz);
+    virtual bool set_value(vector<dods_uint16> &val, int sz);
+    virtual bool set_value(dods_int32 *val, int sz);
+    virtual bool set_value(vector<dods_int32> &val, int sz);
+    virtual bool set_value(dods_uint32 *val, int sz);
+    virtual bool set_value(vector<dods_uint32> &val, int sz);
+    virtual bool set_value(dods_float32 *val, int sz);
+    virtual bool set_value(vector<dods_float32> &val, int sz);
+    virtual bool set_value(dods_float64 *val, int sz);
+    virtual bool set_value(vector<dods_float64> &val, int sz);
+    virtual bool set_value(string *val, int sz);
+    virtual bool set_value(vector<string> &val, int sz);
+
+    virtual void value(dods_byte *b) const;
+    virtual void value(dods_int16 *b) const;
+    virtual void value(dods_uint16 *b) const;
+    virtual void value(dods_int32 *b) const;
+    virtual void value(dods_uint32 *b) const;
+    virtual void value(dods_float32 *b) const;
+    virtual void value(dods_float64 *b) const;
+    virtual void value(vector<string> &b) const;
+
+    virtual void *value();
+
+    virtual BaseType *var(const string &name = "", bool exact_match = true,
+                          btp_stack *s = 0);
+    virtual BaseType *var(const string &name, btp_stack &s);
+    virtual BaseType *var(unsigned int i);
+
+    virtual void add_var(BaseType *v, Part p = nil);
+    virtual bool check_semantics(string &msg, bool all = false);
+
+    virtual void dump(ostream &strm) const ;
+};
+
+} // namespace libdap
+
+#endif /* _vector_h */
diff --git a/XDRFileMarshaller.cc b/XDRFileMarshaller.cc
new file mode 100644
index 0000000..cf8ec40
--- /dev/null
+++ b/XDRFileMarshaller.cc
@@ -0,0 +1,209 @@
+// XDRFileMarshaller.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#include "XDRFileMarshaller.h"
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "util.h"
+#include "InternalErr.h"
+
+namespace libdap {
+
+XDRFileMarshaller::XDRFileMarshaller( FILE *out )
+    : _sink( 0 )
+{
+    _sink = new_xdrstdio( out, XDR_ENCODE ) ;
+}
+
+XDRFileMarshaller::XDRFileMarshaller()
+    : Marshaller(),
+      _sink( 0 )
+{
+    throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
+}
+
+XDRFileMarshaller::XDRFileMarshaller( const XDRFileMarshaller &m )
+    : Marshaller( m ),
+      _sink( 0 )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
+}
+
+XDRFileMarshaller &
+XDRFileMarshaller::operator=( const XDRFileMarshaller & )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;
+
+    return *this ;
+}
+
+XDRFileMarshaller::~XDRFileMarshaller( )
+{
+    delete_xdrstdio( _sink ) ;
+}
+
+void
+XDRFileMarshaller::put_byte( dods_byte val )
+{
+    if( !xdr_char( _sink, (char *)&val ) )
+        throw Error("Network I/O Error. Could not send byte data.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_int16( dods_int16 val )
+{
+    if( !XDR_INT16( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send int 16 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_int32( dods_int32 val )
+{
+    if( !XDR_INT32( _sink, &val ) )
+        throw Error("Network I/O Error. Could not read int 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_float32( dods_float32 val )
+{
+    if( !xdr_float( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send float 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_float64( dods_float64 val )
+{
+    if( !xdr_double( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send float 64 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_uint16( dods_uint16 val )
+{
+    if( !XDR_UINT16( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send uint 16 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_uint32( dods_uint32 val )
+{
+    if( !XDR_UINT32( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send uint 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_str( const string &val )
+{
+    const char *out_tmp = val.c_str() ;
+
+    if( !xdr_string( _sink, (char **)&out_tmp, max_str_len) )
+        throw Error("Network I/O Error. Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_url( const string &val )
+{
+    put_str( val ) ;
+}
+
+void
+XDRFileMarshaller::put_opaque( char *val, unsigned int len )
+{
+    if( !xdr_opaque( _sink, val, len ) )
+        throw Error("Network I/O Error. Could not send opaque data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_int( int val )
+{
+    if( !xdr_int( _sink, &val) )
+	throw Error("Network I/O Error(1). This may be due to a bug in libdap or a\nproblem with the network connection.");
+}
+
+void
+XDRFileMarshaller::put_vector( char *val, int num, Vector & )
+{
+    if (!val)
+	throw InternalErr(__FILE__, __LINE__,
+			  "Buffer pointer is not set.");
+
+    put_int( num ) ;
+
+    if( !xdr_bytes( _sink, (char **)&val,
+		    (unsigned int *) &num,
+		    DODS_MAX_ARRAY) )
+    {
+	throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
+    }
+}
+
+void
+XDRFileMarshaller::put_vector( char *val, int num, int width, Vector &vec )
+{
+    if (!val)
+	throw InternalErr(__FILE__, __LINE__,
+			  "Buffer pointer is not set.");
+
+    put_int( num ) ;
+
+    BaseType *var = vec.var() ;
+    if( !xdr_array( _sink, (char **)&val,
+		    (unsigned int *) & num,
+		    DODS_MAX_ARRAY, width,
+		    XDRUtils::xdr_coder( var->type() ) ) )
+    {
+	throw Error("Network I/O Error(2). This may be due to a bug in libdap or a\nproblem with the network connection.");
+    }
+}
+
+void
+XDRFileMarshaller::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "XDRFileMarshaller::dump - ("
+         << (void *)this << ")" << endl ;
+}
+
+} // namespace libdap
+
diff --git a/XDRFileMarshaller.h b/XDRFileMarshaller.h
new file mode 100644
index 0000000..0b8526f
--- /dev/null
+++ b/XDRFileMarshaller.h
@@ -0,0 +1,83 @@
+// XDRFileMarshaller.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef I_XDRFileMarshaller_h
+#define I_XDRFileMarshaller_h 1
+
+#include "Marshaller.h"
+#include "XDRUtils.h"
+
+namespace libdap
+{
+
+/** @brief marshaller that knows how to marshall/serialize dap data objects
+ * to a file using XDR
+ */
+class XDRFileMarshaller : public Marshaller
+{
+private:
+    XDR *			_sink ;
+    				XDRFileMarshaller() ;
+    				XDRFileMarshaller( const XDRFileMarshaller &m ) ;
+    XDRFileMarshaller &		operator=( const XDRFileMarshaller & ) ;
+public:
+    				XDRFileMarshaller( FILE *out ) ;
+    virtual			~XDRFileMarshaller() ;
+
+    virtual void		put_byte( dods_byte val ) ;
+
+    virtual void		put_int16( dods_int16 val ) ;
+    virtual void		put_int32( dods_int32 val ) ;
+
+    virtual void		put_float32( dods_float32 val ) ;
+    virtual void		put_float64( dods_float64 val ) ;
+
+    virtual void		put_uint16( dods_uint16 val ) ;
+    virtual void		put_uint32( dods_uint32 val ) ;
+
+    virtual void		put_str( const string &val ) ;
+    virtual void		put_url( const string &val ) ;
+
+    virtual void		put_opaque( char *val, unsigned int len ) ;
+    virtual void		put_int( int val ) ;
+
+    virtual void		put_vector( char *val, int num,
+					    Vector &vec ) ;
+    virtual void		put_vector( char *val, int num, int width,
+                                            Vector &vec ) ;
+    virtual void		dump(ostream &strm) const ;
+} ;
+
+} // namespace libdap
+
+#endif // I_XDRFileMarshaller_h
+
diff --git a/XDRFileUnMarshaller.cc b/XDRFileUnMarshaller.cc
new file mode 100644
index 0000000..c853489
--- /dev/null
+++ b/XDRFileUnMarshaller.cc
@@ -0,0 +1,197 @@
+// XDRFileUnMarshaller.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#include "XDRFileUnMarshaller.h"
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+#if  0
+#include "Vector.h"
+#endif
+#include "util.h"
+#include "InternalErr.h"
+
+namespace libdap {
+
+XDRFileUnMarshaller::XDRFileUnMarshaller( FILE *out )
+    : _source( 0 )
+{
+    _source = new_xdrstdio( out, XDR_DECODE ) ;
+}
+
+XDRFileUnMarshaller::XDRFileUnMarshaller()
+    : UnMarshaller(),
+      _source( 0 )
+{
+    throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
+}
+
+XDRFileUnMarshaller::XDRFileUnMarshaller( const XDRFileUnMarshaller &um )
+    : UnMarshaller( um ),
+      _source( 0 )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
+}
+
+XDRFileUnMarshaller &
+XDRFileUnMarshaller::operator=( const XDRFileUnMarshaller & )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;
+
+    return *this ;
+}
+
+XDRFileUnMarshaller::~XDRFileUnMarshaller( )
+{
+    delete_xdrstdio( _source ) ;
+}
+
+void
+XDRFileUnMarshaller::get_byte( dods_byte &val )
+{
+    if( !xdr_char( _source, (char *)&val ) )
+        throw Error("Network I/O Error. Could not read byte data. This may be due to a\nbug in DODS or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_int16( dods_int16 &val )
+{
+    if( !XDR_INT16( _source, &val ) )
+        throw Error("Network I/O Error. Could not read int 16 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_int32( dods_int32 &val )
+{
+    if( !XDR_INT32( _source, &val ) )
+        throw Error("Network I/O Error. Could not read int 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_float32( dods_float32 &val )
+{
+    if( !xdr_float( _source, &val ) )
+        throw Error("Network I/O Error. Could not read float 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_float64( dods_float64 &val )
+{
+    if( !xdr_double( _source, &val ) )
+        throw Error("Network I/O Error. Could not read float 64 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_uint16( dods_uint16 &val )
+{
+    if( !XDR_UINT16( _source, &val ) )
+        throw Error("Network I/O Error. Could not read uint 16 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_uint32( dods_uint32 &val )
+{
+    if( !XDR_UINT32( _source, &val ) )
+        throw Error("Network I/O Error. Could not read uint 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_str( string &val )
+{
+    char *in_tmp = NULL ;
+
+    if( !xdr_string( _source, &in_tmp, max_str_len ) )
+        throw Error("Network I/O Error. Could not read string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+
+    val = in_tmp ;
+
+    free( in_tmp ) ;
+}
+
+void
+XDRFileUnMarshaller::get_url( string &val )
+{
+    get_str( val ) ;
+}
+
+void
+XDRFileUnMarshaller::get_opaque( char *val, unsigned int len )
+{
+    xdr_opaque( _source, val, len ) ;
+}
+
+void
+XDRFileUnMarshaller::get_int( int &val )
+{
+    if( !xdr_int( _source, &val ) )
+	throw Error("Network I/O Error(1). This may be due to a bug in libdap or a\nproblem with the network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_vector( char **val, unsigned int &num, Vector & )
+{
+    if( !xdr_bytes( _source, val, &num, DODS_MAX_ARRAY) )
+	throw Error("Network I/O error. Could not read packed array data.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
+}
+
+void
+XDRFileUnMarshaller::get_vector( char **val, unsigned int &num, int width, Vector &vec )
+{
+    BaseType *var = vec.var() ;
+
+    if( !xdr_array( _source, val, &num, DODS_MAX_ARRAY, width,
+		    XDRUtils::xdr_coder( var->type() ) ) )
+    {
+	throw Error("Network I/O error. Could not read packed array data.\nThis may be due to a bug in libdap or a problem with\nthe network connection.");
+    }
+}
+
+void
+XDRFileUnMarshaller::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "XDRFileUnMarshaller::dump - ("
+         << (void *)this << ")" << endl ;
+}
+
+} // namespace libdap
+
diff --git a/XDRFileUnMarshaller.h b/XDRFileUnMarshaller.h
new file mode 100644
index 0000000..5d78d59
--- /dev/null
+++ b/XDRFileUnMarshaller.h
@@ -0,0 +1,84 @@
+// XDRFileUnMarshaller.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef I_XDRFileUnMarshaller_h
+#define I_XDRFileUnMarshaller_h 1
+
+#include "UnMarshaller.h"
+#include "XDRUtils.h"
+
+namespace libdap
+{
+
+/** @brief unmarshaller that knows how to unmarshall/deserialize dap objects
+ * using XDR from a file
+ */
+class XDRFileUnMarshaller : public UnMarshaller
+{
+private:
+    XDR *			_source ;
+    				XDRFileUnMarshaller() ;
+    				XDRFileUnMarshaller( const XDRFileUnMarshaller &um ) ;
+    XDRFileUnMarshaller &	operator=( const XDRFileUnMarshaller & ) ;
+public:
+    				XDRFileUnMarshaller( FILE *out ) ;
+    virtual			~XDRFileUnMarshaller() ;
+
+    virtual void		get_byte( dods_byte &val ) ;
+
+    virtual void		get_int16( dods_int16 &val ) ;
+    virtual void		get_int32( dods_int32 &val ) ;
+
+    virtual void		get_float32( dods_float32 &val ) ;
+    virtual void		get_float64( dods_float64 &val ) ;
+
+    virtual void		get_uint16( dods_uint16 &val ) ;
+    virtual void		get_uint32( dods_uint32 &val ) ;
+
+    virtual void		get_str( string &val ) ;
+    virtual void		get_url( string &val ) ;
+
+    virtual void		get_opaque( char *val, unsigned int len ) ;
+    virtual void		get_int( int &val ) ;
+
+    virtual void		get_vector( char **val, unsigned int &num,
+					    Vector &vec ) ;
+    virtual void		get_vector( char **val, unsigned int &num,
+					    int width, Vector &vec ) ;
+
+    virtual void		dump(ostream &strm) const ;
+} ;
+
+} // namespace libdap
+
+#endif // I_XDRFileUnMarshaller_h
+
diff --git a/XDRStreamMarshaller.cc b/XDRStreamMarshaller.cc
new file mode 100644
index 0000000..823e74d
--- /dev/null
+++ b/XDRStreamMarshaller.cc
@@ -0,0 +1,401 @@
+// XDRStreamMarshaller.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#include "XDRStreamMarshaller.h"
+
+//#define DODS_DEBUG 1
+
+#include "Vector.h"
+#include "util.h"
+#include "debug.h"
+
+namespace libdap {
+
+char *XDRStreamMarshaller::_buf = 0 ;
+
+#define XDR_DAP_BUFF_SIZE 256
+
+XDRStreamMarshaller::XDRStreamMarshaller( ostream &out )
+    : _sink( 0 ),
+      _out( out )
+{
+    if( !_buf )
+	_buf = (char *)malloc( XDR_DAP_BUFF_SIZE ) ;
+    if ( !_buf )
+        throw Error("Failed to allocate memory for data serialization.");
+
+    _sink = new XDR ;
+    xdrmem_create( _sink, _buf, XDR_DAP_BUFF_SIZE, XDR_ENCODE ) ;
+}
+
+XDRStreamMarshaller::XDRStreamMarshaller()
+    : Marshaller(),
+      _sink( 0 ),
+      _out( cout )
+{
+    throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
+}
+
+XDRStreamMarshaller::XDRStreamMarshaller( const XDRStreamMarshaller &m )
+    : Marshaller( m ),
+      _sink( 0 ),
+      _out( cout )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
+}
+
+XDRStreamMarshaller &
+XDRStreamMarshaller::operator=( const XDRStreamMarshaller & )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;
+
+    return *this ;
+}
+
+XDRStreamMarshaller::~XDRStreamMarshaller( )
+{
+    if( _sink )
+	delete_xdrstdio( _sink ) ;
+    _sink = 0 ;
+}
+
+void
+XDRStreamMarshaller::put_byte( dods_byte val )
+{
+    DBG( std::cerr << "put_byte: " << val << std::endl );
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send byte data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !xdr_char( _sink, (char *)&val ) )
+        throw Error("Network I/O Error. Could not send byte data.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send byte data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_int16( dods_int16 val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send int 16 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !XDR_INT16( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send int 16 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send int 16 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_int32( dods_int32 val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send int 32 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !XDR_INT32( _sink, &val ) )
+        throw Error("Network I/O Error. Culd not read int 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send int 32 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_float32( dods_float32 val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send float 32 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !xdr_float( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send float 32 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send float 32 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_float64( dods_float64 val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send float 64 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !xdr_double( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send float 64 data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send float 64 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_uint16( dods_uint16 val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send uint 16 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !XDR_UINT16( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send uint 16 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send uint 16 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_uint32( dods_uint32 val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send uint 32 data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !XDR_UINT32( _sink, &val ) )
+        throw Error("Network I/O Error. Could not send uint 32 data. This may be due to a\nbug in libdap or a problem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send uint 32 data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_str( const string &val )
+{
+    int size = val.length() + 8 ;
+    char *str_buf = (char *)malloc( size ) ;
+
+    if ( !str_buf ) {
+        throw Error("Failed to allocate memory for string data serialization.");
+    }
+
+    XDR *str_sink = new XDR ;
+    xdrmem_create( str_sink, str_buf, size, XDR_ENCODE ) ;
+
+    if( !xdr_setpos( str_sink, 0 ) ) {
+    	delete_xdrstdio( str_sink ) ;
+        free( str_buf ) ;
+        throw Error("Network I/O Error. Could not send string data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+    }
+
+    const char *out_tmp = val.c_str() ;
+    if( !xdr_string( str_sink, (char **)&out_tmp, size ) ) {
+    	delete_xdrstdio( str_sink ) ;
+        free( str_buf ) ;
+        throw Error("Network I/O Error. Could not send string data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+    }
+
+    unsigned int bytes_written = xdr_getpos( str_sink ) ;
+    if( !bytes_written ) {
+    	delete_xdrstdio( str_sink ) ;
+        free( str_buf ) ;
+        throw Error("Network I/O Error. Could not send string data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+    }
+
+    _out.write( str_buf, bytes_written ) ;
+
+    delete_xdrstdio( str_sink ) ;
+    free( str_buf ) ;
+}
+
+void
+XDRStreamMarshaller::put_url( const string &val )
+{
+    put_str( val ) ;
+}
+
+void
+XDRStreamMarshaller::put_opaque( char *val, unsigned int len )
+{
+    if( len > XDR_DAP_BUFF_SIZE )
+        throw Error("Network I/O Error. Could not send opaque data - length of opaque data larger than allowed");
+
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send opaque data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !xdr_opaque( _sink, val, len ) )
+        throw Error("Network I/O Error. Could not send opaque data.\nThis may be due to a bug in libdap, on the server or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send opaque data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_int( int val )
+{
+    if( !xdr_setpos( _sink, 0 ) )
+        throw Error("Network I/O Error. Could not send int data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    if( !xdr_int( _sink, &val) )
+	throw Error("Network I/O Error(1). Could not send int data.\nThis may be due to a bug in libdap or a\nproblem with the network connection.");
+
+    unsigned int bytes_written = xdr_getpos( _sink ) ;
+    if( !bytes_written )
+        throw Error("Network I/O Error. Could not send int data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+
+    _out.write( _buf, bytes_written ) ;
+}
+
+void
+XDRStreamMarshaller::put_vector( char *val, int num, Vector & )
+{
+    if (!val)
+	throw InternalErr(__FILE__, __LINE__, "Could not send byte vector data. Buffer pointer is not set.");
+
+    // write the number of members of the array being written and then set the position to 0
+    put_int( num ) ;
+
+    // this is the word boundary for writing xdr bytes in a vector.
+    unsigned int add_to = 8 ;
+
+    char *byte_buf = (char *)malloc( num + add_to ) ;
+    if ( !byte_buf ) {
+        throw Error("Failed to allocate memory for byte vector data serialization.");
+    }
+
+    XDR *byte_sink = new XDR ;
+    xdrmem_create( byte_sink, byte_buf, num + add_to, XDR_ENCODE ) ;
+
+    if( !xdr_setpos( byte_sink, 0 ) ) {
+    	delete_xdrstdio( byte_sink ) ;
+        free(byte_buf);
+        throw Error("Network I/O Error. Could not send byte vector data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+    }
+
+    if( !xdr_bytes( byte_sink, (char **)&val, (unsigned int *) &num,
+		    num + add_to ) )
+    {
+    	delete_xdrstdio( byte_sink ) ;
+        free(byte_buf);
+        throw Error("Network I/O Error(2). Could not send byte vector data.\nThis may be due to a bug in libdap or a\nproblem with the network connection.");
+    }
+
+    unsigned int bytes_written = xdr_getpos( byte_sink ) ;
+    if( !bytes_written ) {
+    	delete_xdrstdio( byte_sink ) ;
+        free(byte_buf);
+        throw Error("Network I/O Error. Could not send byte vector data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+    }
+
+    _out.write( byte_buf, bytes_written ) ;
+
+    delete_xdrstdio( byte_sink ) ;
+    free( byte_buf ) ;
+}
+
+void
+XDRStreamMarshaller::put_vector( char *val, int num, int width, Vector &vec )
+{
+    if (!val)
+	throw InternalErr(__FILE__, __LINE__,
+			  "Buffer pointer is not set.");
+    // write the number of array members being written, then set the position back to 0
+    put_int( num ) ;
+
+    int use_width = width ;
+    if( use_width < 4 )
+	use_width = 4 ;
+
+    // the size is the number of elements num times the width of each
+    // element, then add 4 bytes for the number of elements
+    int size = ( num * use_width ) + 4 ;
+
+    // allocate enough memory for the elements
+    char *vec_buf = (char *)malloc( size ) ;
+    if ( !vec_buf ) {
+    	free(vec_buf);
+        throw Error("Failed to allocate memory for vector data serialization.");
+    }
+
+    XDR *vec_sink = new XDR ;
+    xdrmem_create( vec_sink, vec_buf, size, XDR_ENCODE ) ;
+
+    // set the position of the sink to 0, we're starting at the beginning
+    if( !xdr_setpos( vec_sink, 0 ) ) {
+    	delete_xdrstdio( vec_sink ) ;
+        free(vec_buf);
+        throw Error("Network I/O Error. Could not send vector data - unable to set stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+    }
+
+    BaseType *var = vec.var() ;
+
+    // write the array to the buffer
+    if( !xdr_array( vec_sink, (char **)&val,
+		    (unsigned int *) & num,
+		    size, width,
+		    XDRUtils::xdr_coder( var->type() ) ) )
+    {
+    	delete_xdrstdio( vec_sink ) ;
+        free(vec_buf);
+        throw Error("Network I/O Error(2). Could not send vector data.\nThis may be due to a bug in libdap or a\nproblem with the network connection.");
+    }
+
+    // how much was written to the buffer
+    unsigned int bytes_written = xdr_getpos( vec_sink ) ;
+    if( !bytes_written ) {
+    	delete_xdrstdio( vec_sink ) ;
+        free(vec_buf);
+        throw Error("Network I/O Error. Could not send vector data - unable to get stream position.\nThis may be due to a bug in DODS, on the server or a\nproblem with the network connection.");
+    }
+
+    // write that much out to the output stream
+    _out.write( vec_buf, bytes_written ) ;
+
+    delete_xdrstdio( vec_sink ) ;
+    free( vec_buf ) ;
+}
+
+void
+XDRStreamMarshaller::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "XDRStreamMarshaller::dump - ("
+         << (void *)this << ")" << endl ;
+}
+
+} // namespace libdap
+
diff --git a/XDRStreamMarshaller.h b/XDRStreamMarshaller.h
new file mode 100644
index 0000000..eb690ff
--- /dev/null
+++ b/XDRStreamMarshaller.h
@@ -0,0 +1,92 @@
+// XDRStreamMarshaller.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef I_XDRStreamMarshaller_h
+#define I_XDRStreamMarshaller_h 1
+
+#include <iostream>
+
+using std::ostream ;
+using std::cout ;
+
+#include "Marshaller.h"
+#include "XDRUtils.h"
+
+namespace libdap
+{
+
+/** @brief marshaller that knows how to marshal/serialize dap data objects
+ * to a C++ iostream using XDR
+ */
+class XDRStreamMarshaller : public Marshaller
+{
+private:
+    static char *		_buf ;
+    XDR *			_sink ;
+    ostream &			_out ;
+
+    				XDRStreamMarshaller() ;
+    				XDRStreamMarshaller( const XDRStreamMarshaller &m ) ;
+    XDRStreamMarshaller &	operator=( const XDRStreamMarshaller & ) ;
+public:
+    				XDRStreamMarshaller( ostream &out ) ;
+    virtual			~XDRStreamMarshaller() ;
+
+    virtual void		put_byte( dods_byte val ) ;
+
+    virtual void		put_int16( dods_int16 val ) ;
+    virtual void		put_int32( dods_int32 val ) ;
+
+    virtual void		put_float32( dods_float32 val ) ;
+    virtual void		put_float64( dods_float64 val ) ;
+
+    virtual void		put_uint16( dods_uint16 val ) ;
+    virtual void		put_uint32( dods_uint32 val ) ;
+
+    virtual void		put_str( const string &val ) ;
+    virtual void		put_url( const string &val ) ;
+
+    virtual void		put_opaque( char *val, unsigned int len ) ;
+    virtual void		put_int( int val ) ;
+
+    virtual void		put_vector( char *val, int num,
+					    Vector &vec ) ;
+    virtual void		put_vector( char *val, int num, int width,
+                                            Vector &vec ) ;
+
+    virtual void		dump(ostream &strm) const ;
+} ;
+
+} // namespace libdap
+
+#endif // I_XDRStreamMarshaller_h
+
diff --git a/XDRStreamUnMarshaller.cc b/XDRStreamUnMarshaller.cc
new file mode 100644
index 0000000..828fec2
--- /dev/null
+++ b/XDRStreamUnMarshaller.cc
@@ -0,0 +1,358 @@
+// XDRStreamUnMarshaller.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+#include "config.h"
+#include "XDRStreamUnMarshaller.h"
+
+#include <cstring> // for memcpy
+#include <string>
+#include <sstream>
+
+#define DODS_DEBUG2 1
+#define DODS_DEBUG 1
+
+#include "Str.h"
+#include "Vector.h"
+#include "Array.h"
+#include "util.h"
+#include "InternalErr.h"
+#include "debug.h"
+
+namespace libdap {
+
+char *XDRStreamUnMarshaller::_buf = 0 ;
+
+XDRStreamUnMarshaller::XDRStreamUnMarshaller( istream &in )
+    : _source( 0 ), _in( in )
+{
+    if (!_buf)
+	_buf = (char *) malloc(XDR_DAP_BUFF_SIZE);
+    if (!_buf)
+	throw Error("Failed to allocate memory for data serialization.");
+
+    _source = new XDR;
+    xdrmem_create(_source, _buf, XDR_DAP_BUFF_SIZE, XDR_DECODE);
+}
+
+XDRStreamUnMarshaller::XDRStreamUnMarshaller()
+    : UnMarshaller(), _source( 0 ), _in( cin )
+{
+    throw InternalErr( __FILE__, __LINE__, "Default constructor not implemented." ) ;
+}
+
+XDRStreamUnMarshaller::XDRStreamUnMarshaller( const XDRStreamUnMarshaller &um )
+    : UnMarshaller( um ), _source( 0 ), _in( cin )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy constructor not implemented." ) ;
+}
+
+XDRStreamUnMarshaller &
+XDRStreamUnMarshaller::operator=( const XDRStreamUnMarshaller & )
+{
+    throw InternalErr( __FILE__, __LINE__, "Copy operator not implemented." ) ;
+
+    return *this ;
+}
+
+XDRStreamUnMarshaller::~XDRStreamUnMarshaller( )
+{
+    if ( _source )
+	delete_xdrstdio( _source ) ;
+    _source = 0;
+}
+
+void
+XDRStreamUnMarshaller::get_byte( dods_byte &val )
+{
+    if (xdr_setpos( _source, 0 ) < 0)
+	throw Error("Failed to reposition input stream");
+    if (!(_in.read( _buf, 4 ))) {
+	if (_in.eof())
+	    throw Error("Premature EOF in input stream");
+	else {
+	    ostringstream ss("Error reading from input stream: ");
+	    ss << _in.rdstate();
+	    throw Error(ss.str());
+	}
+    }
+
+    DBG2( std::cerr << "_in.gcount(): " << _in.gcount() << std::endl );
+    DBG2( std::cerr << "_in.tellg(): " << _in.tellg() << std::endl );
+    DBG2( std::cerr << "_buf[0]: " << hex << _buf[0] << "; _buf[1]: " << _buf[1]
+             << "; _buf[2]: " << _buf[2] << "; _buf[3]: " << _buf[3]
+             << dec << std::endl );
+
+    if( !xdr_char( _source, (char *)&val ) )
+        throw Error("Network I/O Error. Could not read byte data.");
+
+    DBG2(std::cerr << "get_byte: " << val << std::endl );
+}
+
+void
+XDRStreamUnMarshaller::get_int16( dods_int16 &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 4 );
+
+    if( !XDR_INT16( _source, &val ) )
+        throw Error("Network I/O Error. Could not read int 16 data.");
+}
+
+void
+XDRStreamUnMarshaller::get_int32( dods_int32 &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 4 );
+
+    if( !XDR_INT32( _source, &val ) )
+        throw Error("Network I/O Error. Could not read int 32 data.");
+}
+
+void
+XDRStreamUnMarshaller::get_float32( dods_float32 &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 4 );
+
+    if( !xdr_float( _source, &val ) )
+        throw Error("Network I/O Error. Could not read float 32 data.");
+}
+
+void
+XDRStreamUnMarshaller::get_float64( dods_float64 &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 8 );
+
+    if( !xdr_double( _source, &val ) )
+        throw Error("Network I/O Error. Could not read float 64 data.");
+}
+
+void
+XDRStreamUnMarshaller::get_uint16( dods_uint16 &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 4 );
+
+    if( !XDR_UINT16( _source, &val ) )
+        throw Error("Network I/O Error. Could not read uint 16 data.");
+}
+
+void
+XDRStreamUnMarshaller::get_uint32( dods_uint32 &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 4 );
+
+    if( !XDR_UINT32( _source, &val ) )
+        throw Error("Network I/O Error. Could not read uint 32 data.");
+}
+
+void
+XDRStreamUnMarshaller::get_str( string &val )
+{
+    int i;
+    get_int( i ) ;
+    DBG(std::cerr << "i: " << i << std::endl);
+
+    // Must round up string size to next 4
+    i = ( ( i + 3 ) / 4 ) * 4;
+    DBG(std::cerr << "i: " << i << std::endl);
+
+    char *in_tmp = 0;
+    //char *buf = 0;
+    //XDR *source = 0;
+    // Must address the case where the string is larger than the buffer
+    if ( i + 4 > XDR_DAP_BUFF_SIZE ) {
+	char *buf = (char *) malloc( i + 4 );
+	if (!buf)
+		throw InternalErr(__FILE__, __LINE__, "Error allocating memory");
+	XDR *source = new XDR;	
+	xdrmem_create(source, buf, i + 4, XDR_DECODE);
+	memcpy( buf, _buf, 4 );
+
+	_in.read( buf + 4, i );
+
+	xdr_setpos( source, 0 );
+	if( !xdr_string( source, &in_tmp, max_str_len ) ) {
+	    delete_xdrstdio( source );
+	    throw Error("Network I/O Error. Could not read string data.");
+	}
+
+	delete_xdrstdio( source );
+    }
+    else {
+	_in.read( _buf + 4, i );
+
+	xdr_setpos( _source, 0 );
+	if( !xdr_string( _source, &in_tmp, max_str_len ) )
+	    throw Error("Network I/O Error. Could not read string data.");
+    }
+
+    val = in_tmp ;
+
+    free( in_tmp ) ;
+}
+
+void
+XDRStreamUnMarshaller::get_url( string &val )
+{
+    get_str( val ) ;
+}
+
+void
+XDRStreamUnMarshaller::get_opaque( char *val, unsigned int len )
+{
+    xdr_setpos( _source, 0 );
+
+    // Round len up to the next multiple of 4. There is also the RNDUP()
+    // macro in xdr.h, at least on OS/X.
+    len += len&3;
+    if ( static_cast<int>(len) > XDR_DAP_BUFF_SIZE )
+	throw Error("Network I/O Error. Length of opaque data larger than allowed");
+
+    _in.read( _buf, len );
+
+     xdr_opaque( _source, val, len ) ;
+}
+
+void
+XDRStreamUnMarshaller::get_int( int &val )
+{
+    xdr_setpos( _source, 0 );
+    _in.read( _buf, 4 );
+
+    if( !xdr_int( _source, &val ) )
+	throw Error("Network I/O Error(1).");
+
+    DBG(std::cerr << "get_int: " << val << std::endl);
+}
+
+void
+XDRStreamUnMarshaller::get_vector( char **val, unsigned int &num, Vector & )
+{
+    int i;
+    get_int( i ) ;  // This leaves the XDR encoded value in _buf; used later
+    DBG(std::cerr << "i: " << i << std::endl);
+
+    // Must round up string size to next 4
+    i += i&3;
+    DBG(std::cerr << "i: " << i << std::endl);
+
+    //char *buf = 0;
+    //XDR *source = 0;
+    // Must address the case where the string is larger than the buffer
+    if ( i + 4 > XDR_DAP_BUFF_SIZE ) {
+	char *buf = (char *) malloc( i + 4 );
+	if (!buf)
+		throw InternalErr(__FILE__, __LINE__, "Error allocating memory");
+	XDR *source = new XDR;	
+	xdrmem_create(source, buf, i + 4, XDR_DECODE);
+	memcpy( buf, _buf, 4 );
+
+	_in.read( buf + 4, i );
+	DBG2(cerr << "bytes read: " << _in.gcount() << endl);
+
+	xdr_setpos( source, 0 );
+	if( !xdr_bytes( _source, val, &num, DODS_MAX_ARRAY) ) {
+	    delete_xdrstdio( source );
+	    throw Error("Network I/O Error. Could not read byte array data.");
+	}
+
+	delete_xdrstdio( source );
+    }
+    else {
+	_in.read( _buf + 4, i );
+	DBG2(cerr << "bytes read: " << _in.gcount() << endl);
+
+	xdr_setpos( _source, 0 );
+	if( !xdr_bytes( _source, val, &num, DODS_MAX_ARRAY) )
+	    throw Error("Network I/O Error. Could not read byte array data.");
+    }
+}
+
+void
+XDRStreamUnMarshaller::get_vector( char **val, unsigned int &num, int width, Vector &vec )
+{
+    int i;
+    get_int( i ) ; // This leaves the XDR encoded value in _buf; used later
+    DBG(std::cerr << "i: " << i << std::endl);
+
+    width += width&3;
+    DBG(std::cerr << "width: " << width << std::endl);
+
+    //char *buf = 0;
+    //XDR *source = 0;
+    int size = i * width; // + 4; // '+ 4' to hold the int already read
+    BaseType *var = vec.var();
+
+    // Must address the case where the string is larger than the buffer
+    if (size > XDR_DAP_BUFF_SIZE) {
+	char *buf = (char *) malloc( size + 4 );
+	if (!buf)
+		throw InternalErr(__FILE__, __LINE__, "Error allocating memory");
+	XDR *source = new XDR;	
+	xdrmem_create(source, buf, size + 4, XDR_DECODE);
+	DBG2(cerr << "size: " << size << endl);
+	memcpy(buf, _buf, 4);
+
+	_in.read(buf + 4, size); // +4 for the int already read
+	DBG2(cerr << "bytes read: " << _in.gcount() << endl);
+
+	xdr_setpos( source, 0 );
+	if (!xdr_array( source, val, &num, DODS_MAX_ARRAY, width,
+		        XDRUtils::xdr_coder( var->type() ) ) ) {
+	    delete_xdrstdio( source );
+	    throw Error("Network I/O Error. Could not read array data.");
+	}
+
+	delete_xdrstdio(source);
+    }
+    else {
+	_in.read(_buf + 4, size);
+	DBG2(cerr << "bytes read: " << _in.gcount() << endl);
+
+	xdr_setpos( _source, 0 );
+	if (!xdr_array( _source, val, &num, DODS_MAX_ARRAY, width,
+		        XDRUtils::xdr_coder( var->type() ) ) )
+	    throw Error("Network I/O Error. Could not read array data.");
+    }
+}
+
+void
+XDRStreamUnMarshaller::dump(ostream &strm) const
+{
+    strm << DapIndent::LMarg << "XDRStreamUnMarshaller::dump - ("
+         << (void *)this << ")" << endl ;
+}
+
+} // namespace libdap
+
diff --git a/XDRStreamUnMarshaller.h b/XDRStreamUnMarshaller.h
new file mode 100644
index 0000000..ca26a77
--- /dev/null
+++ b/XDRStreamUnMarshaller.h
@@ -0,0 +1,94 @@
+// XDRStreamUnMarshaller.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef I_XDRStreamUnMarshaller_h
+#define I_XDRStreamUnMarshaller_h 1
+
+#include <iostream>
+
+using std::istream ;
+using std::cin ;
+
+#include "UnMarshaller.h"
+#include "XDRUtils.h"
+
+namespace libdap
+{
+
+const int XDR_DAP_BUFF_SIZE = 4096; // This will be compared to a signed int
+
+/** @brief unmarshaller that knows how to unmarshall/deserialize dap objects
+ * using XDR from a file
+ */
+class XDRStreamUnMarshaller : public UnMarshaller
+{
+private:
+    XDR *			_source ;
+    istream &			_in;
+    static char *		_buf;
+
+    				XDRStreamUnMarshaller() ;
+    				XDRStreamUnMarshaller( const XDRStreamUnMarshaller &um ) ;
+    XDRStreamUnMarshaller &	operator=( const XDRStreamUnMarshaller & ) ;
+public:
+    				XDRStreamUnMarshaller( istream &in ) ;
+    virtual			~XDRStreamUnMarshaller() ;
+
+    virtual void		get_byte( dods_byte &val ) ;
+
+    virtual void		get_int16( dods_int16 &val ) ;
+    virtual void		get_int32( dods_int32 &val ) ;
+
+    virtual void		get_float32( dods_float32 &val ) ;
+    virtual void		get_float64( dods_float64 &val ) ;
+
+    virtual void		get_uint16( dods_uint16 &val ) ;
+    virtual void		get_uint32( dods_uint32 &val ) ;
+
+    virtual void		get_str( string &val ) ;
+    virtual void		get_url( string &val ) ;
+
+    virtual void		get_opaque( char *val, unsigned int len ) ;
+    virtual void		get_int( int &val ) ;
+
+    virtual void		get_vector( char **val, unsigned int &num,
+					    Vector &vec ) ;
+    virtual void		get_vector( char **val, unsigned int &num,
+					    int width, Vector &vec ) ;
+
+    virtual void		dump(ostream &strm) const ;
+} ;
+
+} // namespace libdap
+
+#endif // I_XDRStreamUnMarshaller_h
+
diff --git a/XDRUtils.cc b/XDRUtils.cc
new file mode 100644
index 0000000..33a49bb
--- /dev/null
+++ b/XDRUtils.cc
@@ -0,0 +1,179 @@
+// XDRUtils.cc
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#include "XDRUtils.h"
+#include "debug.h"
+#include "Str.h"
+
+using namespace libdap ;
+
+// This function is used to allocate memory for, and initialize, a new XDR
+// pointer. It sets the stream associated with the (XDR *) to STREAM.
+//
+// NB: STREAM is not one of the C++/libg++ iostream classes; it is a (FILE
+// *).
+
+//  These func's moved to xdrutil_ppc.* under the PPC as explained there
+#ifndef __POWERPC__
+XDR *
+new_xdrstdio(FILE *stream, enum xdr_op xop)
+{
+    XDR *xdr = new XDR;
+
+    xdrstdio_create(xdr, stream, xop);
+
+    return xdr;
+}
+
+XDR *
+set_xdrstdio(XDR *xdr, FILE *stream, enum xdr_op xop)
+{
+    xdrstdio_create(xdr, stream, xop);
+
+    return xdr;
+}
+
+// Delete an XDR pointer allocated using the above function. Do not close the
+// associated FILE pointer.
+
+void
+delete_xdrstdio(XDR *xdr)
+{
+    xdr_destroy(xdr);
+
+    delete xdr; xdr = 0;
+}
+#endif
+
+// This function is used to en/decode Str and Url type variables. It is
+// defined as extern C since it is passed via function pointers to routines
+// in the xdr library where it is executed. This function is defined so
+// that Str and Url have an en/decoder which takes exactly two arguments: an
+// XDR * and a string reference.
+//
+// NB: this function is *not* used for arrays (i.e., it is not the function
+// referenced by BaseType's _xdr_coder field when the object is a Str or Url.
+// Also note that \e max_str_len is an obese number but that really does not
+// matter; xdr_string() would never actually allocate that much memory unless
+// a string that size was sent from the server.
+// Returns: XDR's bool_t; TRUE if no errors are detected, FALSE
+// otherwise. The formal parameter BUF is modified as a side effect.
+
+extern "C" bool_t
+xdr_str(XDR *xdrs, string &buf)
+{
+    DBG(cerr << "In xdr_str, xdrs: " << xdrs << endl);
+
+    switch (xdrs->x_op) {
+    case XDR_ENCODE: { // BUF is a pointer to a (string *)
+            const char *out_tmp = buf.c_str();
+
+            return xdr_string(xdrs, (char **)&out_tmp, max_str_len);
+        }
+
+    case XDR_DECODE: {
+            char *in_tmp = NULL;
+
+            bool_t stat = xdr_string(xdrs, &in_tmp, max_str_len);
+            if (!stat)
+                return stat;
+
+            buf = in_tmp;
+
+            free(in_tmp);
+
+            return stat;
+        }
+
+    default:
+        return 0;
+    }
+}
+
+namespace libdap {
+
+/** The <tt>xdr_coder</tt> function (also "filter primitive") is used to
+    encode and decode each element in a multiple element data
+    structure.  These functions are used to convert data to and from
+    its local representation to the XDR representation, which is
+    used to transmit and receive the data.  See <tt>man xdr</tt> for more
+    information about the available XDR filter primitives.
+
+    \note This class data is only used for multiple element data
+    types.  The simple data types (Int, Float, and so on), are
+    translated directly.
+
+    \note Even though Byte is a cardinal type, xdr_char is <i>not</i>
+    used to transport Byte arrays over the network. Instead, Byte is
+    a special case handled in Array.
+
+    @brief Returns a function used to encode elements of an array.
+    @return A C function used to encode data in the XDR format.
+*/
+xdrproc_t
+XDRUtils::xdr_coder( const Type &t )
+{
+    switch( t )
+    {
+	case dods_int16_c:
+	    return (xdrproc_t)XDR_INT16 ;
+	    break ;
+	case dods_uint16_c:
+	    return (xdrproc_t)XDR_UINT16 ;
+	    break ;
+	case dods_int32_c:
+	    return (xdrproc_t)XDR_INT32 ;
+	    break ;
+	case dods_uint32_c:
+	    return (xdrproc_t)XDR_UINT32 ;
+	    break ;
+	case dods_float32_c:
+	    return (xdrproc_t)XDR_FLOAT32 ;
+	    break ;
+	case dods_float64_c:
+	    return (xdrproc_t)XDR_FLOAT64 ;
+	    break ;
+	case dods_byte_c:
+	case dods_str_c:
+	case dods_url_c:
+	case dods_array_c:
+	case dods_structure_c:
+	case dods_sequence_c:
+	case dods_grid_c:
+	default:
+	    return NULL ;
+	    break ;
+    }
+}
+
+} // namespace libdap
+
diff --git a/XDRUtils.h b/XDRUtils.h
new file mode 100644
index 0000000..437fa96
--- /dev/null
+++ b/XDRUtils.h
@@ -0,0 +1,71 @@
+// XDRUtils.h
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: Patrick West <pwest at ucar.edu>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      pwest       Patrick West <pwest at ucar.edu>
+
+#ifndef S_XDRUtils_h
+#define S_XDRUtils_h 1
+
+#include <cstdio>
+#include "xdr-datatypes.h"
+#include "BaseType.h"
+
+#define xdr_proc_t int *
+
+//  These func's moved to xdrutil_ppc.* under the PPC as explained there
+#ifdef __POWERPC__
+extern "C" XDR *new_xdrstdio(FILE *stream, enum xdr_op xop);
+extern "C" XDR *set_xdrstdio(XDR *xdr, FILE *stream, enum xdr_op xop);
+extern "C" void delete_xdrstdio(XDR *xdr);
+#else
+XDR *new_xdrstdio(FILE *stream, enum xdr_op xop);
+XDR *set_xdrstdio(XDR *xdr, FILE *stream, enum xdr_op xop);
+void delete_xdrstdio(XDR *xdr);
+#endif
+
+extern "C" bool_t xdr_str(XDR *xdrs, string &buf);
+
+namespace libdap
+{
+
+class XDRUtils
+{
+private:			XDRUtils() {}
+public:
+    // xdr_coder is used as an argument to xdr procedures that encode groups
+    // of things (e.g., xdr_array()). Each leaf class's constructor must set
+    // this.
+    static xdrproc_t		xdr_coder( const Type &t ) ;
+} ;
+
+} // namespace libdap
+
+#endif // S_XDRUtils_h
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..dd515b0
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,1030 @@
+# generated automatically by aclocal 1.11 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.65],,
+[m4_warning([this file was generated for autoconf 2.65.
+You have another version of autoconf.  It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version.  Point them to the right macro.
+m4_if([$1], [1.11], [],
+      [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too.  Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+  [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory.  The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run.  This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+#    fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+#    fails if $ac_aux_dir is absolute,
+#    fails when called from a subdirectory in a VPATH build with
+#          a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir.  In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir.  That would be:
+#   am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+#   MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH.  The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL                                            -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE],  [AC_FATAL([$0: invalid condition: $1])],
+	[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+  $1_TRUE=
+  $1_FALSE='#'
+else
+  $1_TRUE='#'
+  $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+  AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery.  Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
+       [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+       [$1], UPC,  [depcc="$UPC"  am_compiler_list=],
+       [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
+                   [depcc="$$1"   am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+               [am_cv_$1_dependencies_compiler_type],
+[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_$1_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
+  fi
+  am__universal=false
+  m4_case([$1], [CC],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac],
+    [CXX],
+    [case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac])
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_$1_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking.              -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`AS_DIRNAME("$mf")`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`AS_DIRNAME(["$file"])`
+      AS_MKDIR_P([$dirpart/$fdir])
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled.  FIXME.  This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+     [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+     [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 8
+
+# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
+AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
+
+# Do all the work for Automake.                             -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much.  Some checks are only needed if
+# your package does certain things.  But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out.  PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition.  After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names.  We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+  [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+	      [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+			     [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+		  [_AM_DEPENDENCIES(CC)],
+		  [define([AC_PROG_CC],
+			  defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+		  [_AM_DEPENDENCIES(CXX)],
+		  [define([AC_PROG_CXX],
+			  defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+		  [_AM_DEPENDENCIES(OBJC)],
+		  [define([AC_PROG_OBJC],
+			  defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+  [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion.  Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated.  The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+AC_SUBST(install_sh)])
+
+# Copyright (C) 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# Check whether the underlying file-system supports filenames
+# with a leading dot.  For instance MS-DOS doesn't.
+AC_DEFUN([AM_SET_LEADING_DOT],
+[rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+AC_SUBST([am__leading_dot])])
+
+# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_PROG_LEX
+# -----------
+# Autoconf leaves LEX=: if lex or flex can't be found.  Change that to a
+# "missing" invocation, for better error output.
+AC_DEFUN([AM_PROG_LEX],
+[AC_PREREQ(2.50)dnl
+AC_REQUIRE([AM_MISSING_HAS_RUN])dnl
+AC_REQUIRE([AC_PROG_LEX])dnl
+if test "$LEX" = :; then
+  LEX=${am_missing_run}flex
+fi])
+
+# Check to see how 'make' treats includes.	            -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+AC_MSG_CHECKING([for style of include used by $am_make])
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p.  We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+  [[\\/$]]* | ?:[[\\/]]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling.                     -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME.  Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane.    -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[[\\\"\#\$\&\'\`$am_lf]]*)
+    AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+  *[[\\\"\#\$\&\'\`$am_lf\ \	]]*)
+    AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$[*]" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$[*]" != "X $srcdir/configure conftest.file" \
+      && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      AC_MSG_ERROR([ls -t appears to fail.  Make sure there is not a broken
+alias in your environment])
+   fi
+
+   test "$[2]" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries.  This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+  AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball.                            -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+#     tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+#     $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [m4_case([$1], [ustar],, [pax],,
+              [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+  case $_am_tool in
+  gnutar)
+    for _am_tar in tar gnutar gtar;
+    do
+      AM_RUN_LOG([$_am_tar --version]) && break
+    done
+    am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+    am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+    am__untar="$_am_tar -xf -"
+    ;;
+  plaintar)
+    # Must skip GNU tar: if it does not support --format= it doesn't create
+    # ustar tarball either.
+    (tar --version) >/dev/null 2>&1 && continue
+    am__tar='tar chf - "$$tardir"'
+    am__tar_='tar chf - "$tardir"'
+    am__untar='tar xf -'
+    ;;
+  pax)
+    am__tar='pax -L -x $1 -w "$$tardir"'
+    am__tar_='pax -L -x $1 -w "$tardir"'
+    am__untar='pax -r'
+    ;;
+  cpio)
+    am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+    am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+    am__untar='cpio -i -H $1 -d'
+    ;;
+  none)
+    am__tar=false
+    am__tar_=false
+    am__untar=false
+    ;;
+  esac
+
+  # If the value was cached, stop now.  We just wanted to have am__tar
+  # and am__untar set.
+  test -n "${am_cv_prog_tar_$1}" && break
+
+  # tar/untar a dummy directory, and stop if the command works
+  rm -rf conftest.dir
+  mkdir conftest.dir
+  echo GrepMe > conftest.dir/file
+  AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+  rm -rf conftest.dir
+  if test -s conftest.tar; then
+    AM_RUN_LOG([$am__untar <conftest.tar])
+    grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+  fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([gl/m4/00gnulib.m4])
+m4_include([gl/m4/alloca.m4])
+m4_include([gl/m4/btowc.m4])
+m4_include([gl/m4/codeset.m4])
+m4_include([gl/m4/configmake.m4])
+m4_include([gl/m4/extensions.m4])
+m4_include([gl/m4/fcntl-o.m4])
+m4_include([gl/m4/glibc21.m4])
+m4_include([gl/m4/gnulib-common.m4])
+m4_include([gl/m4/gnulib-comp.m4])
+m4_include([gl/m4/gnulib-tool.m4])
+m4_include([gl/m4/include_next.m4])
+m4_include([gl/m4/langinfo_h.m4])
+m4_include([gl/m4/localcharset.m4])
+m4_include([gl/m4/locale-fr.m4])
+m4_include([gl/m4/locale-ja.m4])
+m4_include([gl/m4/locale-zh.m4])
+m4_include([gl/m4/longlong.m4])
+m4_include([gl/m4/malloc.m4])
+m4_include([gl/m4/mbrtowc.m4])
+m4_include([gl/m4/mbsinit.m4])
+m4_include([gl/m4/mbstate_t.m4])
+m4_include([gl/m4/multiarch.m4])
+m4_include([gl/m4/nl_langinfo.m4])
+m4_include([gl/m4/regex.m4])
+m4_include([gl/m4/ssize_t.m4])
+m4_include([gl/m4/stdbool.m4])
+m4_include([gl/m4/stddef_h.m4])
+m4_include([gl/m4/stdint.m4])
+m4_include([gl/m4/stdlib_h.m4])
+m4_include([gl/m4/unistd_h.m4])
+m4_include([gl/m4/warn-on-use.m4])
+m4_include([gl/m4/wchar_h.m4])
+m4_include([gl/m4/wchar_t.m4])
+m4_include([gl/m4/wcrtomb.m4])
+m4_include([gl/m4/wctype_h.m4])
+m4_include([gl/m4/wint_t.m4])
+m4_include([conf/acinclude.m4])
+m4_include([conf/check_zlib.m4])
+m4_include([conf/cppunit.m4])
+m4_include([conf/libtool.m4])
+m4_include([conf/ltoptions.m4])
+m4_include([conf/ltsugar.m4])
+m4_include([conf/ltversion.m4])
+m4_include([conf/lt~obsolete.m4])
+m4_include([conf/pkg.m4])
diff --git a/ce_expr.lex b/ce_expr.lex
new file mode 100644
index 0000000..12ae27c
--- /dev/null
+++ b/ce_expr.lex
@@ -0,0 +1,219 @@
+
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-1999
+*/ 
+
+/*
+  Scanner for constraint expressions. The scanner returns tokens for each of
+  the relational and selection operators. It requires GNU flex version 2.5.2
+  or newer.
+
+  The scanner is not reentrant, but can share a name space with other
+  scanners. 
+
+   Note:
+   1) The `defines' file expr.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `exprlex'.
+   3) When bison builds the expr.tab.h file, it uses `expr' instead of `yy'
+   for variable name prefixes (e.g., yylval --> exprlval).
+
+  jhrg 9/5/95
+*/
+
+%{
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: ce_expr.lex 20716 2009-04-08 19:50:54Z jimg $"};
+
+#include <cstdio>
+#include <string>
+#include <cstring>
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_DECL int ce_exprlex YY_PROTO(( void ))
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning constraint expression text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+#include "Error.h"
+#include "parser.h"
+#include "expr.h"
+#include "RValue.h"
+#include "ce_expr.tab.hh"
+#include "escaping.h"
+
+using namespace libdap ;
+
+static void store_id();
+static void store_str();
+static void store_op(int op);
+
+%}
+
+%option noyywrap
+%option prefix="ce_expr"
+%option outfile="lex.ce_expr.cc"
+
+%x quote
+    
+/* In the DAS and DDS parsers I removed the INT and FLOAT lexemes. However,
+   not having them here complicates parsing since you must check to see if a
+   word is a number (like 2.3) or a variable called `2.3.' I'm assuming that
+   people will always put some characters in variable names (e.g., they'll
+   use `2300.7%20MHz' and not just `2300.7'). If that turns out to be a bad
+   assumption, the we'll have to put more code in the parser to figure out
+   what exactly each word is; is it a constant or a variable name. Time will
+   tell. 10/31/2001 jhrg */
+
+NAN		[Nn][Aa][Nn]
+INF		[Ii][Nn][Ff]
+/* See das.lex for comments about the characters allowed in a WORD.
+   10/31/2001 jhrg 
+
+   I've added '*' to the set of characters in a WORD for both the DDS and DAS
+   scanners, but not here because it'll conflict with the url dereference
+   operator. 6/10/2002 jhrg
+*/
+
+SCAN_WORD       [-+a-zA-Z0-9_/%.\\][-+a-zA-Z0-9_/%.\\#]*
+
+SCAN_EQUAL	=
+SCAN_NOT_EQUAL	!=
+SCAN_GREATER	>
+SCAN_GREATER_EQL >=
+SCAN_LESS	<
+SCAN_LESS_EQL	<=
+SCAN_REGEXP	=~
+
+NEVER		[^\-+a-zA-Z0-9_/%.\\#:,(){}[\]&<>=~]
+
+%%
+
+"["    	    	return (int)*yytext;
+"]"    	    	return (int)*yytext;
+":"    	    	return (int)*yytext;
+","		return (int)*yytext;
+"&"		return (int)*yytext;
+"("		return (int)*yytext;
+")"		return (int)*yytext;
+"{"		return (int)*yytext;
+"}"		return (int)*yytext;
+
+{SCAN_WORD}	store_id(); return SCAN_WORD;
+
+{SCAN_EQUAL}	store_op(SCAN_EQUAL); return SCAN_EQUAL;
+{SCAN_NOT_EQUAL} store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+{SCAN_GREATER}	store_op(SCAN_GREATER); return SCAN_GREATER;
+{SCAN_GREATER_EQL} store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+{SCAN_LESS}	store_op(SCAN_LESS); return SCAN_LESS;
+{SCAN_LESS_EQL}	store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+{SCAN_REGEXP}	store_op(SCAN_REGEXP); return SCAN_REGEXP;
+
+[ \t\r\n]+
+<INITIAL><<EOF>> yy_init = 1; yyterminate();
+
+\"		BEGIN(quote); yymore();
+<quote>[^"\\]*  yymore(); /*"*/
+<quote>\\.	yymore();
+<quote>\"	{ 
+    		  BEGIN(INITIAL); 
+                  store_str();
+		  return SCAN_STR;
+                }
+<quote><<EOF>>	{
+                  char msg[256];
+		  sprintf(msg, "Unterminated quote\n");
+		  YY_FATAL_ERROR(msg);
+                }
+
+{NEVER}         {
+                  if (yytext) {	/* suppress msgs about `' chars */
+                    fprintf(stderr, "Character `%c' is not", *yytext);
+                    fprintf(stderr, " allowed and has been ignored\n");
+		  }
+		}
+%%
+
+// Three glue routines for string scanning. These are not declared in the
+// header expr.tab.h nor is YY_BUFFER_STATE. Including these here allows them
+// to see the type definitions in lex.expr.c (where YY_BUFFER_STATE is
+// defined) and allows callers to declare them (since callers outside of this
+// file cannot declare the YY_BUFFER_STATE variable). Note that I changed the
+// name of the expr_scan_string function to expr_string because C++ cannot
+// distinguish by return type. 1/12/99 jhrg
+
+void *
+ce_expr_string(const char *str)
+{
+    return (void *)ce_expr_scan_string(str);
+}
+
+void
+ce_expr_switch_to_buffer(void *buf)
+{
+    ce_expr_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+ce_expr_delete_buffer(void *buf)
+{
+    ce_expr_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+static void
+store_id()
+{
+    strncpy(ce_exprlval.id, www2id(string(yytext)).c_str(), ID_MAX-1);
+    ce_exprlval.id[ID_MAX-1] = '\0';
+}
+
+static void
+store_str()
+{
+    // transform %20 to a space. 7/11/2001 jhrg
+    string *s = new string(www2id(string(yytext)));  // XXX memory leak?
+
+    if (*s->begin() == '\"' && *(s->end()-1) == '\"') {
+	s->erase(s->begin());
+	s->erase(s->end()-1);
+    }
+
+    ce_exprlval.val.type = dods_str_c;
+    ce_exprlval.val.v.s = s;
+}
+
+static void
+store_op(int op)
+{
+    ce_exprlval.op = op;
+}
+
diff --git a/ce_expr.tab.cc b/ce_expr.tab.cc
new file mode 100644
index 0000000..606a454
--- /dev/null
+++ b/ce_expr.tab.cc
@@ -0,0 +1,2649 @@
+/* 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 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse ce_exprparse
+#define yylex   ce_exprlex
+#define yyerror ce_exprerror
+#define yylval  ce_exprlval
+#define yychar  ce_exprchar
+#define yydebug ce_exprdebug
+#define yynerrs ce_exprnerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_STR = 258,
+     SCAN_WORD = 259,
+     SCAN_EQUAL = 260,
+     SCAN_NOT_EQUAL = 261,
+     SCAN_GREATER = 262,
+     SCAN_GREATER_EQL = 263,
+     SCAN_LESS = 264,
+     SCAN_LESS_EQL = 265,
+     SCAN_REGEXP = 266
+   };
+#endif
+/* Tokens.  */
+#define SCAN_STR 258
+#define SCAN_WORD 259
+#define SCAN_EQUAL 260
+#define SCAN_NOT_EQUAL 261
+#define SCAN_GREATER 262
+#define SCAN_GREATER_EQL 263
+#define SCAN_LESS 264
+#define SCAN_LESS_EQL 265
+#define SCAN_REGEXP 266
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 41 "ce_expr.y"
+
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: ce_expr.y 21578 2009-10-02 16:26:26Z jimg $"};
+
+#include <cassert>
+#include <cstdlib>
+#include <string>
+#include <cstring>
+#include <stack>
+
+#include "debug.h"
+#include "escaping.h"
+
+#include "DDS.h"
+#include "ConstraintEvaluator.h"
+
+#include "BaseType.h"
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "Error.h"
+
+#include "util.h"
+#include "parser.h"
+#include "ce_parser.h"
+#include "expr.h"
+#include "RValue.h"
+
+using std::cerr;
+using std::endl;
+using namespace libdap ;
+
+#define EVALUATOR(arg) (static_cast<ce_parser_arg*>(arg)->get_eval())
+#define DDS(arg) (static_cast<ce_parser_arg*>(arg)->get_dds())
+
+#define YYPARSE_PARAM arg
+
+int ce_exprlex(void);		/* the scanner; see expr.lex */
+
+void ce_exprerror(const char *s);	/* easier to overload than to use stdarg... */
+void ce_exprerror(const char *s, const char *s2);
+void no_such_func(char *name);
+void no_such_ident(char *name, char *word);
+
+void ce_exprerror(const string &s); 
+void ce_exprerror(const string &s, const string &s2);
+void no_such_func(const string &name);
+void no_such_ident(const string &name, const string &word);
+
+int_list *make_array_index(value &i1, value &i2, value &i3);
+int_list *make_array_index(value &i1, value &i2);
+int_list *make_array_index(value &i1);
+int_list_list *make_array_indices(int_list *index);
+int_list_list *append_array_index(int_list_list *indices, int_list *index);
+
+void delete_array_indices(int_list_list *indices);
+bool bracket_projection(DDS &table, const char *name, 
+			int_list_list *indices);
+
+void process_array_indices(BaseType *variable, int_list_list *indices); 
+void process_grid_indices(BaseType *variable, int_list_list *indices); 
+void process_sequence_indices(BaseType *variable, int_list_list *indices);
+
+/* Replace these with method calls. jhrg 8/31/06 */
+bool is_array_t(BaseType *variable);
+bool is_grid_t(BaseType *variable);
+bool is_sequence_t(BaseType *variable);
+
+BaseType *make_variable(ConstraintEvaluator &eval, const value &val);
+bool_func get_function(const ConstraintEvaluator &eval, const char *name);
+btp_func get_btp_function(const ConstraintEvaluator &eval, const char *name);
+proj_func get_proj_function(const ConstraintEvaluator &eval, const char *name);
+
+
+
+/* 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
+#line 130 "ce_expr.y"
+{
+    bool boolean;
+    int op;
+    char id[ID_MAX];
+
+    libdap::value val;               // value is defined in expr.h
+
+    libdap::bool_func b_func;
+    libdap::btp_func bt_func;
+
+    libdap::int_list *int_l_ptr;
+    libdap::int_list_list *int_ll_ptr;
+    
+    libdap::rvalue *rval_ptr;
+    libdap::rvalue_list *r_val_l_ptr;
+}
+/* Line 187 of yacc.c.  */
+#line 232 "ce_expr.tab.cc"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 245 "ce_expr.tab.cc"
+
+#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__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# 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 YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* 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)) \
+      + 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  13
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   60
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  21
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  19
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  44
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  67
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   266
+
+#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,    12,     2,
+      14,    15,     2,     2,    13,     2,     2,     2,     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,    18,     2,    19,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    16,     2,    17,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     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
+};
+
+#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,     6,     7,    11,    15,    17,    21,
+      23,    25,    27,    32,    34,    38,    44,    48,    50,    55,
+      57,    62,    64,    68,    70,    71,    73,    75,    77,    80,
+      83,    87,    89,    91,    93,    96,   100,   106,   114,   116,
+     118,   120,   122,   124,   126
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      22,     0,    -1,    -1,    24,    -1,    -1,    12,    23,    27,
+      -1,    24,    12,    27,    -1,    25,    -1,    25,    13,    24,
+      -1,    36,    -1,    26,    -1,    34,    -1,     4,    14,    32,
+      15,    -1,    28,    -1,    27,    12,    28,    -1,    30,    39,
+      16,    31,    17,    -1,    30,    39,    30,    -1,    29,    -1,
+       4,    14,    32,    15,    -1,    33,    -1,     4,    14,    32,
+      15,    -1,    30,    -1,    31,    13,    30,    -1,    31,    -1,
+      -1,     4,    -1,     3,    -1,    35,    -1,    36,    37,    -1,
+      35,    36,    -1,    35,    36,    37,    -1,     4,    -1,     3,
+      -1,    38,    -1,    37,    38,    -1,    18,     4,    19,    -1,
+      18,     4,    20,     4,    19,    -1,    18,     4,    20,     4,
+      20,     4,    19,    -1,     5,    -1,     6,    -1,     7,    -1,
+       8,    -1,     9,    -1,    10,    -1,    11,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   171,   171,   176,   178,   178,   182,   188,   189,   195,
+     223,   227,   233,   255,   256,   262,   271,   282,   288,   301,
+     302,   314,   321,   330,   335,   340,   371,   387,   392,   400,
+     406,   417,   418,   440,   444,   450,   462,   480,   506,   507,
+     508,   509,   510,   511,   512
+};
+#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", "SCAN_STR", "SCAN_WORD", "SCAN_EQUAL",
+  "SCAN_NOT_EQUAL", "SCAN_GREATER", "SCAN_GREATER_EQL", "SCAN_LESS",
+  "SCAN_LESS_EQL", "SCAN_REGEXP", "'&'", "','", "'('", "')'", "'{'", "'}'",
+  "'['", "']'", "':'", "$accept", "constraint_expr", "@1", "projection",
+  "proj_clause", "proj_function", "selection", "clause", "bool_function",
+  "r_value", "r_value_list", "arg_list", "id_or_const", "array_projection",
+  "array_proj_clause", "name", "array_indices", "array_index", "rel_op", 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,    38,    44,    40,    41,   123,   125,    91,    93,
+      58
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    21,    22,    22,    23,    22,    22,    24,    24,    25,
+      25,    25,    26,    27,    27,    28,    28,    28,    29,    30,
+      30,    31,    31,    32,    32,    33,    33,    34,    35,    35,
+      35,    36,    36,    37,    37,    38,    38,    38,    39,    39,
+      39,    39,    39,    39,    39
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     1,     0,     3,     3,     1,     3,     1,
+       1,     1,     4,     1,     3,     5,     3,     1,     4,     1,
+       4,     1,     3,     1,     0,     1,     1,     1,     2,     2,
+       3,     1,     1,     1,     2,     3,     5,     7,     1,     1,
+       1,     1,     1,     1,     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,    32,    31,     4,     0,     3,     7,    10,    11,    27,
+       9,    24,     0,     1,     0,     0,    31,    29,     0,    28,
+      33,    26,    25,    21,    23,     0,    19,    25,     5,    13,
+      17,     0,     6,     8,    30,     0,    34,    24,     0,    12,
+      24,     0,    38,    39,    40,    41,    42,    43,    44,     0,
+      35,     0,     0,    22,     0,    14,     0,    16,     0,    20,
+      20,     0,    36,     0,    15,     0,    37
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     4,    12,     5,     6,     7,    28,    29,    30,    23,
+      24,    25,    26,     8,     9,    10,    19,    20,    49
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -19
+static const yytype_int8 yypact[] =
+{
+       6,   -19,    -8,   -19,     8,     2,    15,   -19,   -19,     9,
+      24,    28,    30,   -19,    30,    32,   -19,    24,    39,    24,
+     -19,   -19,    31,   -19,    33,    29,   -19,    34,    35,   -19,
+     -19,    14,    35,   -19,    24,    19,   -19,    28,    28,   -19,
+      28,    30,   -19,   -19,   -19,   -19,   -19,   -19,   -19,     1,
+     -19,    45,    36,   -19,    37,   -19,    28,   -19,    21,   -19,
+       3,    -6,   -19,    46,   -19,    38,   -19
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -19,   -19,   -19,    40,   -19,   -19,    42,    12,   -19,   -12,
+      -2,   -10,   -19,   -19,   -19,    49,    43,   -18,   -19
+};
+
+/* 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 -19
+static const yytype_int8 yytable[] =
+{
+      31,    36,    31,   -18,    21,    22,    11,    38,    13,     1,
+       2,    64,     1,    16,    14,   -18,    36,    56,     3,    42,
+      43,    44,    45,    46,    47,    48,    53,    52,    15,    31,
+      54,    21,    22,    21,    27,     1,     2,    57,    50,    51,
+      62,    63,    18,    35,    39,    37,    38,    41,    40,    58,
+      65,    59,    60,    55,    61,    33,    32,    66,    17,     0,
+      34
+};
+
+static const yytype_int8 yycheck[] =
+{
+      12,    19,    14,     0,     3,     4,    14,    13,     0,     3,
+       4,    17,     3,     4,    12,    12,    34,    16,    12,     5,
+       6,     7,     8,     9,    10,    11,    38,    37,    13,    41,
+      40,     3,     4,     3,     4,     3,     4,    49,    19,    20,
+      19,    20,    18,     4,    15,    14,    13,    12,    14,     4,
+       4,    15,    15,    41,    56,    15,    14,    19,     9,    -1,
+      17
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     4,    12,    22,    24,    25,    26,    34,    35,
+      36,    14,    23,     0,    12,    13,     4,    36,    18,    37,
+      38,     3,     4,    30,    31,    32,    33,     4,    27,    28,
+      29,    30,    27,    24,    37,     4,    38,    14,    13,    15,
+      14,    12,     5,     6,     7,     8,     9,    10,    11,    39,
+      19,    20,    32,    30,    32,    28,    16,    30,     4,    15,
+      15,    31,    19,    20,    17,     4,    19
+};
+
+#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 (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 (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#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); \
+      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)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# 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)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  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, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#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)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} 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)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  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 (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| 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 (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  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;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* 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;
+
+  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;
+
+
+	/* 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),
+
+		    &yystacksize);
+
+	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);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + 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;
+
+  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];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 171 "ce_expr.y"
+    {
+		     DDS(arg)->mark_all(true);
+		     (yyval.boolean) = true;
+		 ;}
+    break;
+
+  case 4:
+#line 178 "ce_expr.y"
+    { DDS(arg)->mark_all(true); ;}
+    break;
+
+  case 5:
+#line 179 "ce_expr.y"
+    { 
+		     (yyval.boolean) = (yyvsp[(3) - (3)].boolean);
+		 ;}
+    break;
+
+  case 6:
+#line 183 "ce_expr.y"
+    {
+		     (yyval.boolean) = (yyvsp[(1) - (3)].boolean) && (yyvsp[(3) - (3)].boolean);
+		 ;}
+    break;
+
+  case 8:
+#line 190 "ce_expr.y"
+    {
+		    (yyval.boolean) = (yyvsp[(1) - (3)].boolean) && (yyvsp[(3) - (3)].boolean);
+		;}
+    break;
+
+  case 9:
+#line 196 "ce_expr.y"
+    { 
+		    BaseType *var = DDS(arg)->var((yyvsp[(1) - (1)].id));
+		    if (var) {
+			DBG(cerr << "Marking " << (yyvsp[(1) - (1)].id) << endl);
+			(yyval.boolean) = DDS(arg)->mark((yyvsp[(1) - (1)].id), true);
+			DBG(cerr << "result: " << (yyval.boolean) << endl);
+		    }
+		    else {
+			no_such_ident((yyvsp[(1) - (1)].id), "identifier");
+		    }
+		;}
+    break;
+
+  case 10:
+#line 224 "ce_expr.y"
+    {
+		    (yyval.boolean) = (yyvsp[(1) - (1)].boolean);
+		;}
+    break;
+
+  case 11:
+#line 228 "ce_expr.y"
+    {
+		    (yyval.boolean) = (yyvsp[(1) - (1)].boolean);
+		;}
+    break;
+
+  case 12:
+#line 234 "ce_expr.y"
+    {
+		    proj_func p_f = 0;
+		    btp_func f = 0;
+
+		    if ((f = get_btp_function(*(EVALUATOR(arg)), (yyvsp[(1) - (4)].id)))) {
+			EVALUATOR(arg)->append_clause(f, (yyvsp[(3) - (4)].r_val_l_ptr));
+			(yyval.boolean) = true;
+		    }
+		    else if ((p_f = get_proj_function(*(EVALUATOR(arg)), (yyvsp[(1) - (4)].id)))) {
+		        DDS &dds = dynamic_cast<DDS&>(*(DDS(arg)));
+			BaseType **args = build_btp_args( (yyvsp[(3) - (4)].r_val_l_ptr), dds );
+			(*p_f)(((yyvsp[(3) - (4)].r_val_l_ptr)) ? (yyvsp[(3) - (4)].r_val_l_ptr)->size():0, args, dds, *(EVALUATOR(arg)));
+			delete[] args;
+			(yyval.boolean) = true;
+		    }
+		    else {
+			no_such_func((yyvsp[(1) - (4)].id));
+		    }
+		;}
+    break;
+
+  case 14:
+#line 257 "ce_expr.y"
+    {
+		    (yyval.boolean) = (yyvsp[(1) - (3)].boolean) && (yyvsp[(3) - (3)].boolean);
+		;}
+    break;
+
+  case 15:
+#line 263 "ce_expr.y"
+    {
+		    if ((yyvsp[(1) - (5)].rval_ptr)) {
+			EVALUATOR(arg)->append_clause((yyvsp[(2) - (5)].op), (yyvsp[(1) - (5)].rval_ptr), (yyvsp[(4) - (5)].r_val_l_ptr));
+			(yyval.boolean) = true;
+		    }
+		    else
+			(yyval.boolean) = false;
+		;}
+    break;
+
+  case 16:
+#line 272 "ce_expr.y"
+    {
+		    if ((yyvsp[(1) - (3)].rval_ptr)) {
+			rvalue_list *rv = new rvalue_list;
+			rv->push_back((yyvsp[(3) - (3)].rval_ptr));
+			EVALUATOR(arg)->append_clause((yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].rval_ptr), rv);
+			(yyval.boolean) = true;
+		    }
+		    else
+			(yyval.boolean) = false;
+		;}
+    break;
+
+  case 17:
+#line 283 "ce_expr.y"
+    {
+		    (yyval.boolean) = (yyvsp[(1) - (1)].boolean);
+		;}
+    break;
+
+  case 18:
+#line 289 "ce_expr.y"
+    {
+		   bool_func b_func = get_function((*EVALUATOR(arg)), (yyvsp[(1) - (4)].id));
+		   if (!b_func) {
+		       no_such_func((yyvsp[(1) - (4)].id));
+		   }
+		   else {
+		       EVALUATOR(arg)->append_clause(b_func, (yyvsp[(3) - (4)].r_val_l_ptr));
+		       (yyval.boolean) = true;
+		   }
+	       ;}
+    break;
+
+  case 20:
+#line 303 "ce_expr.y"
+    {
+		    btp_func func = get_btp_function((*EVALUATOR(arg)), (yyvsp[(1) - (4)].id));
+		    if (func) {
+			(yyval.rval_ptr) = new rvalue(func, (yyvsp[(3) - (4)].r_val_l_ptr));
+		    } 
+		    else {  		
+			no_such_func((yyvsp[(1) - (4)].id));
+		    }
+		;}
+    break;
+
+  case 21:
+#line 315 "ce_expr.y"
+    {
+		    if ((yyvsp[(1) - (1)].rval_ptr))
+			(yyval.r_val_l_ptr) = make_rvalue_list((yyvsp[(1) - (1)].rval_ptr));
+		    else
+			(yyval.r_val_l_ptr) = 0;
+		;}
+    break;
+
+  case 22:
+#line 322 "ce_expr.y"
+    {
+		    if ((yyvsp[(1) - (3)].r_val_l_ptr) && (yyvsp[(3) - (3)].rval_ptr))
+			(yyval.r_val_l_ptr) = append_rvalue_list((yyvsp[(1) - (3)].r_val_l_ptr), (yyvsp[(3) - (3)].rval_ptr));
+		    else
+			(yyval.r_val_l_ptr) = 0;
+		;}
+    break;
+
+  case 23:
+#line 331 "ce_expr.y"
+    {  
+		  (yyval.r_val_l_ptr) = (yyvsp[(1) - (1)].r_val_l_ptr);
+	      ;}
+    break;
+
+  case 24:
+#line 335 "ce_expr.y"
+    { 
+		  (yyval.r_val_l_ptr) = 0; 
+	      ;}
+    break;
+
+  case 25:
+#line 341 "ce_expr.y"
+    { 
+		    BaseType *btp = DDS(arg)->var(www2id(string((yyvsp[(1) - (1)].id))));
+		    if (btp) {
+                        btp->set_in_selection(true);
+                        (yyval.rval_ptr) = new rvalue(btp);
+		    }
+		    else {
+			value new_val;
+			if (check_int32((yyvsp[(1) - (1)].id))) {
+			    new_val.type = dods_int32_c;
+			    new_val.v.i = atoi((yyvsp[(1) - (1)].id));
+			}
+			else if (check_uint32((yyvsp[(1) - (1)].id))) {
+			    new_val.type = dods_uint32_c;
+			    new_val.v.ui = atoi((yyvsp[(1) - (1)].id));
+			}
+			else if (check_float64((yyvsp[(1) - (1)].id))) {
+			    new_val.type = dods_float64_c;
+			    new_val.v.f = atof((yyvsp[(1) - (1)].id));
+			}
+			else {
+			    new_val.type = dods_str_c;
+			    new_val.v.s = new string((yyvsp[(1) - (1)].id));
+			}
+			BaseType *btp = make_variable((*EVALUATOR(arg)), new_val); 
+			// *** test for btp == null
+			// delete new_val.v.s; // Str::val2buf copies the value.
+			(yyval.rval_ptr) = new rvalue(btp);
+		    }
+		;}
+    break;
+
+  case 26:
+#line 372 "ce_expr.y"
+    {
+                    if ((yyvsp[(1) - (1)].val).type != dods_str_c || (yyvsp[(1) - (1)].val).v.s == 0 || (yyvsp[(1) - (1)].val).v.s->empty())
+                        ce_exprerror("Malformed string", "");
+                        
+                    BaseType *var = DDS(arg)->var(*((yyvsp[(1) - (1)].val).v.s));
+                    if (var) {
+                        (yyval.rval_ptr) = new rvalue(var);
+                    }
+                    else {
+                        var = make_variable((*EVALUATOR(arg)), (yyvsp[(1) - (1)].val)); 
+                        (yyval.rval_ptr) = new rvalue(var);
+                    }
+                ;}
+    break;
+
+  case 27:
+#line 388 "ce_expr.y"
+    {
+                    (yyval.boolean) = (*DDS(arg)).mark((yyvsp[(1) - (1)].id), true);
+                ;}
+    break;
+
+  case 28:
+#line 393 "ce_expr.y"
+    {
+                    if (!bracket_projection((*DDS(arg)), (yyvsp[(1) - (2)].id), (yyvsp[(2) - (2)].int_ll_ptr)))
+                      no_such_ident((yyvsp[(1) - (2)].id), "array, grid or sequence");
+
+                    strncpy((yyval.id), (yyvsp[(1) - (2)].id), ID_MAX-1);
+                    (yyval.id)[ID_MAX-1] = '\0';
+                ;}
+    break;
+
+  case 29:
+#line 401 "ce_expr.y"
+    {
+                    string name = string((yyvsp[(1) - (2)].id)) + string ((yyvsp[(2) - (2)].id));
+                    strncpy((yyval.id), name.c_str(), ID_MAX-1);
+                    (yyval.id)[ID_MAX-1] = '\0';
+                ;}
+    break;
+
+  case 30:
+#line 407 "ce_expr.y"
+    {
+                    string name = string((yyvsp[(1) - (3)].id)) + string ((yyvsp[(2) - (3)].id));
+                    if (!bracket_projection((*DDS(arg)), name.c_str(), (yyvsp[(3) - (3)].int_ll_ptr)))
+                      no_such_ident(name.c_str(), "array, grid or sequence");
+
+                    strncpy((yyval.id), name.c_str(), ID_MAX-1);
+                    (yyval.id)[ID_MAX-1] = '\0';
+                ;}
+    break;
+
+  case 32:
+#line 419 "ce_expr.y"
+    {
+                    if ((yyvsp[(1) - (1)].val).type != dods_str_c || (yyvsp[(1) - (1)].val).v.s == 0 || (yyvsp[(1) - (1)].val).v.s->empty())
+                        ce_exprerror("Malformed string", "");
+                        
+                    strncpy((yyval.id), www2id(*((yyvsp[(1) - (1)].val).v.s)).c_str(), ID_MAX-1);
+                    // delete the string? ***
+                    (yyval.id)[ID_MAX-1] = '\0';
+/*
+                    BaseType *var = DDS(arg)->var(*($1.v.s));
+                    if (var) {
+                        DBG(cerr << "Marking " << $1 << endl);
+                        $$ = DDS(arg)->mark(*($1.v.s), true);
+                        DBG(cerr << "result: " << $$ << endl);
+                    }
+                    else {
+                        no_such_ident(*($1.v.s), "identifier");
+                    }
+*/
+                ;}
+    break;
+
+  case 33:
+#line 441 "ce_expr.y"
+    {
+		    (yyval.int_ll_ptr) = make_array_indices((yyvsp[(1) - (1)].int_l_ptr));
+		;}
+    break;
+
+  case 34:
+#line 445 "ce_expr.y"
+    {
+		    (yyval.int_ll_ptr) = append_array_index((yyvsp[(1) - (2)].int_ll_ptr), (yyvsp[(2) - (2)].int_l_ptr));
+		;}
+    break;
+
+  case 35:
+#line 451 "ce_expr.y"
+    {
+		    if (!check_uint32((yyvsp[(2) - (3)].id))) {
+			string msg = "The word `";
+			msg += string((yyvsp[(2) - (3)].id)) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    value i;
+		    i.type = dods_uint32_c;
+		    i.v.i = atoi((yyvsp[(2) - (3)].id));
+		    (yyval.int_l_ptr) = make_array_index(i);
+		;}
+    break;
+
+  case 36:
+#line 463 "ce_expr.y"
+    {
+		    if (!check_uint32((yyvsp[(2) - (5)].id))) {
+			string msg = "The word `";
+			msg += string((yyvsp[(2) - (5)].id)) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    if (!check_uint32((yyvsp[(4) - (5)].id))) {
+			string msg = "The word `";
+			msg += string((yyvsp[(4) - (5)].id)) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    value i,j;
+		    i.type = j.type = dods_uint32_c;
+		    i.v.i = atoi((yyvsp[(2) - (5)].id));
+		    j.v.i = atoi((yyvsp[(4) - (5)].id));
+		    (yyval.int_l_ptr) = make_array_index(i, j);
+		;}
+    break;
+
+  case 37:
+#line 481 "ce_expr.y"
+    {
+		    if (!check_uint32((yyvsp[(2) - (7)].id))) {
+			string msg = "The word `";
+			msg += string((yyvsp[(2) - (7)].id)) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    if (!check_uint32((yyvsp[(4) - (7)].id))) {
+			string msg = "The word `";
+			msg += string((yyvsp[(4) - (7)].id)) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    if (!check_uint32((yyvsp[(6) - (7)].id))) {
+			string msg = "The word `";
+			msg += string((yyvsp[(6) - (7)].id)) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    value i, j, k;
+		    i.type = j.type = k.type = dods_uint32_c;
+		    i.v.i = atoi((yyvsp[(2) - (7)].id));
+		    j.v.i = atoi((yyvsp[(4) - (7)].id));
+		    k.v.i = atoi((yyvsp[(6) - (7)].id));
+		    (yyval.int_l_ptr) = make_array_index(i, j, k);
+		;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1869 "ce_expr.tab.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* 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 (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 (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  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);
+	  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;
+
+  /* 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;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* 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 (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* 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);
+      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);
+}
+
+
+#line 515 "ce_expr.y"
+
+
+// All these error reporting function now throw instances of Error. The expr
+// parser no longer returns an error code to indicate and error. 2/16/2000
+// jhrg.
+
+void
+ce_exprerror(const string &s)
+{ 
+    ce_exprerror(s.c_str());
+}
+
+void
+ce_exprerror(const char *s)
+{
+    // cerr << "Expression parse error: " << s << endl;
+    string msg = "Constraint expression parse error: " + (string)s;
+    throw Error(malformed_expr, msg);
+}
+
+void
+ce_exprerror(const string &s, const string &s2)
+{
+    ce_exprerror(s.c_str(), s2.c_str());
+}
+
+void
+ce_exprerror(const char *s, const char *s2)
+{
+    string msg = "Constraint expression parse error: " + (string)s + ": " 
+	+ (string)s2;
+    throw Error(malformed_expr, msg);
+}
+
+void
+no_such_ident(const string &name, const string &word)
+{
+    string msg = "No such " + word + " in dataset";
+    ce_exprerror(msg.c_str(), name);
+}
+
+void
+no_such_ident(char *name, char *word)
+{
+    string msg = "No such " + (string)word + " in dataset";
+    ce_exprerror(msg.c_str(), name);
+}
+
+void
+no_such_func(const string &name)
+{
+    no_such_func(name.c_str());
+}
+
+void
+no_such_func(char *name)
+{
+    ce_exprerror("Not a registered function", name);
+}
+
+/* If we're calling this, assume var is not a Sequence. But assume that the
+   name contains a dot and it's a separator. Look for the rightmost dot and
+   then look to see if the name to the left is a sequence. Return a pointer
+   to the sequence if it is otherwise return null. Uses tail-recursion to
+   'walk' back from right to left looking at each dot. This way the sequence
+   will be found even if there are structures between the field and the
+   Sequence. */
+static Sequence *
+parent_is_sequence(DDS &table, const string &n)
+{
+    string::size_type dotpos = n.find_last_of('.');
+    if (dotpos == string::npos)
+	return 0;
+
+    string s = n.substr(0, dotpos);
+    
+    // If the thing returned by table.var is not a Sequence, this cast
+    // will yield null.
+    Sequence *seq = dynamic_cast<Sequence*>(table.var(s));
+    if (seq)
+	return seq;
+    else
+	return parent_is_sequence(table, s);
+}
+
+
+bool
+bracket_projection(DDS &table, const char *name, int_list_list *indices)
+{
+    BaseType *var = table.var(name);
+    Sequence *seq;		// used in last else-if clause
+#if 0
+    Array *array;
+#endif    
+    if (!var)
+	return false;
+	
+    if (is_array_t(var)) {
+	/* calls to set_send_p should be replaced with
+	   calls to DDS::mark so that arrays of Structures,
+	   etc. will be processed correctly when individual
+	   elements are projected using short names.
+	   9/1/98 jhrg */
+	/* var->set_send_p(true); */
+	//table.mark(name, true);
+	// We don't call mark() here for an array. Instead it is called from
+	// within the parser. jhrg 10/10/08
+	process_array_indices(var, indices);    // throws on error
+	delete_array_indices(indices);
+    }
+    else if (is_grid_t(var)) {
+	process_grid_indices(var, indices);
+        table.mark(name, true);
+	delete_array_indices(indices);
+    }
+    else if (is_sequence_t(var)) {
+	table.mark(name, true);
+	process_sequence_indices(var, indices);
+	delete_array_indices(indices);
+    }
+    else if ((seq = parent_is_sequence(table, name))) {
+	process_sequence_indices(seq, indices);
+        table.mark(name, true);
+	delete_array_indices(indices);
+    }
+    else {
+	return false;
+    }
+  
+    return true;
+}
+
+// Given three values (I1, I2, I3), all of which must be integers, build an
+// int_list which contains those values.
+//
+// Returns: A pointer to an int_list of three integers or NULL if any of the
+// values are not integers.
+
+int_list *
+make_array_index(value &i1, value &i2, value &i3)
+{
+    if (i1.type != dods_uint32_c
+	|| i2.type != dods_uint32_c
+	|| i3.type != dods_uint32_c)
+	return (int_list *)0;
+
+    int_list *index = new int_list;
+
+    index->push_back((int)i1.v.i);
+    index->push_back((int)i2.v.i);
+    index->push_back((int)i3.v.i);
+
+    DBG(cout << "index: ";\
+	for (int_iter dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    return index;
+}
+
+int_list *
+make_array_index(value &i1, value &i2)
+{
+    if (i1.type != dods_uint32_c || i2.type != dods_uint32_c)
+	return (int_list *)0;
+
+    int_list *index = new int_list;
+ 
+    index->push_back((int)i1.v.i);
+    index->push_back(1);
+    index->push_back((int)i2.v.i);
+
+    DBG(cout << "index: ";\
+	for (int_citer dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    return index;
+}
+
+int_list *
+make_array_index(value &i1)
+{
+    if (i1.type != dods_uint32_c)
+	return (int_list *)0;
+
+    int_list *index = new int_list;
+
+    index->push_back((int)i1.v.i);
+    index->push_back(1);
+    index->push_back((int)i1.v.i);
+
+    DBG(cout << "index: ";\
+	for (int_citer dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    return index;
+}
+
+int_list_list *
+make_array_indices(int_list *index)
+{
+    int_list_list *indices = new int_list_list;
+
+    DBG(cout << "index: ";\
+	for (int_citer dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    assert(index);
+    indices->push_back(index);
+
+    return indices;
+}
+
+int_list_list *
+append_array_index(int_list_list *indices, int_list *index)
+{
+    assert(indices);
+    assert(index);
+
+    indices->push_back(index);
+
+    return indices;
+}
+
+// Delete an array indices list. 
+
+void
+delete_array_indices(int_list_list *indices)
+{
+    assert(indices);
+
+    for (int_list_citer i = indices->begin(); i != indices->end(); i++) {
+	int_list *il = *i ;
+	assert(il);
+	delete il;
+    }
+
+    delete indices;
+}
+
+bool
+is_array_t(BaseType *variable)
+{
+    assert(variable);
+
+    if (variable->type() != dods_array_c)
+	return false;
+    else
+	return true;
+}
+
+bool
+is_grid_t(BaseType *variable)
+{
+    assert(variable);
+
+    if (variable->type() != dods_grid_c)
+	return false;
+    else
+	return true;
+}
+
+bool
+is_sequence_t(BaseType *variable)
+{
+    assert(variable);
+
+    if (variable->type() != dods_sequence_c)
+	return false;
+    else
+	return true;
+}
+
+void
+process_array_indices(BaseType *variable, int_list_list *indices)
+{
+    assert(variable);
+
+    Array *a = dynamic_cast<Array *>(variable); // replace with dynamic cast
+    if (!a)
+	throw Error(malformed_expr, 
+	   string("The constraint expression evaluator expected an array; ")
+		    + variable->name() + " is not an array.");
+		   
+    if (a->dimensions(true) != (unsigned)indices->size())
+	throw Error(malformed_expr, 
+	   string("Error: The number of dimensions in the constraint for ")
+		    + variable->name() 
+		    + " must match the number in the array.");
+		   
+    DBG(cerr << "Before clear_constraint:" << endl);
+    DBG(a->print_decl(cerr, "", true, false, true));
+
+    // a->reset_constraint();	// each projection erases the previous one
+
+    DBG(cerr << "After reset_constraint:" << endl);
+    DBG(a->print_decl(cerr, "", true, false, true));
+
+    assert(indices);
+    int_list_citer p = indices->begin() ;
+    Array::Dim_iter r = a->dim_begin() ;
+    for (; p != indices->end() && r != a->dim_end(); p++, r++) {
+	int_list *index = *p;
+	assert(index);
+
+	int_citer q = index->begin(); 
+	assert(q!=index->end());
+	int start = *q;
+
+	q++;
+	int stride = *q;
+	
+	q++;
+	int stop = *q;
+
+	q++;
+	if (q != index->end()) {
+	    throw Error(malformed_expr,
+			string("Too many values in index list for ")
+			+ a->name() + ".");
+	}
+
+	DBG(cerr << "process_array_indices: Setting constraint on "\
+	    << a->name() << "[" << start << ":" << stop << "]" << endl);
+
+        // It's possible that an array will appear more than once in a CE
+        // (for example, if an array of structures is constrained so that
+        // only two fields are projected and there's an associated hyperslab).
+        // However, in this case the two hyperslabs must be equal; test for
+        // that here. But see clear_constraint above... 10/28/08 jhrg
+
+        if (a->send_p()
+            && (a->dimension_start(r, true) != start
+                || a->dimension_stop(r, true) != stop
+                || a->dimension_stride(r, true) != stride))
+            throw Error(malformed_expr,
+                        string("The Array was already projected differently in the constraint expression: ")
+                    + a->name() + ".");
+                 
+	a->add_constraint(r, start, stride, stop);
+
+	DBG(cerr << "Set Constraint: " << a->dimension_size(r, true) << endl);
+    }
+
+    DBG(cerr << "After processing loop:" << endl);
+    DBG(a->print_decl(cerr, "", true, false, true));
+
+    DBG(cout << "Array Constraint: ";\
+	for (Array::Dim_iter dp = a->dim_begin(); dp != a->dim_end(); dp++)\
+	    cout << a->dimension_size(dp, true) << " ";\
+	cout << endl);
+    
+    if (p != indices->end() && r == a->dim_end()) {
+	throw Error(malformed_expr,
+		    string("Too many indices in constraint for ")
+		    + a->name() + ".");
+    }
+}
+
+void
+process_grid_indices(BaseType *variable, int_list_list *indices)
+{
+    assert(variable);
+    assert(variable->type() == dods_grid_c);
+    Grid *g = dynamic_cast<Grid *>(variable);
+    if (!g)
+	throw Error(unknown_error, "Expected a Grid variable");
+
+    Array *a = g->get_array();
+#if 0
+    // This test s now part of Grid::get_array(). jhrg 3/5/09
+    if (!a)
+	throw InternalErr(__FILE__, __LINE__, "Malformed Grid variable");
+#endif
+    if (a->dimensions(true) != (unsigned)indices->size())
+	throw Error(malformed_expr, 
+	   string("Error: The number of dimensions in the constraint for ")
+		    + variable->name() 
+		    + " must match the number in the grid.");
+		   
+    // First do the constraints on the ARRAY in the grid.
+    process_array_indices(g->array_var(), indices);
+
+    // Now process the maps.
+    Grid::Map_iter r = g->map_begin() ;
+
+    // Suppress all maps by default.
+    for (; r != g->map_end(); r++)
+    {
+	(*r)->set_send_p(false);
+    }
+
+    // Add specified maps to the current projection.
+    assert(indices);
+    int_list_citer p = indices->begin();
+    r = g->map_begin(); 
+    for (; p != indices->end() && r != g->map_end(); p++, r++)
+    {
+	int_list *index = *p;
+	assert(index);
+
+	int_citer q = index->begin(); 
+	assert(q != index->end());
+	int start = *q;
+
+	q++;
+	int stride = *q;
+	
+	q++;
+	int stop = *q;
+
+	BaseType *btp = *r;
+	assert(btp);
+	assert(btp->type() == dods_array_c);
+	Array *a = (Array *)btp;
+	a->set_send_p(true);
+	a->reset_constraint();
+
+	q++;
+	if (q!=index->end()) {
+	    throw Error(malformed_expr,
+			string("Too many values in index list for ")
+			+ a->name() + ".");
+	}
+
+	DBG(cerr << "process_grid_indices: Setting constraint on "\
+	    << a->name() << "[" << start << ":" << stop << "]" << endl);
+
+	Array::Dim_iter si = a->dim_begin() ;
+	a->add_constraint(si, start, stride, stop);
+
+	DBG(Array::Dim_iter aiter = a->dim_begin() ; \
+	    cerr << "Set Constraint: " \
+	    << a->dimension_size(aiter, true) << endl);
+    }
+
+    DBG(cout << "Grid Constraint: ";\
+	for (Array::Dim_iter dp = ((Array *)g->array_var())->dim_begin();
+	     dp != ((Array *)g->array_var())->dim_end(); \
+	     dp++)\
+	   cout << ((Array *)g->array_var())->dimension_size(dp, true) << " ";\
+	cout << endl);
+    
+    if (p!=indices->end() && r==g->map_end()) {
+	throw Error(malformed_expr,
+		    string("Too many indices in constraint for ")
+		    + (*r)->name() + ".");
+    }
+}
+
+void
+process_sequence_indices(BaseType *variable, int_list_list *indices)
+{
+    assert(variable);
+    assert(variable->type() == dods_sequence_c);
+    Sequence *s = dynamic_cast<Sequence *>(variable);
+    if (!s)
+	throw Error(malformed_expr, "Expected a Sequence variable");
+
+    // Add specified maps to the current projection.
+    assert(indices);
+    for (int_list_citer p = indices->begin(); p != indices->end(); p++)
+    {
+	int_list *index = *p;
+	assert(index);
+
+	int_citer q = index->begin(); 
+	assert(q!=index->end());
+	int start = *q;
+
+	q++;
+	int stride = *q;
+	
+	q++;
+	int stop = *q;
+
+	q++;
+	if (q!=index->end()) {
+	  throw Error(malformed_expr, 
+		      string("Too many values in index list for ")
+		      + s->name() + ".");
+	}
+
+	s->set_row_number_constraint(start, stop, stride);
+    }
+}
+
+
+// Given a value, wrap it up in a BaseType and return a pointer to the same.
+
+BaseType *
+make_variable(ConstraintEvaluator &eval, const value &val)
+{
+    BaseType *var;
+    switch (val.type) {
+      case dods_int32_c: {
+	var = new Int32("dummy");
+	var->val2buf((void *)&val.v.i);
+	break;
+      }
+
+      case dods_float64_c: {
+	var = new Float64("dummy");
+	var->val2buf((void *)&val.v.f);
+	break;
+      }
+
+      case dods_str_c: {
+	var = new Str("dummy");
+	var->val2buf((void *)val.v.s);
+	break;
+      }
+
+      default:
+	var = (BaseType *)0;
+	return var;
+    }
+
+    var->set_read_p(true);	// ...so the evaluator will know it has data
+    eval.append_constant(var);
+
+    return var;
+}
+
+// Given a string (passed in VAL), consult the DDS CE function lookup table
+// to see if a function by that name exists. 
+// NB: function arguments are type-checked at run-time.
+//
+// Returns: A pointer to the function or NULL if not such function exists.
+
+bool_func
+get_function(const ConstraintEvaluator &eval, const char *name)
+{
+    bool_func f;
+
+    if (eval.find_function(name, &f))
+	return f;
+    else
+	return 0;
+}
+
+btp_func
+get_btp_function(const ConstraintEvaluator &eval, const char *name)
+{
+    btp_func f;
+
+    if (eval.find_function(name, &f))
+	return f;
+    else
+	return 0;
+}
+
+proj_func
+get_proj_function(const ConstraintEvaluator &eval, const char *name)
+{
+    proj_func f;
+
+    if (eval.find_function(name, &f))
+	return f;
+    else
+	return 0;
+}
+
+
diff --git a/ce_expr.tab.hh b/ce_expr.tab.hh
new file mode 100644
index 0000000..8b3cb6e
--- /dev/null
+++ b/ce_expr.tab.hh
@@ -0,0 +1,95 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface 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.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_STR = 258,
+     SCAN_WORD = 259,
+     SCAN_EQUAL = 260,
+     SCAN_NOT_EQUAL = 261,
+     SCAN_GREATER = 262,
+     SCAN_GREATER_EQL = 263,
+     SCAN_LESS = 264,
+     SCAN_LESS_EQL = 265,
+     SCAN_REGEXP = 266
+   };
+#endif
+/* Tokens.  */
+#define SCAN_STR 258
+#define SCAN_WORD 259
+#define SCAN_EQUAL 260
+#define SCAN_NOT_EQUAL 261
+#define SCAN_GREATER 262
+#define SCAN_GREATER_EQL 263
+#define SCAN_LESS 264
+#define SCAN_LESS_EQL 265
+#define SCAN_REGEXP 266
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 130 "ce_expr.y"
+{
+    bool boolean;
+    int op;
+    char id[ID_MAX];
+
+    libdap::value val;               // value is defined in expr.h
+
+    libdap::bool_func b_func;
+    libdap::btp_func bt_func;
+
+    libdap::int_list *int_l_ptr;
+    libdap::int_list_list *int_ll_ptr;
+    
+    libdap::rvalue *rval_ptr;
+    libdap::rvalue_list *r_val_l_ptr;
+}
+/* Line 1489 of yacc.c.  */
+#line 88 "ce_expr.tab.hh"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE ce_exprlval;
+
diff --git a/ce_expr.y b/ce_expr.y
new file mode 100644
index 0000000..2685c46
--- /dev/null
+++ b/ce_expr.y
@@ -0,0 +1,1080 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+/*
+  This is the parser for the DODS constraint expression grammar. The parser
+  calls various `helper' functions defined by the DAP classes which either
+  implement the operations (in the case of relational ops) or store
+  information (in the case of selection operations). 
+
+  jhrg 9/5/95
+*/
+
+%{
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: ce_expr.y 21578 2009-10-02 16:26:26Z jimg $"};
+
+#include <cassert>
+#include <cstdlib>
+#include <string>
+#include <cstring>
+#include <stack>
+
+#include "debug.h"
+#include "escaping.h"
+
+#include "DDS.h"
+#include "ConstraintEvaluator.h"
+
+#include "BaseType.h"
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "Error.h"
+
+#include "util.h"
+#include "parser.h"
+#include "ce_parser.h"
+#include "expr.h"
+#include "RValue.h"
+
+using std::cerr;
+using std::endl;
+using namespace libdap ;
+
+#define EVALUATOR(arg) (static_cast<ce_parser_arg*>(arg)->get_eval())
+#define DDS(arg) (static_cast<ce_parser_arg*>(arg)->get_dds())
+
+#define YYPARSE_PARAM arg
+
+int ce_exprlex(void);		/* the scanner; see expr.lex */
+
+void ce_exprerror(const char *s);	/* easier to overload than to use stdarg... */
+void ce_exprerror(const char *s, const char *s2);
+void no_such_func(char *name);
+void no_such_ident(char *name, char *word);
+
+void ce_exprerror(const string &s); 
+void ce_exprerror(const string &s, const string &s2);
+void no_such_func(const string &name);
+void no_such_ident(const string &name, const string &word);
+
+int_list *make_array_index(value &i1, value &i2, value &i3);
+int_list *make_array_index(value &i1, value &i2);
+int_list *make_array_index(value &i1);
+int_list_list *make_array_indices(int_list *index);
+int_list_list *append_array_index(int_list_list *indices, int_list *index);
+
+void delete_array_indices(int_list_list *indices);
+bool bracket_projection(DDS &table, const char *name, 
+			int_list_list *indices);
+
+void process_array_indices(BaseType *variable, int_list_list *indices); 
+void process_grid_indices(BaseType *variable, int_list_list *indices); 
+void process_sequence_indices(BaseType *variable, int_list_list *indices);
+
+/* Replace these with method calls. jhrg 8/31/06 */
+bool is_array_t(BaseType *variable);
+bool is_grid_t(BaseType *variable);
+bool is_sequence_t(BaseType *variable);
+
+BaseType *make_variable(ConstraintEvaluator &eval, const value &val);
+bool_func get_function(const ConstraintEvaluator &eval, const char *name);
+btp_func get_btp_function(const ConstraintEvaluator &eval, const char *name);
+proj_func get_proj_function(const ConstraintEvaluator &eval, const char *name);
+
+%}
+
+%union {
+    bool boolean;
+    int op;
+    char id[ID_MAX];
+
+    libdap::value val;               // value is defined in expr.h
+
+    libdap::bool_func b_func;
+    libdap::btp_func bt_func;
+
+    libdap::int_list *int_l_ptr;
+    libdap::int_list_list *int_ll_ptr;
+    
+    libdap::rvalue *rval_ptr;
+    libdap::rvalue_list *r_val_l_ptr;
+}
+
+%token <val> SCAN_STR
+
+%token <id> SCAN_WORD
+
+%token <op> SCAN_EQUAL
+%token <op> SCAN_NOT_EQUAL
+%token <op> SCAN_GREATER
+%token <op> SCAN_GREATER_EQL
+%token <op> SCAN_LESS
+%token <op> SCAN_LESS_EQL
+%token <op> SCAN_REGEXP
+
+%type <boolean> constraint_expr projection proj_clause proj_function
+%type <boolean> array_projection selection clause bool_function
+%type <id> array_proj_clause name
+%type <op> rel_op
+%type <int_l_ptr> array_index
+%type <int_ll_ptr> array_indices
+%type <rval_ptr> r_value id_or_const
+%type <r_val_l_ptr> r_value_list arg_list
+
+%%
+
+constraint_expr: /* empty constraint --> send all */
+                 {
+		     DDS(arg)->mark_all(true);
+		     $$ = true;
+		 }
+                 /* projection only */
+                 | projection
+		 /* selection only --> project everything */
+                 | '&' { DDS(arg)->mark_all(true); } selection
+                 { 
+		     $$ = $3;
+		 }
+                 | projection '&' selection
+                 {
+		     $$ = $1 && $3;
+		 }
+;
+
+projection:     proj_clause
+                | proj_clause ',' projection
+                {
+		    $$ = $1 && $3;
+		}
+;
+
+proj_clause:	name 
+                { 
+		    BaseType *var = DDS(arg)->var($1);
+		    if (var) {
+			DBG(cerr << "Marking " << $1 << endl);
+			$$ = DDS(arg)->mark($1, true);
+			DBG(cerr << "result: " << $$ << endl);
+		    }
+		    else {
+			no_such_ident($1, "identifier");
+		    }
+		}
+/*		| SCAN_STR
+                {
+                    if ($1.type != dods_str_c || $1.v.s == 0 || $1.v.s->empty())
+                        ce_exprerror("Malformed string", "");
+                        
+                    BaseType *var = DDS(arg)->var(*($1.v.s));
+                    if (var) {
+                        DBG(cerr << "Marking " << $1 << endl);
+                        $$ = DDS(arg)->mark(*($1.v.s), true);
+                        DBG(cerr << "result: " << $$ << endl);
+                    }
+                    else {
+                        no_such_ident(*($1.v.s), "identifier");
+                    }
+                }
+*/
+                | proj_function
+                {
+		    $$ = $1;
+		}
+		| array_projection
+                {
+		    $$ = $1;
+		}
+;
+
+proj_function:  SCAN_WORD '(' arg_list ')'
+	        {
+		    proj_func p_f = 0;
+		    btp_func f = 0;
+
+		    if ((f = get_btp_function(*(EVALUATOR(arg)), $1))) {
+			EVALUATOR(arg)->append_clause(f, $3);
+			$$ = true;
+		    }
+		    else if ((p_f = get_proj_function(*(EVALUATOR(arg)), $1))) {
+		        DDS &dds = dynamic_cast<DDS&>(*(DDS(arg)));
+			BaseType **args = build_btp_args( $3, dds );
+			(*p_f)(($3) ? $3->size():0, args, dds, *(EVALUATOR(arg)));
+			delete[] args;
+			$$ = true;
+		    }
+		    else {
+			no_such_func($1);
+		    }
+		}
+;
+
+selection:	clause
+		| selection '&' clause
+                {
+		    $$ = $1 && $3;
+		}
+;
+
+clause:		r_value rel_op '{' r_value_list '}'
+                {
+		    if ($1) {
+			EVALUATOR(arg)->append_clause($2, $1, $4);
+			$$ = true;
+		    }
+		    else
+			$$ = false;
+		}
+		| r_value rel_op r_value
+                {
+		    if ($1) {
+			rvalue_list *rv = new rvalue_list;
+			rv->push_back($3);
+			EVALUATOR(arg)->append_clause($2, $1, rv);
+			$$ = true;
+		    }
+		    else
+			$$ = false;
+		}
+		| bool_function
+                {
+		    $$ = $1;
+		}
+;
+
+bool_function: SCAN_WORD '(' arg_list ')'
+	       {
+		   bool_func b_func = get_function((*EVALUATOR(arg)), $1);
+		   if (!b_func) {
+		       no_such_func($1);
+		   }
+		   else {
+		       EVALUATOR(arg)->append_clause(b_func, $3);
+		       $$ = true;
+		   }
+	       }
+;
+
+r_value:        id_or_const
+		| SCAN_WORD '(' arg_list ')'
+		{
+		    btp_func func = get_btp_function((*EVALUATOR(arg)), $1);
+		    if (func) {
+			$$ = new rvalue(func, $3);
+		    } 
+		    else {  		
+			no_such_func($1);
+		    }
+		}
+;
+
+r_value_list:	r_value
+		{
+		    if ($1)
+			$$ = make_rvalue_list($1);
+		    else
+			$$ = 0;
+		}
+		| r_value_list ',' r_value
+                {
+		    if ($1 && $3)
+			$$ = append_rvalue_list($1, $3);
+		    else
+			$$ = 0;
+		}
+;
+
+arg_list:     r_value_list
+              {  
+		  $$ = $1;
+	      }
+              | /* Null, argument lists may be empty */
+              { 
+		  $$ = 0; 
+	      }
+;
+
+id_or_const:    SCAN_WORD
+		{ 
+		    BaseType *btp = DDS(arg)->var(www2id(string($1)));
+		    if (btp) {
+                        btp->set_in_selection(true);
+                        $$ = new rvalue(btp);
+		    }
+		    else {
+			value new_val;
+			if (check_int32($1)) {
+			    new_val.type = dods_int32_c;
+			    new_val.v.i = atoi($1);
+			}
+			else if (check_uint32($1)) {
+			    new_val.type = dods_uint32_c;
+			    new_val.v.ui = atoi($1);
+			}
+			else if (check_float64($1)) {
+			    new_val.type = dods_float64_c;
+			    new_val.v.f = atof($1);
+			}
+			else {
+			    new_val.type = dods_str_c;
+			    new_val.v.s = new string($1);
+			}
+			BaseType *btp = make_variable((*EVALUATOR(arg)), new_val); 
+			// *** test for btp == null
+			// delete new_val.v.s; // Str::val2buf copies the value.
+			$$ = new rvalue(btp);
+		    }
+		}
+                | SCAN_STR
+                {
+                    if ($1.type != dods_str_c || $1.v.s == 0 || $1.v.s->empty())
+                        ce_exprerror("Malformed string", "");
+                        
+                    BaseType *var = DDS(arg)->var(*($1.v.s));
+                    if (var) {
+                        $$ = new rvalue(var);
+                    }
+                    else {
+                        var = make_variable((*EVALUATOR(arg)), $1); 
+                        $$ = new rvalue(var);
+                    }
+                }
+;
+
+array_projection : array_proj_clause
+                {
+                    $$ = (*DDS(arg)).mark($1, true);
+                }
+                
+array_proj_clause: name array_indices
+                {
+                    if (!bracket_projection((*DDS(arg)), $1, $2))
+                      no_such_ident($1, "array, grid or sequence");
+
+                    strncpy($$, $1, ID_MAX-1);
+                    $$[ID_MAX-1] = '\0';
+                }
+                | array_proj_clause name
+                {
+                    string name = string($1) + string ($2);
+                    strncpy($$, name.c_str(), ID_MAX-1);
+                    $$[ID_MAX-1] = '\0';
+                }
+                | array_proj_clause name array_indices
+                {
+                    string name = string($1) + string ($2);
+                    if (!bracket_projection((*DDS(arg)), name.c_str(), $3))
+                      no_such_ident(name.c_str(), "array, grid or sequence");
+
+                    strncpy($$, name.c_str(), ID_MAX-1);
+                    $$[ID_MAX-1] = '\0';
+                }
+;
+
+name:           SCAN_WORD
+                | SCAN_STR
+                {
+                    if ($1.type != dods_str_c || $1.v.s == 0 || $1.v.s->empty())
+                        ce_exprerror("Malformed string", "");
+                        
+                    strncpy($$, www2id(*($1.v.s)).c_str(), ID_MAX-1);
+                    // delete the string? ***
+                    $$[ID_MAX-1] = '\0';
+/*
+                    BaseType *var = DDS(arg)->var(*($1.v.s));
+                    if (var) {
+                        DBG(cerr << "Marking " << $1 << endl);
+                        $$ = DDS(arg)->mark(*($1.v.s), true);
+                        DBG(cerr << "result: " << $$ << endl);
+                    }
+                    else {
+                        no_such_ident(*($1.v.s), "identifier");
+                    }
+*/
+                }
+;
+
+array_indices:  array_index
+                {
+		    $$ = make_array_indices($1);
+		}
+                | array_indices array_index
+                {
+		    $$ = append_array_index($1, $2);
+		}
+;
+
+array_index: 	'[' SCAN_WORD ']'
+                {
+		    if (!check_uint32($2)) {
+			string msg = "The word `";
+			msg += string($2) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    value i;
+		    i.type = dods_uint32_c;
+		    i.v.i = atoi($2);
+		    $$ = make_array_index(i);
+		}
+		|'[' SCAN_WORD ':' SCAN_WORD ']'
+                {
+		    if (!check_uint32($2)) {
+			string msg = "The word `";
+			msg += string($2) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    if (!check_uint32($4)) {
+			string msg = "The word `";
+			msg += string($4) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    value i,j;
+		    i.type = j.type = dods_uint32_c;
+		    i.v.i = atoi($2);
+		    j.v.i = atoi($4);
+		    $$ = make_array_index(i, j);
+		}
+		| '[' SCAN_WORD ':' SCAN_WORD ':' SCAN_WORD ']'
+                {
+		    if (!check_uint32($2)) {
+			string msg = "The word `";
+			msg += string($2) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    if (!check_uint32($4)) {
+			string msg = "The word `";
+			msg += string($4) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    if (!check_uint32($6)) {
+			string msg = "The word `";
+			msg += string($6) + "' is not a valid array index.";
+			throw Error(malformed_expr, msg);
+		    }
+		    value i, j, k;
+		    i.type = j.type = k.type = dods_uint32_c;
+		    i.v.i = atoi($2);
+		    j.v.i = atoi($4);
+		    k.v.i = atoi($6);
+		    $$ = make_array_index(i, j, k);
+		}
+;
+
+rel_op:		SCAN_EQUAL
+		| SCAN_NOT_EQUAL
+		| SCAN_GREATER
+		| SCAN_GREATER_EQL
+		| SCAN_LESS
+		| SCAN_LESS_EQL
+		| SCAN_REGEXP
+;
+
+%%
+
+// All these error reporting function now throw instances of Error. The expr
+// parser no longer returns an error code to indicate and error. 2/16/2000
+// jhrg.
+
+void
+ce_exprerror(const string &s)
+{ 
+    ce_exprerror(s.c_str());
+}
+
+void
+ce_exprerror(const char *s)
+{
+    // cerr << "Expression parse error: " << s << endl;
+    string msg = "Constraint expression parse error: " + (string)s;
+    throw Error(malformed_expr, msg);
+}
+
+void
+ce_exprerror(const string &s, const string &s2)
+{
+    ce_exprerror(s.c_str(), s2.c_str());
+}
+
+void
+ce_exprerror(const char *s, const char *s2)
+{
+    string msg = "Constraint expression parse error: " + (string)s + ": " 
+	+ (string)s2;
+    throw Error(malformed_expr, msg);
+}
+
+void
+no_such_ident(const string &name, const string &word)
+{
+    string msg = "No such " + word + " in dataset";
+    ce_exprerror(msg.c_str(), name);
+}
+
+void
+no_such_ident(char *name, char *word)
+{
+    string msg = "No such " + (string)word + " in dataset";
+    ce_exprerror(msg.c_str(), name);
+}
+
+void
+no_such_func(const string &name)
+{
+    no_such_func(name.c_str());
+}
+
+void
+no_such_func(char *name)
+{
+    ce_exprerror("Not a registered function", name);
+}
+
+/* If we're calling this, assume var is not a Sequence. But assume that the
+   name contains a dot and it's a separator. Look for the rightmost dot and
+   then look to see if the name to the left is a sequence. Return a pointer
+   to the sequence if it is otherwise return null. Uses tail-recursion to
+   'walk' back from right to left looking at each dot. This way the sequence
+   will be found even if there are structures between the field and the
+   Sequence. */
+static Sequence *
+parent_is_sequence(DDS &table, const string &n)
+{
+    string::size_type dotpos = n.find_last_of('.');
+    if (dotpos == string::npos)
+	return 0;
+
+    string s = n.substr(0, dotpos);
+    
+    // If the thing returned by table.var is not a Sequence, this cast
+    // will yield null.
+    Sequence *seq = dynamic_cast<Sequence*>(table.var(s));
+    if (seq)
+	return seq;
+    else
+	return parent_is_sequence(table, s);
+}
+
+
+bool
+bracket_projection(DDS &table, const char *name, int_list_list *indices)
+{
+    BaseType *var = table.var(name);
+    Sequence *seq;		// used in last else-if clause
+#if 0
+    Array *array;
+#endif    
+    if (!var)
+	return false;
+	
+    if (is_array_t(var)) {
+	/* calls to set_send_p should be replaced with
+	   calls to DDS::mark so that arrays of Structures,
+	   etc. will be processed correctly when individual
+	   elements are projected using short names.
+	   9/1/98 jhrg */
+	/* var->set_send_p(true); */
+	//table.mark(name, true);
+	// We don't call mark() here for an array. Instead it is called from
+	// within the parser. jhrg 10/10/08
+	process_array_indices(var, indices);    // throws on error
+	delete_array_indices(indices);
+    }
+    else if (is_grid_t(var)) {
+	process_grid_indices(var, indices);
+        table.mark(name, true);
+	delete_array_indices(indices);
+    }
+    else if (is_sequence_t(var)) {
+	table.mark(name, true);
+	process_sequence_indices(var, indices);
+	delete_array_indices(indices);
+    }
+    else if ((seq = parent_is_sequence(table, name))) {
+	process_sequence_indices(seq, indices);
+        table.mark(name, true);
+	delete_array_indices(indices);
+    }
+    else {
+	return false;
+    }
+  
+    return true;
+}
+
+// Given three values (I1, I2, I3), all of which must be integers, build an
+// int_list which contains those values.
+//
+// Returns: A pointer to an int_list of three integers or NULL if any of the
+// values are not integers.
+
+int_list *
+make_array_index(value &i1, value &i2, value &i3)
+{
+    if (i1.type != dods_uint32_c
+	|| i2.type != dods_uint32_c
+	|| i3.type != dods_uint32_c)
+	return (int_list *)0;
+
+    int_list *index = new int_list;
+
+    index->push_back((int)i1.v.i);
+    index->push_back((int)i2.v.i);
+    index->push_back((int)i3.v.i);
+
+    DBG(cout << "index: ";\
+	for (int_iter dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    return index;
+}
+
+int_list *
+make_array_index(value &i1, value &i2)
+{
+    if (i1.type != dods_uint32_c || i2.type != dods_uint32_c)
+	return (int_list *)0;
+
+    int_list *index = new int_list;
+ 
+    index->push_back((int)i1.v.i);
+    index->push_back(1);
+    index->push_back((int)i2.v.i);
+
+    DBG(cout << "index: ";\
+	for (int_citer dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    return index;
+}
+
+int_list *
+make_array_index(value &i1)
+{
+    if (i1.type != dods_uint32_c)
+	return (int_list *)0;
+
+    int_list *index = new int_list;
+
+    index->push_back((int)i1.v.i);
+    index->push_back(1);
+    index->push_back((int)i1.v.i);
+
+    DBG(cout << "index: ";\
+	for (int_citer dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    return index;
+}
+
+int_list_list *
+make_array_indices(int_list *index)
+{
+    int_list_list *indices = new int_list_list;
+
+    DBG(cout << "index: ";\
+	for (int_citer dp = index->begin(); dp != index->end(); dp++)\
+	cout << (*dp) << " ";\
+	cout << endl);
+
+    assert(index);
+    indices->push_back(index);
+
+    return indices;
+}
+
+int_list_list *
+append_array_index(int_list_list *indices, int_list *index)
+{
+    assert(indices);
+    assert(index);
+
+    indices->push_back(index);
+
+    return indices;
+}
+
+// Delete an array indices list. 
+
+void
+delete_array_indices(int_list_list *indices)
+{
+    assert(indices);
+
+    for (int_list_citer i = indices->begin(); i != indices->end(); i++) {
+	int_list *il = *i ;
+	assert(il);
+	delete il;
+    }
+
+    delete indices;
+}
+
+bool
+is_array_t(BaseType *variable)
+{
+    assert(variable);
+
+    if (variable->type() != dods_array_c)
+	return false;
+    else
+	return true;
+}
+
+bool
+is_grid_t(BaseType *variable)
+{
+    assert(variable);
+
+    if (variable->type() != dods_grid_c)
+	return false;
+    else
+	return true;
+}
+
+bool
+is_sequence_t(BaseType *variable)
+{
+    assert(variable);
+
+    if (variable->type() != dods_sequence_c)
+	return false;
+    else
+	return true;
+}
+
+void
+process_array_indices(BaseType *variable, int_list_list *indices)
+{
+    assert(variable);
+
+    Array *a = dynamic_cast<Array *>(variable); // replace with dynamic cast
+    if (!a)
+	throw Error(malformed_expr, 
+	   string("The constraint expression evaluator expected an array; ")
+		    + variable->name() + " is not an array.");
+		   
+    if (a->dimensions(true) != (unsigned)indices->size())
+	throw Error(malformed_expr, 
+	   string("Error: The number of dimensions in the constraint for ")
+		    + variable->name() 
+		    + " must match the number in the array.");
+		   
+    DBG(cerr << "Before clear_constraint:" << endl);
+    DBG(a->print_decl(cerr, "", true, false, true));
+
+    // a->reset_constraint();	// each projection erases the previous one
+
+    DBG(cerr << "After reset_constraint:" << endl);
+    DBG(a->print_decl(cerr, "", true, false, true));
+
+    assert(indices);
+    int_list_citer p = indices->begin() ;
+    Array::Dim_iter r = a->dim_begin() ;
+    for (; p != indices->end() && r != a->dim_end(); p++, r++) {
+	int_list *index = *p;
+	assert(index);
+
+	int_citer q = index->begin(); 
+	assert(q!=index->end());
+	int start = *q;
+
+	q++;
+	int stride = *q;
+	
+	q++;
+	int stop = *q;
+
+	q++;
+	if (q != index->end()) {
+	    throw Error(malformed_expr,
+			string("Too many values in index list for ")
+			+ a->name() + ".");
+	}
+
+	DBG(cerr << "process_array_indices: Setting constraint on "\
+	    << a->name() << "[" << start << ":" << stop << "]" << endl);
+
+        // It's possible that an array will appear more than once in a CE
+        // (for example, if an array of structures is constrained so that
+        // only two fields are projected and there's an associated hyperslab).
+        // However, in this case the two hyperslabs must be equal; test for
+        // that here. But see clear_constraint above... 10/28/08 jhrg
+
+        if (a->send_p()
+            && (a->dimension_start(r, true) != start
+                || a->dimension_stop(r, true) != stop
+                || a->dimension_stride(r, true) != stride))
+            throw Error(malformed_expr,
+                        string("The Array was already projected differently in the constraint expression: ")
+                    + a->name() + ".");
+                 
+	a->add_constraint(r, start, stride, stop);
+
+	DBG(cerr << "Set Constraint: " << a->dimension_size(r, true) << endl);
+    }
+
+    DBG(cerr << "After processing loop:" << endl);
+    DBG(a->print_decl(cerr, "", true, false, true));
+
+    DBG(cout << "Array Constraint: ";\
+	for (Array::Dim_iter dp = a->dim_begin(); dp != a->dim_end(); dp++)\
+	    cout << a->dimension_size(dp, true) << " ";\
+	cout << endl);
+    
+    if (p != indices->end() && r == a->dim_end()) {
+	throw Error(malformed_expr,
+		    string("Too many indices in constraint for ")
+		    + a->name() + ".");
+    }
+}
+
+void
+process_grid_indices(BaseType *variable, int_list_list *indices)
+{
+    assert(variable);
+    assert(variable->type() == dods_grid_c);
+    Grid *g = dynamic_cast<Grid *>(variable);
+    if (!g)
+	throw Error(unknown_error, "Expected a Grid variable");
+
+    Array *a = g->get_array();
+#if 0
+    // This test s now part of Grid::get_array(). jhrg 3/5/09
+    if (!a)
+	throw InternalErr(__FILE__, __LINE__, "Malformed Grid variable");
+#endif
+    if (a->dimensions(true) != (unsigned)indices->size())
+	throw Error(malformed_expr, 
+	   string("Error: The number of dimensions in the constraint for ")
+		    + variable->name() 
+		    + " must match the number in the grid.");
+		   
+    // First do the constraints on the ARRAY in the grid.
+    process_array_indices(g->array_var(), indices);
+
+    // Now process the maps.
+    Grid::Map_iter r = g->map_begin() ;
+
+    // Suppress all maps by default.
+    for (; r != g->map_end(); r++)
+    {
+	(*r)->set_send_p(false);
+    }
+
+    // Add specified maps to the current projection.
+    assert(indices);
+    int_list_citer p = indices->begin();
+    r = g->map_begin(); 
+    for (; p != indices->end() && r != g->map_end(); p++, r++)
+    {
+	int_list *index = *p;
+	assert(index);
+
+	int_citer q = index->begin(); 
+	assert(q != index->end());
+	int start = *q;
+
+	q++;
+	int stride = *q;
+	
+	q++;
+	int stop = *q;
+
+	BaseType *btp = *r;
+	assert(btp);
+	assert(btp->type() == dods_array_c);
+	Array *a = (Array *)btp;
+	a->set_send_p(true);
+	a->reset_constraint();
+
+	q++;
+	if (q!=index->end()) {
+	    throw Error(malformed_expr,
+			string("Too many values in index list for ")
+			+ a->name() + ".");
+	}
+
+	DBG(cerr << "process_grid_indices: Setting constraint on "\
+	    << a->name() << "[" << start << ":" << stop << "]" << endl);
+
+	Array::Dim_iter si = a->dim_begin() ;
+	a->add_constraint(si, start, stride, stop);
+
+	DBG(Array::Dim_iter aiter = a->dim_begin() ; \
+	    cerr << "Set Constraint: " \
+	    << a->dimension_size(aiter, true) << endl);
+    }
+
+    DBG(cout << "Grid Constraint: ";\
+	for (Array::Dim_iter dp = ((Array *)g->array_var())->dim_begin();
+	     dp != ((Array *)g->array_var())->dim_end(); \
+	     dp++)\
+	   cout << ((Array *)g->array_var())->dimension_size(dp, true) << " ";\
+	cout << endl);
+    
+    if (p!=indices->end() && r==g->map_end()) {
+	throw Error(malformed_expr,
+		    string("Too many indices in constraint for ")
+		    + (*r)->name() + ".");
+    }
+}
+
+void
+process_sequence_indices(BaseType *variable, int_list_list *indices)
+{
+    assert(variable);
+    assert(variable->type() == dods_sequence_c);
+    Sequence *s = dynamic_cast<Sequence *>(variable);
+    if (!s)
+	throw Error(malformed_expr, "Expected a Sequence variable");
+
+    // Add specified maps to the current projection.
+    assert(indices);
+    for (int_list_citer p = indices->begin(); p != indices->end(); p++)
+    {
+	int_list *index = *p;
+	assert(index);
+
+	int_citer q = index->begin(); 
+	assert(q!=index->end());
+	int start = *q;
+
+	q++;
+	int stride = *q;
+	
+	q++;
+	int stop = *q;
+
+	q++;
+	if (q!=index->end()) {
+	  throw Error(malformed_expr, 
+		      string("Too many values in index list for ")
+		      + s->name() + ".");
+	}
+
+	s->set_row_number_constraint(start, stop, stride);
+    }
+}
+
+
+// Given a value, wrap it up in a BaseType and return a pointer to the same.
+
+BaseType *
+make_variable(ConstraintEvaluator &eval, const value &val)
+{
+    BaseType *var;
+    switch (val.type) {
+      case dods_int32_c: {
+	var = new Int32("dummy");
+	var->val2buf((void *)&val.v.i);
+	break;
+      }
+
+      case dods_float64_c: {
+	var = new Float64("dummy");
+	var->val2buf((void *)&val.v.f);
+	break;
+      }
+
+      case dods_str_c: {
+	var = new Str("dummy");
+	var->val2buf((void *)val.v.s);
+	break;
+      }
+
+      default:
+	var = (BaseType *)0;
+	return var;
+    }
+
+    var->set_read_p(true);	// ...so the evaluator will know it has data
+    eval.append_constant(var);
+
+    return var;
+}
+
+// Given a string (passed in VAL), consult the DDS CE function lookup table
+// to see if a function by that name exists. 
+// NB: function arguments are type-checked at run-time.
+//
+// Returns: A pointer to the function or NULL if not such function exists.
+
+bool_func
+get_function(const ConstraintEvaluator &eval, const char *name)
+{
+    bool_func f;
+
+    if (eval.find_function(name, &f))
+	return f;
+    else
+	return 0;
+}
+
+btp_func
+get_btp_function(const ConstraintEvaluator &eval, const char *name)
+{
+    btp_func f;
+
+    if (eval.find_function(name, &f))
+	return f;
+    else
+	return 0;
+}
+
+proj_func
+get_proj_function(const ConstraintEvaluator &eval, const char *name)
+{
+    proj_func f;
+
+    if (eval.find_function(name, &f))
+	return f;
+    else
+	return 0;
+}
+
diff --git a/ce_functions.cc b/ce_functions.cc
new file mode 100644
index 0000000..25e02f4
--- /dev/null
+++ b/ce_functions.cc
@@ -0,0 +1,1071 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+
+// These functions are used by the CE evaluator
+//
+// 1/15/99 jhrg
+
+#include "config.h"
+
+static char rcsid[]not_used =
+{   "$Id: ce_functions.cc 24370 2011-03-28 16:21:32Z jimg $"
+};
+
+#include <limits.h>
+
+#include <cstdlib>      // used by strtod()
+#include <cerrno>
+#include <cmath>
+#include <iostream>
+#include <vector>
+#include <algorithm>
+
+//#define DODS_DEBUG
+#undef FUNCTION_DAP	// undef so the dap() function always returns an error;
+			// use keywords instead.
+
+#include "BaseType.h"
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+#include "Error.h"
+#include "RValue.h"
+
+#include "GSEClause.h"
+#include "GridGeoConstraint.h"
+#include "ArrayGeoConstraint.h"
+
+#include "ce_functions.h"
+#include "gse_parser.h"
+#include "gse.tab.hh"
+#include "debug.h"
+#include "util.h"
+
+//  We wrapped VC++ 6.x strtod() to account for a short coming
+//  in that function in regards to "NaN".  I don't know if this
+//  still applies in more recent versions of that product.
+//  ROM - 12/2007
+#ifdef WIN32
+#include <limits>
+double w32strtod(const char *, char **);
+#endif
+
+using namespace std;
+
+int gse_parse(void *arg);
+void gse_restart(FILE * in);
+
+// Glue routines declared in gse.lex
+void gse_switch_to_buffer(void *new_buffer);
+void gse_delete_buffer(void *buffer);
+void *gse_string(const char *yy_str);
+
+namespace libdap {
+
+/** Is \e lhs equal to \e rhs? Use epsilon to determine equality. */
+inline bool double_eq(double lhs, double rhs, double epsilon = 1.0e-5)
+{
+    if (lhs > rhs)
+        return (lhs - rhs) < ((lhs + rhs) / epsilon);
+    else
+        return (rhs - lhs) < ((lhs + rhs) / epsilon);
+}
+
+/** Given a BaseType pointer, extract the string value it contains and return
+ it.
+
+ @param arg The BaseType pointer
+ @return A C++ string
+ @exception Error thrown if the referenced BaseType object does not contain
+ a DAP String. */
+string extract_string_argument(BaseType * arg)
+{
+    if (arg->type() != dods_str_c)
+        throw Error(malformed_expr,
+                "The function requires a DAP string argument.");
+
+    if (!arg->read_p())
+        throw InternalErr(__FILE__, __LINE__,
+                "The CE Evaluator built an argument list where some constants held no values.");
+
+    string s = dynamic_cast<Str&>(*arg).value();
+
+    DBG(cerr << "s: " << s << endl);
+
+    return s;
+}
+
+template<class T> static void set_array_using_double_helper(Array * a,
+        double *src, int src_len)
+{
+    T *values = new T[src_len];
+    for (int i = 0; i < src_len; ++i)
+        values[i] = (T) src[i];
+
+#ifdef VAL2BUF
+    a->val2buf(values, true);
+#else
+    a->set_value(values, src_len);
+#endif
+
+    delete[]values;
+}
+
+/** Given an array that holds some sort of numeric data, load it with values
+ using an array of doubles. This function makes several assumptions. First,
+ it assumes the caller really wants to put the doubles into whatever types
+ the array holds! Caveat emptor. Second, it assumes that if the size of
+ source (\e src) array is different than the destination (\e dest) the
+ caller has made a mistake. In that case it will throw an Error object.
+
+ After setting the values, this method sets the \c read_p property for
+ \e dest.
+
+ @param dest An Array. The values are written to this array, reusing
+ its storage. Existing values are lost.
+ @param src The source data.
+ @param src_len The number of elements in the \e src array.
+ @exception Error Thrown if \e dest is not a numeric-type array (Byte, ...,
+ Float64) or if the number of elements in \e src does not match the number
+ is \e dest. */
+void set_array_using_double(Array * dest, double *src, int src_len)
+{
+    // Simple types are Byte, ..., Float64, String and Url.
+    if ((dest->type() == dods_array_c && !dest->var()->is_simple_type()) 
+	|| dest->var()->type() == dods_str_c 
+	|| dest->var()->type() == dods_url_c)
+        throw InternalErr(__FILE__, __LINE__,
+                "The function requires a DAP numeric-type array argument.");
+
+    // Test sizes. Note that Array::length() takes any constraint into account
+    // when it returns the length. Even if this was removed, the 'helper'
+    // function this uses calls Vector::val2buf() which uses Vector::width()
+    // which in turn uses length().
+    if (dest->length() != src_len)
+        throw InternalErr(__FILE__, __LINE__,
+                "The source and destination array sizes don't match ("
+                + long_to_string(src_len) + " versus "
+                + long_to_string(dest->length()) + ").");
+
+    // The types of arguments that the CE Parser will build for numeric
+    // constants are limited to Uint32, Int32 and Float64. See ce_expr.y.
+    // Expanded to work for any numeric type so it can be used for more than
+    // just arguments.
+    switch (dest->var()->type()) {
+    case dods_byte_c:
+        set_array_using_double_helper<dods_byte>(dest, src, src_len);
+        break;
+    case dods_uint16_c:
+        set_array_using_double_helper<dods_uint16>(dest, src, src_len);
+        break;
+    case dods_int16_c:
+        set_array_using_double_helper<dods_int16>(dest, src, src_len);
+        break;
+    case dods_uint32_c:
+        set_array_using_double_helper<dods_uint32>(dest, src, src_len);
+        break;
+    case dods_int32_c:
+        set_array_using_double_helper<dods_int32>(dest, src, src_len);
+        break;
+    case dods_float32_c:
+        set_array_using_double_helper<dods_float32>(dest, src, src_len);
+        break;
+    case dods_float64_c:
+        set_array_using_double_helper<dods_float64>(dest, src, src_len);
+        break;
+    default:
+        throw InternalErr(__FILE__, __LINE__,
+                "The argument list built by the CE parser contained an unsupported numeric type.");
+    }
+
+    // Set the read_p property.
+    dest->set_read_p(true);
+}
+
+template<class T> static double *extract_double_array_helper(Array * a)
+{
+    int length = a->length();
+
+    T *b = new T[length];
+    a->value(b);
+
+    double *dest = new double[length];
+    for (int i = 0; i < length; ++i)
+        dest[i] = (double) b[i];
+    delete[]b;
+
+    return dest;
+}
+
+/** Given a pointer to an Array which holds a numeric type, extract the
+ values and return in an array of doubles. This function allocates the
+ array using 'new double[n]' so delete[] can be used when you are done
+ the data. */
+double *extract_double_array(Array * a)
+{
+    // Simple types are Byte, ..., Float64, String and Url.
+    if ((a->type() == dods_array_c && !a->var()->is_simple_type())
+	|| a->var()->type() == dods_str_c || a->var()->type() == dods_url_c)
+        throw Error(malformed_expr,
+                "The function requires a DAP numeric-type array argument.");
+
+    if (!a->read_p())
+        throw InternalErr(__FILE__, __LINE__,
+                string("The Array '") + a->name() +
+                "'does not contain values.");
+
+    // The types of arguments that the CE Parser will build for numeric
+    // constants are limited to Uint32, Int32 and Float64. See ce_expr.y.
+    // Expanded to work for any numeric type so it can be used for more than
+    // just arguments.
+    switch (a->var()->type()) {
+    case dods_byte_c:
+        return extract_double_array_helper<dods_byte>(a);
+    case dods_uint16_c:
+        return extract_double_array_helper<dods_uint16>(a);
+    case dods_int16_c:
+        return extract_double_array_helper<dods_int16>(a);
+    case dods_uint32_c:
+        return extract_double_array_helper<dods_uint32>(a);
+    case dods_int32_c:
+        return extract_double_array_helper<dods_int32>(a);
+    case dods_float32_c:
+        return extract_double_array_helper<dods_float32>(a);
+    case dods_float64_c:
+        return extract_double_array_helper<dods_float64>(a);
+    default:
+        throw InternalErr(__FILE__, __LINE__,
+                "The argument list built by the CE parser contained an unsupported numeric type.");
+    }
+}
+
+/** Given a BaseType pointer, extract the numeric value it contains and return
+ it in a C++ double.
+
+ @param arg The BaseType pointer
+ @return A C++ double
+ @exception Error thrown if the referenced BaseType object does not contain
+ a DAP numeric value. */
+double extract_double_value(BaseType * arg)
+{
+    // Simple types are Byte, ..., Float64, String and Url.
+    if (!arg->is_simple_type() || arg->type() == dods_str_c || arg->type()
+            == dods_url_c)
+        throw Error(malformed_expr,
+                "The function requires a DAP numeric-type argument.");
+
+    if (!arg->read_p())
+        throw InternalErr(__FILE__, __LINE__,
+                "The CE Evaluator built an argument list where some constants held no values.");
+
+    // The types of arguments that the CE Parser will build for numeric
+    // constants are limited to Uint32, Int32 and Float64. See ce_expr.y.
+    // Expanded to work for any numeric type so it can be used for more than
+    // just arguments.
+    switch (arg->type()) {
+    case dods_byte_c:
+        return (double)(dynamic_cast<Byte&>(*arg).value());
+    case dods_uint16_c:
+        return (double)(dynamic_cast<UInt16&>(*arg).value());
+    case dods_int16_c:
+        return (double)(dynamic_cast<Int16&>(*arg).value());
+    case dods_uint32_c:
+        return (double)(dynamic_cast<UInt32&>(*arg).value());
+    case dods_int32_c:
+        return (double)(dynamic_cast<Int32&>(*arg).value());
+    case dods_float32_c:
+        return (double)(dynamic_cast<Float32&>(*arg).value());
+    case dods_float64_c:
+        return dynamic_cast<Float64&>(*arg).value();
+    default:
+        throw InternalErr(__FILE__, __LINE__,
+                "The argument list built by the CE parser contained an unsupported numeric type.");
+    }
+}
+
+/** This server-side function returns version information for the server-side
+ functions. Note that this function takes no arguments and returns a
+ String using the BaseType value/result parameter.
+
+ @param btpp A pointer to the return value; caller must delete.
+*/
+void
+function_version(int, BaseType *[], DDS &, BaseType **btpp)
+{
+    string
+            xml_value =
+                    "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\
+                       <functions>\
+                       <function name=\"geogrid\" version=\"1.2\"/>\
+                       <function name=\"grid\" version=\"1.0\"/>\
+                       <function name=\"linear_scale\" version=\"1.0b1\"/>\
+                       <function name=\"version\" version=\"1.0\"/>\
+        	       <function name=\"dap\" version=\"1.0\"/>\
+                     </functions>";
+
+    //                        <function name=\"geoarray\" version=\"0.9b1\"/>
+
+    Str *response = new Str("version");
+
+    response->set_value(xml_value);
+    *btpp = response;
+    return;
+}
+
+void
+function_dap(int, BaseType *[], DDS &, ConstraintEvaluator &)
+{
+#ifdef FUNCTION_DAP
+    if (argc != 1) {
+	throw Error("The 'dap' function must be called with a version number.\n\
+	see http://docs.opendap.org/index.php/Server_Side_Processing_Functions#dap");
+    }
+
+    double pv = extract_double_value(argv[0]);
+    dds.set_dap_version(pv);
+#else
+    throw Error("The 'dap' function is not supported in lieu of Constraint expression 'keywords.'\n\
+see http://docs.opendap.org/index.php/Server_Side_Processing_Functions#keywords");
+#endif
+}
+
+static void parse_gse_expression(gse_arg * arg, BaseType * expr)
+{
+    gse_restart(0); // Restart the scanner.
+    void *cls = gse_string(extract_string_argument(expr).c_str());
+    // gse_switch_to_buffer(cls); // Get set to scan the string.
+    bool status = gse_parse((void *) arg) == 0;
+    gse_delete_buffer(cls);
+    if (!status)
+        throw Error(malformed_expr, "Error parsing grid selection.");
+}
+
+static void apply_grid_selection_expr(Grid * grid, GSEClause * clause)
+{
+    // Basic plan: For each map, look at each clause and set start and stop
+    // to be the intersection of the ranges in those clauses.
+    Grid::Map_iter map_i = grid->map_begin();
+    while (map_i != grid->map_end() && (*map_i)->name() != clause->get_map_name())
+        ++map_i;
+
+    if (map_i == grid->map_end())
+        throw Error(malformed_expr,"The map vector '" + clause->get_map_name()
+                + "' is not in the grid '" + grid->name() + "'.");
+
+    // Use pointer arith & the rule that map order must match array dim order
+    Array::Dim_iter grid_dim = (grid->get_array()->dim_begin() + (map_i - grid->map_begin()));
+
+    Array *map = dynamic_cast < Array * >((*map_i));
+    if (!map)
+        throw InternalErr(__FILE__, __LINE__, "Expected an Array");
+    int start = max(map->dimension_start(map->dim_begin()), clause->get_start());
+    int stop = min(map->dimension_stop(map->dim_begin()), clause->get_stop());
+
+    if (start > stop) {
+        ostringstream msg;
+        msg
+                << "The expressions passed to grid() do not result in an inclusive \n"
+                << "subset of '" << clause->get_map_name()
+                << "'. The map's values range " << "from "
+                << clause->get_map_min_value() << " to "
+                << clause->get_map_max_value() << ".";
+        throw Error(malformed_expr,msg.str());
+    }
+
+    DBG(cerr << "Setting constraint on " << map->name()
+            << "[" << start << ":" << stop << "]" << endl);
+
+    // Stride is always one.
+    map->add_constraint(map->dim_begin(), start, 1, stop);
+    grid->get_array()->add_constraint(grid_dim, start, 1, stop);
+}
+
+static void apply_grid_selection_expressions(Grid * grid,
+        vector < GSEClause * >clauses)
+{
+    vector < GSEClause * >::iterator clause_i = clauses.begin();
+    while (clause_i != clauses.end())
+        apply_grid_selection_expr(grid, *clause_i++);
+
+    grid->set_read_p(false);
+}
+
+/** The grid function uses a set of relational expressions to form a selection
+ within a Grid variable based on the values in the Grid's map vectors.
+ Thus, if a Grid has a 'temperature' map which ranges from 0.0 to 32.0
+ degrees, it's possible to request the values of the Grid that fall between
+ 10.5 and 12.5 degrees without knowing to which array indexes those values
+ correspond. The function takes one or more arguments:<ul>
+ <li>The name of a Grid.</li>
+ <li>Zero or more strings which hold relational expressions of the form:<ul>
+ <li><code><map var> <relop> <constant></code></li>
+ <li><code><constant> <relop> <map var> <relop>
+ <constant></code></li>
+ </ul></li>
+ </ul>
+
+ Each of the relation expressions is applied to the Grid and the result is
+ returned.
+
+ @note Since this is a function and one of the arguments is the grid, the
+ grid is read (using the Grid::read() method) at the time the argument list
+ is built.
+
+ @todo In order to be used by geogrid() , this code may have to be modified
+ so that the maps and array are not re-read by the serialize() method. It
+ might also be a good idea to change from the '?grid(SST,"10<time<20")'
+ syntax in a URL to '?SST&grid(SST,"10<time<20")' even though it's more
+ verbose in the URL, it would make the function a true 'selection operator'
+ and allow several grids to be returned with selections in one request.
+
+ @param argc The number of values in argv.
+ @param argv An array of BaseType pointers which hold the arguments to be
+ passed to geogrid. The arguments may be Strings, Integers, or Reals, subject
+ to the above constraints.
+ @param btpp A pointer to the return value; caller must delete.
+
+ @see geogrid() (func_geogrid_select) A function which has logic specific
+ to longitude/latitude selection. */
+void
+function_grid(int argc, BaseType * argv[], DDS &, BaseType **btpp)
+{
+    DBG(cerr << "Entering function_grid..." << endl);
+
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"grid\" version=\"1.0\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#grid\">\n" +
+    "</function>\n";
+
+    if (argc == 0) {
+        Str *response = new Str("info");
+        response->set_value(info);
+        *btpp = response;
+        return;
+    }
+
+    Grid *original_grid = dynamic_cast < Grid * >(argv[0]);
+    if (!original_grid)
+        throw Error(malformed_expr,"The first argument to grid() must be a Grid variable!");
+
+    // Duplicate the grid; ResponseBuilder::send_data() will delete the variable
+    // after serializing it.
+    BaseType *btp = original_grid->ptr_duplicate();
+    Grid *l_grid = dynamic_cast < Grid * >(btp);
+    if (!l_grid) {
+    	delete btp;
+        throw InternalErr(__FILE__, __LINE__, "Expected a Grid.");
+    }
+    
+    DBG(cerr << "grid: past initialization code" << endl);
+
+    // Read the maps. Do this before calling parse_gse_expression(). Avoid
+    // reading the array until the constraints have been applied because it
+    // might be really large.
+
+    // This version makes sure to set the send_p flags which is needed for
+    // the hdf4 handler (and is what should be done in general).
+    Grid::Map_iter i = l_grid->map_begin();
+    while (i != l_grid->map_end())
+        (*i++)->set_send_p(true);
+    l_grid->read();
+
+    DBG(cerr << "grid: past map read" << endl);
+
+    // argv[1..n] holds strings; each are little expressions to be parsed.
+    // When each expression is parsed, the parser makes a new instance of
+    // GSEClause. GSEClause checks to make sure the named map really exists
+    // in the Grid and that the range of values given makes sense.
+    vector < GSEClause * > clauses;
+    gse_arg *arg = new gse_arg(l_grid);
+    for (int i = 1; i < argc; ++i) {
+        parse_gse_expression(arg, argv[i]);
+        clauses.push_back(arg->get_gsec());
+    }
+    delete arg;
+    arg = 0;
+
+    apply_grid_selection_expressions(l_grid, clauses);
+
+    DBG(cerr << "grid: past gse application" << endl);
+
+    l_grid->get_array()->set_send_p(true);
+
+    l_grid->read();
+
+    *btpp = l_grid;
+    return;
+}
+
+/** The geogrid function returns the part of a Grid which includes a
+ geographically specified rectangle. The arguments to the function are the
+ name of a Grid, the left-top and right-bottom points of the rectangle and
+ zero or more relational expressions of the sort that the grid function
+ accepts. The constraints on the arguments are:<ul> <li>The Grid must have
+ Latitude and Longitude map vectors. Those are discovered by looking for
+ map vectors which satisfy enough of any one of a set of conventions to
+ make the identification of those map vectors positive or by guessing
+ which maps are which. The set of conventions supported is: COARDS, CF
+ 1.0, GDT and CSC (see
+ http://www.unidata.ucar.edu/software/netcdf/conventions.html). If the
+ geogrid guesses at the maps, it adds an attribute (geogrid_warning) which
+ says so. (in version 1.1)</li> <li>The rectangle corner points are in
+ Longitude-Latitude. Longitude may be given using -180 to 180 or 0 to 360.
+ For data sources with global coverage, geogrid assumes that the Longitude
+ axis is circular. For requests made using 0/359 notation, it assumes it
+ is modulus 360. Requests made using -180/179 notation cannot use values
+ outside that range.</li> <li>The notation used to specify the rectangular
+ region determines the notation used in the longitude/latitude map vectors
+ of the Grid returned by the function.</li> <li>There are no restrictions
+ on the relational expressions beyond those for the grid() (see
+ func_grid_select()) function.</li> </ul>
+
+ @note The geogrid() function is implemented as a 'BaseType function'
+ which means that there can be only one function per request and no other
+ variables may be named in the request.
+
+ @param argc The number of values in argv.
+ @param argv An array of BaseType pointers which hold the arguments to be
+ passed to geogrid. The arguments may be Strings, Integers, or Reals,
+ subject to the above constraints.
+ @param btpp A pointer to the return value; caller must delete.
+
+ @return The constrained and read Grid, ready to be sent. */
+void
+function_geogrid(int argc, BaseType * argv[], DDS &, BaseType **btpp)
+{
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"geogrid\" version=\"1.2\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geogrid\">\n"+
+    "</function>";
+
+    if (argc == 0) {
+        Str *response = new Str("version");
+        response->set_value(info);
+        *btpp = response;
+        return ;
+    }
+
+    // There are two main forms of this function, one that takes a Grid and one
+    // that takes a Grid and two Arrays. The latter provides a way to explicitly
+    // tell the function which maps contain lat and lon data. The remaining
+    // arguments are the same for both versions, although that includes a
+    // varying argument list.
+
+    // Look at the types of the first three arguments to determine which of the
+    // two forms were used to call this function.
+    Grid *l_grid = 0;
+    if (argc < 1 || !(l_grid = dynamic_cast < Grid * >(argv[0]->ptr_duplicate())))
+	throw Error(malformed_expr,"The first argument to geogrid() must be a Grid variable!");
+
+    // Both forms require at least this many args
+    if (argc < 5)
+        throw Error(malformed_expr,"Wrong number of arguments to geogrid() (expected at least 5 args). See geogrid() for more information.");
+
+    bool grid_lat_lon_form;
+    Array *l_lat = 0;
+    Array *l_lon = 0;
+    if (!(l_lat = dynamic_cast < Array * >(argv[1]))) //->ptr_duplicate())))
+	grid_lat_lon_form = false;
+    else if (!(l_lon = dynamic_cast < Array * >(argv[2]))) //->ptr_duplicate())))
+	throw Error(malformed_expr,"When using the Grid, Lat, Lon form of geogrid() both the lat and lon maps must be given (lon map missing)!");
+    else
+	grid_lat_lon_form = true;
+
+    if (grid_lat_lon_form && argc < 7)
+        throw Error(malformed_expr,"Wrong number of arguments to geogrid() (expected at least 7 args). See geogrid() for more information.");
+
+#if 0
+    Grid *l_grid = dynamic_cast < Grid * >(argv[0]->ptr_duplicate());
+    if (!l_grid)
+        throw Error(malformed_expr,"The first argument to geogrid() must be a Grid variable!");
+#endif
+    // Read the maps. Do this before calling parse_gse_expression(). Avoid
+    // reading the array until the constraints have been applied because it
+    // might be really large.
+    //
+    // Trick: Some handlers build Grids from a combination of Array
+    // variables and attributes. Those handlers (e.g., hdf4) use the send_p
+    // property to determine which parts of the Grid to read *but they can
+    // only read the maps from within Grid::read(), not the map's read()*.
+    // Since the Grid's array does not have send_p set, it will not be read
+    // by the call below to Grid::read().
+    Grid::Map_iter i = l_grid->map_begin();
+    while (i != l_grid->map_end())
+        (*i++)->set_send_p(true);
+
+    l_grid->read();
+    // Calling read() above sets the read_p flag for the entire grid; clear it
+    // for the grid's array so that later on the code will be sure to read it
+    // under all circumstances.
+    l_grid->get_array()->set_read_p(false);
+    DBG(cerr << "geogrid: past map read" << endl);
+
+    // Look for Grid Selection Expressions tacked onto the end of the BB
+    // specification. If there are any, evaluate them before evaluating the BB.
+    int min_arg_count = (grid_lat_lon_form) ? 7 : 5;
+    if (argc > min_arg_count) {
+        // argv[5..n] holds strings; each are little Grid Selection Expressions
+        // to be parsed and evaluated.
+        vector < GSEClause * > clauses;
+        gse_arg *arg = new gse_arg(l_grid);
+        for (int i = min_arg_count; i < argc; ++i) {
+            parse_gse_expression(arg, argv[i]);
+            clauses.push_back(arg->get_gsec());
+        }
+        delete arg;
+        arg = 0;
+
+        apply_grid_selection_expressions(l_grid, clauses);
+    }
+
+    try {
+        // Build a GeoConstraint object. If there are no longitude/latitude
+        // maps then this constructor throws Error.
+        GridGeoConstraint gc(l_grid);
+
+        // This sets the bounding box and modifies the maps to match the
+        // notation of the box (0/359 or -180/179)
+        int box_index_offset = (grid_lat_lon_form) ? 3 : 1;
+        double top = extract_double_value(argv[box_index_offset]);
+        double left = extract_double_value(argv[box_index_offset + 1]);
+        double bottom = extract_double_value(argv[box_index_offset + 2]);
+        double right = extract_double_value(argv[box_index_offset + 3]);
+        gc.set_bounding_box(top, left, bottom, right);
+        DBG(cerr << "geogrid: past bounding box set" << endl);
+
+        // This also reads all of the data into the grid variable
+        gc.apply_constraint_to_data();
+        DBG(cerr << "geogrid: past apply constraint" << endl);
+
+        // In this function the l_grid pointer is the same as the pointer returned
+        // by this call. The caller of the function must free the pointer.
+        *btpp = gc.get_constrained_grid();
+        return;
+    }
+    catch (Error &e) {
+        throw e;
+    }
+    catch (exception & e) {
+        throw
+        InternalErr(string
+                ("A C++ exception was thrown from inside geogrid(): ")
+                + e.what());
+    }
+}
+
+// These static functions could be moved to a class that provides a more
+// general interface for COARDS/CF someday. Assume each BaseType comes bundled
+// with an attribute table.
+
+// This was ripped from parser-util.cc
+static double string_to_double(const char *val)
+{
+    char *ptr;
+    errno = 0;
+    // Clear previous value. 5/21/2001 jhrg
+
+#ifdef WIN32
+    double v = w32strtod(val, &ptr);
+#else
+    double v = strtod(val, &ptr);
+#endif
+
+    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
+            || *ptr != '\0') {
+        throw Error(malformed_expr,string("Could not convert the string '") + val + "' to a double.");
+    }
+
+    double abs_val = fabs(v);
+    if (abs_val > DODS_DBL_MAX || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
+        throw Error(malformed_expr,string("Could not convert the string '") + val + "' to a double.");
+
+    return v;
+}
+
+/** Look for any one of a series of attribute values in the attribute table
+ for \e var. This function treats the list of attributes as if they are ordered
+ from most to least likely/important. It stops when the first of the vector of
+ values is found. If the variable (var) is a Grid, this function also looks
+ at the Grid's Array for the named attributes. In all cases it returns the
+ first value found.
+ @param var Look for attributes in this BaseType variable.
+ @param attributes A vector of attributes; the first one found will be returned.
+ @return The attribute value in a double. */
+static double get_attribute_double_value(BaseType *var,
+        vector<string> &attributes)
+{
+    // This code also builds a list of the attribute values that have been
+    // passed in but not found so that an informative message can be returned.
+    AttrTable &attr = var->get_attr_table();
+    string attribute_value = "";
+    string values = "";
+    vector<string>::iterator i = attributes.begin();
+    while (attribute_value == "" && i != attributes.end()) {
+        values += *i;
+        if (!values.empty())
+            values += ", ";
+        attribute_value = attr.get_attr(*i++);
+    }
+
+    // If the value string is empty, then look at the grid's array (if it's a
+    // grid) or throw an Error.
+    if (attribute_value.empty()) {
+        if (var->type() == dods_grid_c)
+            return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attributes);
+        else
+            throw Error(malformed_expr,string("No COARDS/CF '") + values.substr(0, values.length() - 2)
+                    + "' attribute was found for the variable '"
+                    + var->name() + "'.");
+    }
+
+    return string_to_double(remove_quotes(attribute_value).c_str());
+}
+
+static double get_attribute_double_value(BaseType *var, const string &attribute)
+{
+    AttrTable &attr = var->get_attr_table();
+    string attribute_value = attr.get_attr(attribute);
+
+    // If the value string is empty, then look at the grid's array (if it's a
+    // grid or throw an Error.
+    if (attribute_value.empty()) {
+        if (var->type() == dods_grid_c)
+            return get_attribute_double_value(dynamic_cast<Grid&>(*var).get_array(), attribute);
+        else
+            throw Error(malformed_expr,string("No COARDS '") + attribute
+                    + "' attribute was found for the variable '"
+                    + var->name() + "'.");
+    }
+
+    return string_to_double(remove_quotes(attribute_value).c_str());
+}
+
+static double get_y_intercept(BaseType *var)
+{
+    vector<string> attributes;
+    attributes.push_back("add_offset");
+    attributes.push_back("add_off");
+    return get_attribute_double_value(var, attributes);
+}
+
+static double get_slope(BaseType *var)
+{
+    return get_attribute_double_value(var, "scale_factor");
+}
+
+static double get_missing_value(BaseType *var)
+{
+    return get_attribute_double_value(var, "missing_value");
+}
+
+/** Given a BaseType, scale it using 'y = mx + b'. Either provide the
+ constants 'm' and 'b' or the function will look for the COARDS attributes
+ 'scale_factor' and 'add_offset'.
+
+ @param argc A count of the arguments 
+ @param argv An array of pointers to each argument, wrapped in a child of BaseType
+ @param btpp A pointer to the return value; caller must delete.
+
+ @return The scaled variable, represented using Float64
+ @exception Error Thrown if scale_factor is not given and the COARDS
+ attributes cannot be found OR if the source variable is not a
+ numeric scalar, Array or Grid. */
+void
+function_linear_scale(int argc, BaseType * argv[], DDS &, BaseType **btpp)
+{
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"linear_scale\" version=\"1.0b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#linear_scale\">\n" +
+    "</function>";
+
+    if (argc == 0) {
+        Str *response = new Str("info");
+        response->set_value(info);
+        *btpp = response;
+        return;
+    }
+
+    // Check for 1 or 3 arguments: 1 --> use attributes; 3 --> m & b supplied
+    DBG(cerr << "argc = " << argc << endl);
+    if (!(argc == 1 || argc == 3 || argc == 4))
+        throw Error(malformed_expr,"Wrong number of arguments to linear_scale(). See linear_scale() for more information");
+
+    // Get m & b
+    bool use_missing = false;
+    double m, b, missing = 0.0;
+    if (argc == 4) {
+        m = extract_double_value(argv[1]);
+        b = extract_double_value(argv[2]);
+        missing = extract_double_value(argv[3]);
+        use_missing = true;
+    } else if (argc == 3) {
+        m = extract_double_value(argv[1]);
+        b = extract_double_value(argv[2]);
+        use_missing = false;
+    } else {
+        m = get_slope(argv[0]);
+
+        // This is really a hack; on a fair number of datasets, the y intercept
+        // is not given and is assumed to be 0. Here the function looks and
+        // catches the error if a y intercept is not found.
+        try {
+            b = get_y_intercept(argv[0]);
+        }
+        catch (Error &e) {
+            b = 0.0;
+        }
+
+        // This is not the best plan; the get_missing_value() function should
+        // do something other than throw, but to do that would require mayor
+        // surgery on get_attribute_double_value().
+        try {
+            missing = get_missing_value(argv[0]);
+            use_missing = true;
+        }
+        catch (Error &e) {
+            use_missing = false;
+        }
+    }
+
+    DBG(cerr << "m: " << m << ", b: " << b << endl);DBG(cerr << "use_missing: " << use_missing << ", missing: " << missing << endl);
+
+    // Read the data, scale and return the result. Must replace the new data
+    // in a constructor (i.e., Array part of a Grid).
+    BaseType *dest = 0;
+    double *data;
+    if (argv[0]->type() == dods_grid_c) {
+        Array &source = *dynamic_cast<Grid&>(*argv[0]).get_array();
+        source.set_send_p(true);
+        source.read();
+        data = extract_double_array(&source);
+        int length = source.length();
+        int i = 0;
+        while (i < length) {
+            DBG2(cerr << "data[" << i << "]: " << data[i] << endl);
+            if (!use_missing || !double_eq(data[i], missing))
+                data[i] = data[i] * m + b;
+            DBG2(cerr << " >> data[" << i << "]: " << data[i] << endl);
+            ++i;
+        }
+
+        // Vector::add_var will delete the existing 'template' variable
+        Float64 *temp_f = new Float64(source.name());
+        source.add_var(temp_f);
+#ifdef VAL2BUF
+        source.val2buf(static_cast<void*>(data), false);
+#else
+        source.set_value(data, i);
+#endif
+        delete [] data; // val2buf copies.
+        delete temp_f; // add_var copies and then adds.
+        dest = argv[0];
+    } else if (argv[0]->is_vector_type()) {
+        Array &source = dynamic_cast<Array&>(*argv[0]);
+        source.set_send_p(true);
+        // If the array is really a map, make sure to read using the Grid
+        // because of the HDF4 handler's odd behavior WRT dimensions.
+        if (source.get_parent() && source.get_parent()->type() == dods_grid_c)
+            source.get_parent()->read();
+        else
+            source.read();
+
+        data = extract_double_array(&source);
+        int length = source.length();
+        int i = 0;
+        while (i < length) {
+            if (!use_missing || !double_eq(data[i], missing))
+                data[i] = data[i] * m + b;
+            ++i;
+        }
+
+        Float64 *temp_f = new Float64(source.name());
+        source.add_var(temp_f);
+
+        source.val2buf(static_cast<void*>(data), false);
+
+        delete [] data; // val2buf copies.
+        delete temp_f; // add_var copies and then adds.
+
+        dest = argv[0];
+    } else if (argv[0]->is_simple_type() && !(argv[0]->type() == dods_str_c
+            || argv[0]->type() == dods_url_c)) {
+        double data = extract_double_value(argv[0]);
+        if (!use_missing || !double_eq(data, missing))
+            data = data * m + b;
+
+        dest = new Float64(argv[0]->name());
+
+        dest->val2buf(static_cast<void*>(&data));
+
+    } else {
+        throw Error(malformed_expr,"The linear_scale() function works only for numeric Grids, Arrays and scalars.");
+    }
+
+    *btpp = dest;
+    return;
+}
+
+#if 0
+/** Perform a selection on the array using geographical coordinates. This
+ function takes several groups of arguments.
+ <ul>
+ <li>geoarray(var, top, left, bottom, right)</li>
+ <li>geoarray(var, top, left, bottom, right, var_top, v_left, v_bottom, v_right)</li>
+ <li>geoarray(var, top, left, bottom, right, var_top, v_left, v_bottom, v_right, projection, datum)</li>
+ </ul>
+
+ @note Only the plat-carre projection and wgs84 datum are currently
+ supported.
+
+ @param argc A count of the arguments 
+ @param argv An array of pointers to each argument, wrapped in a child of BaseType
+ @param btpp A pointer to the return value; caller must delete.
+
+ @return The Array, constrained by the selection
+ @exception Error Thrown if thins go awry. */
+void
+function_geoarray(int argc, BaseType * argv[], DDS &, BaseType **btpp)
+{
+    string info =
+    string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n") +
+    "<function name=\"geoarray\" version=\"0.9b1\" href=\"http://docs.opendap.org/index.php/Server_Side_Processing_Functions#geoarray\">\n" +
+    "</function>";
+
+    if (argc == 0) {
+        Str *response = new Str("version");
+        response->set_value(info);
+        *btpp = response;
+        return;
+    }
+
+    DBG(cerr << "argc = " << argc << endl);
+    if (!(argc == 5 || argc == 9 || argc == 11))
+        throw Error(malformed_expr,"Wrong number of arguments to geoarray(). See geoarray() for more information.");
+
+    // Check the Array (and dup because the caller will free the variable).
+    Array *l_array = dynamic_cast < Array * >(argv[0]->ptr_duplicate());
+    if (!l_array)
+        throw Error(malformed_expr,"The first argument to geoarray() must be an Array variable!");
+
+    try {
+
+        // Read the bounding box and variable extents from the params
+        double bb_top = extract_double_value(argv[1]);
+        double bb_left = extract_double_value(argv[2]);
+        double bb_bottom = extract_double_value(argv[3]);
+        double bb_right = extract_double_value(argv[4]);
+
+        switch (argc) {
+            case 5: {
+            	ArrayGeoConstraint agc(l_array);
+
+         		agc.set_bounding_box(bb_left, bb_top, bb_right, bb_bottom);
+				// This also reads all of the data into the grid variable
+        		agc.apply_constraint_to_data();
+        		*btpp = agc.get_constrained_array();
+        		return;
+            	break;
+            }
+            case 9: {
+                double var_top = extract_double_value(argv[5]);
+                double var_left = extract_double_value(argv[6]);
+                double var_bottom = extract_double_value(argv[7]);
+                double var_right = extract_double_value(argv[8]);
+                ArrayGeoConstraint agc (l_array, var_left, var_top, var_right, var_bottom);
+
+        		agc.set_bounding_box(bb_left, bb_top, bb_right, bb_bottom);
+				// This also reads all of the data into the grid variable
+        		agc.apply_constraint_to_data();
+        		*btpp =  agc.get_constrained_array();
+        		return;
+                break;
+            }
+            case 11: {
+                double var_top = extract_double_value(argv[5]);
+                double var_left = extract_double_value(argv[6]);
+                double var_bottom = extract_double_value(argv[7]);
+                double var_right = extract_double_value(argv[8]);
+                string projection = extract_string_argument(argv[9]);
+                string datum = extract_string_argument(argv[10]);
+                ArrayGeoConstraint agc(l_array,
+                        var_left, var_top, var_right, var_bottom,
+                        projection, datum);
+
+        		agc.set_bounding_box(bb_left, bb_top, bb_right, bb_bottom);
+				// This also reads all of the data into the grid variable
+        		agc.apply_constraint_to_data();
+        		*btpp = agc.get_constrained_array();
+        		return;
+                break;
+            }
+            default:
+            	throw InternalErr(__FILE__, __LINE__, "Wrong number of args to geoarray.");
+        }
+    }
+    catch (Error & e) {
+        throw e;
+    }
+    catch (exception & e) {
+        throw
+        InternalErr(string
+                ("A C++ exception was thrown from inside geoarray(): ")
+                + e.what());
+
+    }
+
+    throw InternalErr(__FILE__, __LINE__, "Impossible condition in geoarray.");
+}
+#endif
+
+void register_functions(ConstraintEvaluator & ce)
+{
+    ce.add_function("grid", function_grid);
+    ce.add_function("geogrid", function_geogrid);
+    ce.add_function("linear_scale", function_linear_scale);
+#if 0
+    ce.add_function("geoarray", function_geoarray);
+#endif
+    ce.add_function("version", function_version);
+
+    ce.add_function("dap", function_dap);
+}
+
+} // namespace libdap
diff --git a/ce_functions.h b/ce_functions.h
new file mode 100644
index 0000000..cf4dce8
--- /dev/null
+++ b/ce_functions.h
@@ -0,0 +1,66 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Declarations for CE functions.
+//
+// 1/15/99 jhrg
+
+#ifndef _ce_functions_h
+#define _ce_functions_h
+
+#include "BaseType.h"
+#include "Array.h"
+#include "Error.h"
+#include "ConstraintEvaluator.h"
+
+namespace libdap
+{
+
+// These functions are use by the code in GeoConstraint
+string extract_string_argument(BaseType *arg) ;
+double extract_double_value(BaseType *arg) ;
+double *extract_double_array(Array *a) ;
+void set_array_using_double(Array *dest, double *src, int src_len) ;
+
+void func_version(int argc, BaseType *argv[], DDS &dds, BaseType **btpp) ;
+void function_grid(int argc, BaseType *argv[], DDS &dds, BaseType **btpp) ;
+void function_geogrid(int argc, BaseType *argv[], DDS &dds, BaseType **btpp) ;
+void function_linear_scale(int argc, BaseType *argv[], DDS &dds, BaseType **btpp) ;
+void function_geoarray(int argc, BaseType *argv[], DDS &dds, BaseType **btpp) ;
+
+// Projection function used to pass DAP version information
+void function_dap(int argc, BaseType *argv[], DDS &dds, ConstraintEvaluator &ce);
+
+void register_functions(ConstraintEvaluator &ce);
+
+} // namespace libdap
+
+#endif // _ce_functions_h
diff --git a/ce_parser.h b/ce_parser.h
new file mode 100644
index 0000000..4e0feff
--- /dev/null
+++ b/ce_parser.h
@@ -0,0 +1,36 @@
+namespace libdap
+{
+
+struct ce_parser_arg
+{
+    ConstraintEvaluator *eval;
+    DDS *dds;
+
+    ce_parser_arg() : eval(0), dds(0)
+    {}
+    ce_parser_arg(ConstraintEvaluator *e, DDS *d) : eval(e), dds(d)
+    {}
+    virtual ~ce_parser_arg()
+    {}
+
+    ConstraintEvaluator *get_eval()
+    {
+        return eval;
+    }
+    void set_eval(ConstraintEvaluator *obj)
+    {
+        eval = obj;
+    }
+
+    DDS *get_dds()
+    {
+        return dds;
+    }
+    void set_dds(DDS *obj)
+    {
+        dds = obj;
+    }
+};
+
+} // namespace libdap
+
diff --git a/cgi_util.h b/cgi_util.h
new file mode 100644
index 0000000..247f431
--- /dev/null
+++ b/cgi_util.h
@@ -0,0 +1,15 @@
+/*
+ * cgi_util.h
+ *
+ * Compatibility header file. Use <mime_util.h> instead.
+ *
+ *  Created on: Aug 27, 2009
+ *      Author: jimg
+ */
+
+#ifndef CGI_UTIL_H_
+#define CGI_UTIL_H_
+
+#include <>mime_util.h>
+
+#endif /* CGI_UTIL_H_ */
diff --git a/conf/acinclude.m4 b/conf/acinclude.m4
new file mode 100644
index 0000000..d0ff1ae
--- /dev/null
+++ b/conf/acinclude.m4
@@ -0,0 +1,606 @@
+
+# m4 macros from the Unidata netcdf 2.3.2 pl4 distribution. Modified for use
+# with GNU Autoconf 2.1. I renamed these from UC_* to DODS_* so that there
+# will not be confusion when porting future versions of netcdf into the DODS
+# source distribution. Unidata, Inc. wrote the text of these macros and holds
+# a copyright on them.
+#
+# jhrg 3/27/95
+#
+# Added some of my own macros (don't blame Unidata for them!) starting with
+# DODS_PROG_LEX and down in the file. jhrg 2/11/96
+#
+# I've added a table of contents for this file. jhrg 2/2/98
+# 
+# 1. Unidata-derived macros. 
+# 2. Macros for finding libraries used by the core software.
+# 3. Macros used to test things about the compiler
+# 4. Macros for locating various systems (Matlab, etc.)
+# 5. Macros used to test things about the computer/OS/hardware
+#
+# $Id: acinclude.m4 18942 2008-06-25 21:27:05Z jimg $
+
+# 1. Unidata's macros
+#-------------------------------------------------------------------------
+
+# 2. Finding libraries 
+#
+# To use these in DODS software, in the Makefile.in use LIBS XTRALIBS for 
+# non-gui and LIBS GUILIBS XTRALIBS for the clients that link with the 
+# gui DAP++ library. These should be set by a line like LIBS=@LIBS@, etc.
+# Then the group should be used on the link line. 10/16/2000 jhrg
+#--------------------------------------------------------------------------
+
+# Electric fence and dbnew are used to debug malloc/new and free/delete.
+# I assume that if you use these switches you know enough to build the 
+# libraries. 2/3/98 jhrg
+
+AC_DEFUN([DODS_EFENCE], [dnl
+    AC_ARG_ENABLE(efence,
+		  [  --enable-efence         Runtime memory checks (malloc)],
+		  EFENCE=$enableval, EFENCE=no)
+
+    case "$EFENCE" in
+    yes)
+      AC_MSG_RESULT(Configuring dynamic memory checks on malloc/free calls)
+      LIBS="$LIBS -lefence"
+      ;;
+    *)
+      ;;
+    esac])
+
+AC_DEFUN([DODS_DBNEW], [dnl
+    AC_ARG_ENABLE(dbnew,
+	          [  --enable-dbnew          Runtime memory checks (new)],
+		  DBNEW=$enableval, DBNEW=no)
+
+    case "$DBNEW" in
+    yes)
+      AC_MSG_RESULT(Configuring dynamic memory checks on new/delete calls)
+      AC_DEFINE(TRACE_NEW, , [Use the dbnew library to trace bew/delete calls])
+      LIBS="$LIBS -ldbnew"
+      ;;
+    *)
+      ;;
+    esac])
+
+# check for hdf libraries
+# cross-compile problem with test option -d
+AC_DEFUN([DODS_HDF_LIBRARY], [dnl
+    AC_ARG_WITH(hdf,
+        [  --with-hdf=ARG          Where is the HDF library (directory)],
+        HDF_PATH=${withval}, HDF_PATH="$HDF_PATH")
+    if test ! -d "$HDF_PATH"
+    then
+        HDF_PATH="/usr/local/hdf"
+    fi
+    if test "$HDF_PATH"
+    then
+            LDFLAGS="$LDFLAGS -L${HDF_PATH}/lib"
+            INCS="$INCS -I${HDF_PATH}/include"
+            AC_SUBST(INCS)
+    fi
+
+dnl None of this works with HDF 4.1 r1. jhrg 8/2/97
+
+    AC_CHECK_LIB(z, deflate, LIBS="-lz $LIBS", nohdf=1)
+    AC_CHECK_LIB(jpeg, jpeg_start_compress, LIBS="-ljpeg $LIBS", nohdf=1)
+    AC_CHECK_LIB(df, Hopen, LIBS="-ldf $LIBS" , nohdf=1)
+    AC_CHECK_LIB(mfhdf, SDstart, LIBS="-lmfhdf $LIBS" , nohdf=1)])
+
+# 3. Compiler test macros
+#--------------------------------------------------------------------------
+
+AC_DEFUN([DODS_GCC_VERSION], [dnl
+    AC_MSG_CHECKING(for gcc/g++ 2.8 or greater)
+
+    GCC_VER=`gcc -v 2>&1 | awk '/version/ {print}'`
+
+    dnl We need the gcc version number as a number, without `.'s and limited
+    dnl to three digits. The old version below was replaced by Andy Jacobson's 
+    dnl patch which works with gcc 3, including the pre-release versions.
+
+    dnl GCC_VER=`echo $GCC_VER | sed 's@[[a-z ]]*\([[0-9.]]\)@\1@'`
+    GCC_VER=`echo $GCC_VER | sed 's at .*gcc version \([[0-9\.]]*\).*@\1@'`
+
+    case $GCC_VER in
+        *egcs*) AC_MSG_RESULT(Found egcs version ${GCC_VER}.) ;;
+	2.[[7-9]]*)   AC_MSG_RESULT(Found gcc/g++ version ${GCC_VER}) ;;
+	3.[[0-9]]*)   AC_MSG_RESULT(Found gcc/g++ version ${GCC_VER}) ;;
+        *)      AC_MSG_ERROR(must be at least version 2.7.x) ;;
+    esac])
+
+# 4. Macros to locate various programs/systems used by parts of DODS
+#---------------------------------------------------------------------------
+
+# Added by Ethan, 1999/06/21
+# Look for perl.
+# 
+# I modified the regexp below to remove any text that follows the version
+# number. This extra text was hosing the test. 7/15/99 jhrg
+
+AC_DEFUN([DODS_PROG_PERL], [dnl
+    AC_CHECK_PROG(PERL, perl, `which perl`)
+    case "$PERL" in
+	*perl*)
+	    perl_ver=`$PERL -v 2>&1 | awk '/This is perl/ {print}'`
+	    perl_ver=`echo $perl_ver | sed 's/This is perl,[[^0-9]]*\([[0-9._]]*\).*/\1/'`
+            perl_ver_main=`echo $perl_ver | sed 's/\([[0-9]]*\).*/\1/'`
+	    if test -n "$perl_ver" && test $perl_ver_main -ge 5
+	    then
+		AC_MSG_RESULT(Found perl version ${perl_ver}.)
+	    else
+		AC_MSG_ERROR(perl version: found ${perl_ver} should be at least 5.000.)
+	    fi
+	    ;;
+	*)
+	    AC_MSG_WARN(perl is required.)
+	    ;;
+    esac
+
+    AC_SUBST(PERL)])
+
+# Added by Ethan, 1999/06/21
+# Look for GNU tar.
+# 
+# I modified the regexp below but it still does not work exactly correctly; 
+# the variable tar_ver should have only the version number in it. However,
+# my version (1.12) spits out a multi-line thing. The regexp below gets the
+# version number from the first line but does not remove the subsequent lines
+# of garbage. 7/15/99 jhrg
+# Added awk line to handle multiline output. 1999/07/22 erd
+
+AC_DEFUN([DODS_PROG_GTAR], [dnl
+    AC_CHECK_PROGS(TAR,gtar tar,tar)
+    case "$TAR" in
+	*tar)
+	    tar_ver=`$TAR --version 2>&1 | awk '/G[[Nn]][[Uu]] tar/ {print}'`
+	    tar_ver=`echo $tar_ver | sed 's/.*GNU tar[[^0-9.]]*\([[0-9._]]*\)/\1/'`
+	    if test -n "$tar_ver"
+	    then
+		AC_MSG_RESULT(Found Gnu tar version ${tar_ver}.)
+	    else
+		AC_MSG_WARN(GNU tar is required for some Makefile targets.)
+	    fi
+	    ;;
+	*)
+	    AC_MSG_WARN(GNU tar is required for some Makefile targets.)
+	    ;;
+    esac
+
+    AC_SUBST(TAR)])
+
+# Find the matlab root directory
+# cross-compile problem with test option -d
+
+AC_DEFUN([DODS_MATLAB], [dnl
+    AC_ARG_WITH(matlab,
+        [  --with-matlab=ARG       Where is the Matlab root directory],
+        MATLAB_ROOT=${withval}, MATLAB_ROOT="$MATLAB_ROOT")
+    if test "$MATLAB_ROOT" = no; then
+        MATLAB_ROOT="$MATLAB_ROOT"
+    elif test ! -d "$MATLAB_ROOT"
+    then
+        MATLAB_ROOT=""
+    fi
+    if test -z "$MATLAB_ROOT"
+    then
+        AC_MSG_CHECKING(for matlab root)
+
+	MATLAB_ROOT=`mex -v 2>&1 | awk '/MATLAB *= / {print}'`
+	MATLAB_ROOT=`echo $MATLAB_ROOT | sed 's@[[^/]]*\(/.*\)@\1@'`
+
+	if test -z "$MATLAB_ROOT"
+	then
+	    AC_MSG_ERROR(Matlab not found! Run configure --help)
+        else
+	    AC_SUBST(MATLAB_ROOT)
+	    AC_MSG_RESULT($MATLAB_ROOT)
+        fi
+    else
+        AC_SUBST(MATLAB_ROOT)
+        AC_MSG_RESULT("Set Matlab root to $MATLAB_ROOT")
+    fi
+
+    dnl Find the lib directory (which is named according to machine type).
+    dnl The test was using -z; I changed it to -n to fix a problem withthe 
+    dnl matlab server build. The build did not find the libraries with the
+    dnl env var MATLAB_LIB was not set. 04/12/04 jhrg
+    AC_MSG_CHECKING(for matlab library dir)
+    if test -n "$MATLAB_LIB"
+    then
+        matlab_lib_dir=${MATLAB_LIB}
+    else
+        matlab_lib_dir=`find ${MATLAB_ROOT}/extern/lib -name 'libmat*' -print | sed '1q'`
+        matlab_lib_dir=`echo $matlab_lib_dir | sed 's@\(.*\)/libmat.*@\1@'`
+    fi
+    AC_MSG_RESULT($matlab_lib_dir)
+
+    if test "$matlab_lib_dir"
+    then
+	LDFLAGS="$LDFLAGS -L$matlab_lib_dir"
+	dnl This is used by the nph script to set LD_LIBRARY_PATH
+	AC_SUBST(matlab_lib_dir)
+    fi
+    
+    dnl sleazy test for version 5; look for the version 4 compat flag
+
+    if grep V4_COMPAT ${MATLAB_ROOT}/extern/include/mat.h > /dev/null 2>&1
+    then
+	dnl if we're here, we're linking under ML 5 or 6. 02/10/03 jhrg
+	MAT_VERSION_FLAG="-V4"
+	dnl ML 6 lacks libmi.a/.so. 02/10/03 jhrg
+	if access -r ${matlab_lib_dir}/libmi.*
+	then
+	    MATLIBS="-lmat -lmi -lmx -lut"
+	else
+	    MATLIBS="-lmat -lmx -lut"
+	fi
+    else
+       MAT_VERSION_FLAG=""
+       MATLIBS="-lmat"
+    fi
+
+    AC_CHECK_LIB(ots, _OtsDivide64Unsigned, MATLIBS="$MATLIBS -lots", )
+    AC_SUBST(MATLIBS)
+    AC_SUBST(MAT_VERSION_FLAG)])
+
+# cross-compile problem with test option -d
+AC_DEFUN([DODS_DSP_ROOT], [dnl
+
+    AC_ARG_WITH(dsp,
+		[  --with-dsp=DIR          Directory containing DSP software from U of Miami],
+		DSP_ROOT=${withval}, DSP_ROOT="$DSP_ROOT")
+
+    if test ! -d "$DSP_ROOT"
+    then
+        DSP_ROOT=""
+    fi
+    if test -z "$DSP_ROOT"
+    then
+	AC_MSG_CHECKING(for the DSP library root directory)
+
+	for p in /usr/local/src/DSP /usr/local/DSP \
+		 /usr/local/src/dsp /usr/local/dsp \
+		 /usr/contrib/src/dsp /usr/contrib/dsp \
+		 $DODS_ROOT/third-party/dsp /usr/dsp /data1/dsp
+	do
+	    if test -z "$DSP_ROOT"
+	    then
+	    	for d in `ls -dr ${p}* 2>/dev/null`
+		do
+		    if test -f ${d}/inc/dsplib.h
+		    then
+		        DSP_ROOT=${d}
+		        break
+		    fi
+	        done
+	    fi
+	done
+    fi
+
+    if test "$DSP_ROOT"
+    then
+	AC_SUBST(DSP_ROOT)
+	dnl Only add this path to gcc's options... jhrg 11/15/96
+	INCS="$INCS -I\$(DSP_ROOT)/inc"
+	AC_SUBST(INCS) 		# 09/20/02 jhrg
+	LDFLAGS="$LDFLAGS -L\$(DSP_ROOT)/lib -L\$(DSP_ROOT)/shlib"
+	AC_MSG_RESULT(Set DSP root directory to $DSP_ROOT) 
+    else
+        AC_MSG_ERROR(not found! see configure --help)
+    fi])
+
+# Find IDL. 9/23/99 jhrg
+
+AC_DEFUN([DODS_IDL], [dnl
+    AC_ARG_WITH(idl,
+        [  --with-idl=ARG       Where is the IDL root directory],
+        IDL_ROOT=${withval}, IDL_ROOT="$IDL_ROOT")
+    AC_REQUIRE([AC_CANONICAL_HOST])
+
+    AC_MSG_CHECKING(for the IDL root directory)
+    if test -z "$IDL_ROOT"
+    then
+        # Find IDL's root directory by looking at the exectuable and then 
+        # finding where that symbolic link points.
+        # !!! Doesn't work if idl isn't a symbolic link - erd !!!
+	# I think that the following 'if' fixes the symbolic link problem. 
+	# 05/02/03 jhrg 
+        idl_loc=`which idl`
+	if echo `ls -l $idl_loc` | grep '.*->.*' > /dev/null 2>&1
+	then
+            idl_loc=`ls -l $idl_loc | sed 's/.*->[ ]*\(.*\)$/\1/'`
+	fi
+        IDL_ROOT=`echo $idl_loc | sed 's/\(.*\)\/bin.*/\1/'`
+    fi
+
+    AC_MSG_RESULT($IDL_ROOT)
+    AC_SUBST(IDL_ROOT)
+
+    # Now find where the IDL 5.2 or later sharable libraries live.
+    # NB: This won't work if libraries for several architecutures are 
+    # installed for several machines.
+    AC_MSG_CHECKING(for the IDL sharable library directory)
+    # cd to the IDL root because it is likely a symbolic link and find 
+    # won't normally follow symbolic links.
+    IDL_LIBS=`(cd $IDL_ROOT; find . -name 'libidl.so' -print)`
+    # Strip off the leading `.' (it's there because we ran find in the CWD) 
+    # and the name of the library used to find the directory.
+    IDL_LIBS=`echo $IDL_LIBS | sed 's/\.\(.*\)\/libidl.so/\1/' | sed '1q'`
+    IDL_LIBS=${IDL_ROOT}${IDL_LIBS}
+    AC_MSG_RESULT($IDL_LIBS)
+    AC_SUBST(IDL_LIBS)])
+
+
+# 5. Misc stuff
+#---------------------------------------------------------------------------
+
+AC_DEFUN([DODS_DEBUG_OPTION], [dnl
+    AC_ARG_ENABLE(debug, 
+		  [  --enable-debug=ARG      Program instrumentation (1,2)],
+		  DEBUG=$enableval, DEBUG=no)
+
+    case "$DEBUG" in
+    no) 
+      ;;
+    1)
+      AC_MSG_RESULT(Setting debugging to level 1)
+      AC_DEFINE(DODS_DEBUG)
+      ;;
+    2) 
+      AC_MSG_RESULT(Setting debugging to level 2)
+      AC_DEFINE(DODS_DEBUG, , [Set instrumentation to level 1 (see debug.h)])
+      AC_DEFINE(DODS_DEBUG2, , [Set instrumentation to level 2])
+      ;;
+    *)
+      AC_MSG_ERROR(Bad debug value)
+      ;;
+    esac])
+
+AC_DEFUN([DODS_OS], [dnl
+    AC_MSG_CHECKING(type of operating system)
+    # I have removed the following test because some systems (e.g., SGI)
+    # define OS in a way that breaks this code but that is close enough
+    # to also be hard to detect. jhrg 3/23/97
+    #  if test -z "$OS"; then
+    #  fi 
+    OS=`uname -s | tr '[[A-Z]]' '[[a-z]]' | sed 's;/;;g'`
+    if test -z "$OS"; then
+        AC_MSG_WARN(OS unknown!)
+    fi
+    case $OS in
+        aix)
+            ;;
+        hp-ux)
+            OS=hpux`uname -r | sed 's/[[A-Z.0]]*\([[0-9]]*\).*/\1/'`
+            ;;
+        irix)
+            OS=${OS}`uname -r | sed 's/\..*//'`
+            ;;
+        # I added the following case because the `tr' command above *seems* 
+	# to fail on Irix 5. I can get it to run just fine from the shell, 
+	# but not in the configure script built using this macro. jhrg 8/27/97
+        IRIX)
+            OS=irix`uname -r | sed 's/\..*//'`
+	    ;;
+        osf*)
+            ;;
+        sn*)
+            OS=unicos
+            ;;
+        sunos)
+            OS_MAJOR=`uname -r | sed 's/\..*//'`
+            OS=$OS$OS_MAJOR
+            ;;
+        ultrix)
+            case `uname -m` in
+            VAX)
+                OS=vax-ultrix
+                ;;
+            esac
+            ;;
+        *)
+            # On at least one UNICOS system, 'uname -s' returned the
+            # hostname (sigh).
+            if uname -a | grep CRAY >/dev/null; then
+                OS=unicos
+            fi
+            ;;
+    esac
+
+    # Adjust OS for CRAY MPP environment.
+    #
+    case "$OS" in
+    unicos)
+
+        case "$CC$TARGET$CFLAGS" in
+        *cray-t3*)
+            OS=unicos-mpp
+            ;;
+        esac
+        ;;
+    esac
+
+    AC_SUBST(OS)
+
+    AC_MSG_RESULT($OS)])
+
+
+AC_DEFUN([DODS_MACHINE], [dnl
+    AC_MSG_CHECKING(type of machine)
+
+    if test -z "$MACHINE"; then
+    MACHINE=`uname -m | tr '[[A-Z]]' '[[a-z]]'`
+    case $OS in
+        aix*)
+            MACHINE=rs6000
+            ;;
+        hp*)
+            MACHINE=hp`echo $MACHINE | sed 's%/.*%%'`
+            ;;
+        sunos*)
+            case $MACHINE in
+                sun4*)
+                    MACHINE=sun4
+                    ;;
+            esac
+            ;;
+        irix*)
+            case $MACHINE in
+                ip2?)
+                    MACHINE=sgi
+                    ;;
+            esac
+            ;;
+	ultrix*)
+	    case $MACHINE in
+		vax*)
+		     case "$CC" in
+        		/bin/cc*|cc*)
+echo "changing C compiler to \`vcc' because \`cc' floating-point is broken"
+            		CC=vcc
+            		;;
+		     esac
+		     ;;
+	    esac
+	    ;;
+
+    esac
+    fi
+
+    AC_SUBST(MACHINE)
+    AC_MSG_RESULT($MACHINE)])
+
+AC_DEFUN([DODS_CHECK_SIZES], [dnl
+    # Ignore the errors about AC_TRY_RUN missing an argument. jhrg 5/2/95
+
+    AC_REQUIRE([AC_PROG_CC])
+
+    AC_CHECK_SIZEOF(int)
+    AC_CHECK_SIZEOF(long)
+    AC_CHECK_SIZEOF(char)
+    AC_CHECK_SIZEOF(double)
+    AC_CHECK_SIZEOF(float)
+
+    # check for C99 types, headers and functions
+    AC_CHECK_HEADER([inttypes.h],[dap_inttypes_header=yes],,)
+    # DINT32 4
+    AC_CHECK_SIZEOF([int32_t])
+    # DUINT32
+    AC_CHECK_SIZEOF([uint32_t])
+    # DINT16 short
+    AC_CHECK_SIZEOF([int16_t])
+    # DUINT16 unsigned short
+    AC_CHECK_SIZEOF([uint16_t])
+    # DBYTE 1
+    AC_CHECK_SIZEOF([uint8_t])
+    if test x"$dap_inttypes_header" = x'yes' -a $ac_cv_sizeof_int32_t -eq 4 -a $ac_cv_sizeof_int16_t -eq 2 -a $ac_cv_sizeof_uint8_t -eq 1 -a $ac_cv_sizeof_double -eq 8; then
+        dap_use_c99_types=yes
+    fi
+    AM_CONDITIONAL([USE_C99_TYPES],[test x"$dap_use_c99_types" = 'xyes'])
+
+    # I've separated the typedefs from the config.h header because other
+    # projects which use the DAP were getting conflicts with their includes,
+    # or the includes of still other libraries, and config.h. The
+    # config.h header is now included only by .cc and .c files and headers
+    # that need the typedefs use dods-datatypes.h.
+    # there are 2 possibilities for the definition of dods_int32, ...,
+    # types. First possibility is that the C99 types are used and
+    # dods-datatypes-static.h is copied. In that case the following
+    # definitions are not really usefull. In case the C99 types are
+    # not available, dods-datatypes-config.h.in is used to generate
+    # dods-datatypes.h.
+    # The code below makes dods-datatypes-config.h stand on its own.
+    # 8/2/2000 jhrg
+
+    # DMH: Divide into two sets of tests: one for DODS and one for XDR
+    if test x"$dap_use_c99_types" = 'xyes'; then
+        DODS_INT32=int32_t
+        DODS_UINT32=uint32_t
+        DODS_INT16=int16_t
+        DODS_UINT16=uint16_t
+        DODS_BYTE=uint8_t
+    else
+        DODS_INT16=short
+        DODS_UINT16="unsigned short"
+	DODS_INT32=int
+	DODS_UINT32="unsigned int"
+	DODS_BYTE="unsigned char"
+    fi
+    DODS_FLOAT64=double
+    DODS_FLOAT32=float
+
+    # I'm using the three arg form of AC_DEFINE_UNQUOTED because autoheader
+    # needs the third argument (although I don't quite get the specifics...
+    # 2/15/2001 jhrg
+    AC_DEFINE_UNQUOTED(DINT32, $DODS_INT32, [int32])
+    AC_DEFINE_UNQUOTED(DUINT32, $DODS_UINT32, [uint32])
+    AC_DEFINE_UNQUOTED(DINT16, $DODS_INT16, [dint16])
+    AC_DEFINE_UNQUOTED(DUINT16, $DODS_UINT16, [uint16])
+    AC_DEFINE_UNQUOTED(DFLOAT64, $DODS_FLOAT64, [dfloat64])
+    AC_DEFINE_UNQUOTED(DFLOAT32, $DODS_FLOAT32, [dfloat32])
+    AC_DEFINE_UNQUOTED(DBYTE, $DODS_BYTE, [dbyte])
+
+    # XDR INTEGER TYPES
+    # Unfortunately, there is little commonality about xdr
+
+    # First, we need to see if the xdr routines are in libc, librpc,
+    # or librpcsvc or libnsl
+    dap_xdrlib=
+    AC_SEARCH_LIBS([xdr_void],[c rpc nsl rpcsvc],[
+      dap_xdrlib=`echo $ac_res|sed -e 's/^-l//'`],[
+      AC_MSG_WARN(Cannot locate library containing xdr functions.)])
+    # Added for autoconf 2.59 which appears to not use/set $ac_res. jhrg
+    if test -z "$dap_xdrlib" ; then dap_xdrlib=c; fi
+    if test "$dap_xdrlib" = "none required" ; then dap_xdrlib=c; fi
+    # I don't think this is needed for autoconf 2.61 but I have no idea about
+    # 2.59 - it doesn't seem to be hurting anything with 2.61. jhrg
+    if test "$dap_xdrlib" != "c" ; then
+       # Add to library list
+       AC_CHECK_LIB($dap_xdrlib,xdr_void)
+    fi
+    # Now figure out what integer functions to use
+    dap_xdrint=0
+    AC_CHECK_LIB($dap_xdrlib,[xdr_uint32_t],[dap_xdrint=1],[
+      AC_CHECK_LIB($dap_xdrlib,[xdr_u_int32_t],[dap_xdrint=2],[
+        AC_CHECK_LIB($dap_xdrlib,[xdr_uint],[dap_xdrint=3],[
+          AC_CHECK_LIB($dap_xdrlib,[xdr_u_int],[dap_xdrint=4],[])])])])
+    case "$dap_xdrint" in
+    1) # uint32_t
+	XDR_INT32=xdr_int32_t
+	XDR_UINT32=xdr_uint32_t
+        XDR_INT16=xdr_int16_t
+        XDR_UINT16=xdr_uint16_t
+        ;;
+    2) # u_int32_t
+	XDR_INT32=xdr_int32_t
+	XDR_UINT32=xdr_u_int32_t
+        XDR_INT16=xdr_int16_t
+        XDR_UINT16=xdr_u_int16_t
+        ;;
+    3) # uint
+	XDR_INT32=xdr_int
+	XDR_UINT32=xdr_uint
+        XDR_INT16=xdr_short
+        XDR_UINT16=xdr_ushort
+        ;;
+    4) # u_int
+	XDR_INT32=xdr_int
+	XDR_UINT32=xdr_u_int
+        XDR_INT16=xdr_short
+        XDR_UINT16=xdr_u_short
+        ;;
+    *)
+	AC_MSG_ERROR(Cannot determine DODS XDR integer sizes)
+        ;;
+    esac
+    XDR_FLOAT64=xdr_double
+    XDR_FLOAT32=xdr_float
+
+    AC_DEFINE_UNQUOTED([XDR_INT16], [$XDR_INT16], [xdr int16])
+    AC_DEFINE_UNQUOTED([XDR_UINT16], [$XDR_UINT16], [xdr uint16])
+    AC_DEFINE_UNQUOTED([XDR_INT32], [$XDR_INT32], [xdr int32])
+    AC_DEFINE_UNQUOTED([XDR_UINT32], [$XDR_UINT32], [xdr uint32])
+    AC_DEFINE_UNQUOTED([XDR_FLOAT64], [$XDR_FLOAT64], [xdr float64])
+    AC_DEFINE_UNQUOTED([XDR_FLOAT32], [$XDR_FLOAT32], [xdr float32])])
diff --git a/conf/arg-nonnull.h b/conf/arg-nonnull.h
new file mode 100644
index 0000000..226d1a8
--- /dev/null
+++ b/conf/arg-nonnull.h
@@ -0,0 +1,26 @@
+/* A C macro for declaring that specific arguments must not be NULL.
+   Copyright (C) 2009-2011 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 3 of the License, 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
+   that the values passed as arguments n, ..., m must be non-NULL pointers.
+   n = 1 stands for the first argument, n = 2 for the second argument etc.  */
+#ifndef _GL_ARG_NONNULL
+# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
+#  define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
+# else
+#  define _GL_ARG_NONNULL(params)
+# endif
+#endif
diff --git a/conf/c++defs.h b/conf/c++defs.h
new file mode 100644
index 0000000..d521417
--- /dev/null
+++ b/conf/c++defs.h
@@ -0,0 +1,271 @@
+/* C++ compatible function declaration macros.
+   Copyright (C) 2010-2011 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 3 of the License, 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_CXXDEFS_H
+#define _GL_CXXDEFS_H
+
+/* The three most frequent use cases of these macros are:
+
+   * For providing a substitute for a function that is missing on some
+     platforms, but is declared and works fine on the platforms on which
+     it exists:
+
+       #if @GNULIB_FOO@
+       # if !@HAVE_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       # endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on all platforms,
+     but is broken/insufficient and needs to be replaced on some platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+
+   * For providing a replacement for a function that exists on some platforms
+     but is broken/insufficient and needs to be replaced on some of them and
+     is additionally either missing or undeclared on some other platforms:
+
+       #if @GNULIB_FOO@
+       # if @REPLACE_FOO@
+       #  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+       #   undef foo
+       #   define foo rpl_foo
+       #  endif
+       _GL_FUNCDECL_RPL (foo, ...);
+       _GL_CXXALIAS_RPL (foo, ...);
+       # else
+       #  if !@HAVE_FOO@   or   if !@HAVE_DECL_FOO@
+       _GL_FUNCDECL_SYS (foo, ...);
+       #  endif
+       _GL_CXXALIAS_SYS (foo, ...);
+       # endif
+       _GL_CXXALIASWARN (foo);
+       #elif defined GNULIB_POSIXCHECK
+       ...
+       #endif
+*/
+
+/* _GL_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#if defined __cplusplus
+# define _GL_EXTERN_C extern "C"
+#else
+# define _GL_EXTERN_C extern
+#endif
+
+/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
+   declares a replacement function, named rpl_func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
+  _GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
+#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype rpl_func parameters_and_attributes
+
+/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
+   declares the system function, named func, with the given prototype,
+   consisting of return type, parameters, and attributes.
+   Example:
+     _GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
+                                  _GL_ARG_NONNULL ((1)));
+ */
+#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
+  _GL_EXTERN_C rettype func parameters_and_attributes
+
+/* _GL_CXXALIAS_RPL (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
+   Example:
+     _GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
+ */
+#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
+  _GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                \
+    {                                                         \
+      rettype (*const func) parameters = ::rpl_func;          \
+    }                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
+   is like  _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
+   except that the C function rpl_func may have a slightly different
+   declaration.  A cast is used to silence the "invalid conversion" error
+   that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                                     \
+    {                                                              \
+      rettype (*const func) parameters =                           \
+        reinterpret_cast<rettype(*)parameters>(::rpl_func);        \
+    }                                                              \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS (func, rettype, parameters);
+   declares a C++ alias called GNULIB_NAMESPACE::func
+   that redirects to the system provided function func, if GNULIB_NAMESPACE
+   is defined.
+   Example:
+     _GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
+ */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+  /* If we were to write
+       rettype (*const func) parameters = ::func;
+     like above in _GL_CXXALIAS_RPL_1, the compiler could optimize calls
+     better (remove an indirection through a 'static' pointer variable),
+     but then the _GL_CXXALIASWARN macro below would cause a warning not only
+     for uses of ::func but also for uses of GNULIB_NAMESPACE::func.  */
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                     \
+    {                                              \
+      static rettype (*func) parameters = ::func;  \
+    }                                              \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function func may have a slightly different declaration.
+   A cast is used to silence the "invalid conversion" error that would
+   otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    namespace GNULIB_NAMESPACE                          \
+    {                                                   \
+      static rettype (*func) parameters =               \
+        reinterpret_cast<rettype(*)parameters>(::func); \
+    }                                                   \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
+   is like  _GL_CXXALIAS_SYS (func, rettype, parameters);
+   except that the C function is picked among a set of overloaded functions,
+   namely the one with rettype2 and parameters2.  Two consecutive casts
+   are used to silence the "cannot find a match" and "invalid conversion"
+   errors that would otherwise occur.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+  /* The outer cast must be a reinterpret_cast.
+     The inner cast: When the function is defined as a set of overloaded
+     functions, it works as a static_cast<>, choosing the designated variant.
+     When the function is defined as a single variant, it works as a
+     reinterpret_cast<>. The parenthesized cast syntax works both ways.  */
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    namespace GNULIB_NAMESPACE                                                \
+    {                                                                         \
+      static rettype (*func) parameters =                                     \
+        reinterpret_cast<rettype(*)parameters>(                               \
+          (rettype2(*)parameters2)(::func));                                  \
+    }                                                                         \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#else
+# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN (func);
+   causes a warning to be emitted when ::func is used but not when
+   GNULIB_NAMESPACE::func is used.  func must be defined without overloaded
+   variants.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN(func) \
+   _GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN_1(func,namespace) \
+   _GL_CXXALIASWARN_2 (func, namespace)
+/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !__OPTIMIZE__
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+    _GL_WARN_ON_USE (func, \
+                     "The symbol ::" #func " refers to the system function. " \
+                     "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     extern __typeof__ (func) func
+# else
+#  define _GL_CXXALIASWARN_2(func,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN(func) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
+   causes a warning to be emitted when the given overloaded variant of ::func
+   is used but not when GNULIB_NAMESPACE::func is used.  */
+#if defined __cplusplus && defined GNULIB_NAMESPACE
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+   _GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
+                        GNULIB_NAMESPACE)
+# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
+   _GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
+/* To work around GCC bug <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
+   we enable the warning only when not optimizing.  */
+# if !__OPTIMIZE__
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+    _GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
+                         "The symbol ::" #func " refers to the system function. " \
+                         "Use " #namespace "::" #func " instead.")
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+     extern __typeof__ (func) func
+# else
+#  define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
+     _GL_EXTERN_C int _gl_cxxalias_dummy
+# endif
+#else
+# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
+    _GL_EXTERN_C int _gl_cxxalias_dummy
+#endif
+
+#endif /* _GL_CXXDEFS_H */
diff --git a/conf/check_zlib.m4 b/conf/check_zlib.m4
new file mode 100644
index 0000000..9beac0f
--- /dev/null
+++ b/conf/check_zlib.m4
@@ -0,0 +1,122 @@
+##### http://autoconf-archive.cryp.to/check_zlib.html
+#
+# SYNOPSIS
+#
+#   CHECK_ZLIB()
+#
+# DESCRIPTION
+#
+#   This macro searches for an installed zlib library. If nothing was
+#   specified when calling configure, it searches first in /usr/local
+#   and then in /usr. If the --with-zlib=DIR is specified, it will try
+#   to find it in DIR/include/zlib.h and DIR/lib/libz.a. If
+#   --without-zlib is specified, the library is not searched at all.
+#
+#   If either the header file (zlib.h) or the library (libz) is not
+#   found, the configuration exits on error, asking for a valid zlib
+#   installation directory or --without-zlib.
+#
+#   The macro defines the symbol HAVE_LIBZ if the library is found. You
+#   should use autoheader to include a definition for this symbol in a
+#   config.h file. Sample usage in a C/C++ source is as follows:
+#
+#     #ifdef HAVE_LIBZ
+#     #include <zlib.h>
+#     #endif /* HAVE_LIBZ */
+#
+# LAST MODIFICATION
+#
+#   2004-09-20
+#
+# COPYLEFT
+#
+#   Copyright (c) 2004 Loic Dachary <loic at senga.org>
+#
+#   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 of the
+#   License, 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., 59 Temple Place - Suite 330, Boston, MA
+#   02111-1307, USA.
+#
+#   As a special exception, the respective Autoconf Macro's copyright
+#   owner gives unlimited permission to copy, distribute and modify the
+#   configure scripts that are the output of Autoconf when processing
+#   the Macro. You need not follow the terms of the GNU General Public
+#   License when using or distributing such scripts, even though
+#   portions of the text of the Macro appear in them. The GNU General
+#   Public License (GPL) does govern all other use of the material that
+#   constitutes the Autoconf Macro.
+#
+#   This special exception to the GPL applies to versions of the
+#   Autoconf Macro released by the Autoconf Macro Archive. When you
+#   make and distribute a modified version of the Autoconf Macro, you
+#   may extend this special exception to the GPL to apply to your
+#   modified version as well.
+
+AC_DEFUN([DAP_CHECK_ZLIB],
+#
+# Handle user hints
+#
+[
+AC_ARG_WITH(zlib,
+[  --with-zlib=DIR root directory path of zlib installation [defaults to
+                    /usr/local or /usr if not found in /usr/local]
+  --without-zlib to disable zlib usage completely],
+[if test "$withval" != no ; then
+  if test -d "$withval"
+  then
+    ZLIB_HOME="$withval"
+  else
+    AC_MSG_WARN([Sorry, $withval does not exist, checking usual places])
+  fi
+else
+  AC_MSG_WARN([zlib is required for deflate, not disabled])
+fi])
+
+ZLIB_OLD_LDFLAGS=$LDFLAGS
+ZLIB_OLD_CPPFLAGS=$CPPFLAGS
+
+#
+# Locate zlib, if wanted
+#
+if test -n "${ZLIB_HOME}"
+then
+        LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
+        CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
+fi
+AC_LANG_SAVE
+AC_LANG_C
+AC_CHECK_LIB(z, inflateEnd, [zlib_cv_libz=yes], [zlib_cv_libz=no])
+AC_CHECK_HEADER(zlib.h, [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no])
+AC_LANG_RESTORE
+
+if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes"
+then
+        #
+        # If both library and header were found, use them
+        #
+        ZLIB_LIBS="-lz"
+else
+        #
+        # If either header or library was not found, revert and bomb
+        #
+        AC_MSG_ERROR([zlib is required for deflate, specify a valid zlib installation with --with-zlib=DIR])
+fi
+
+LDFLAGS="$ZLIB_OLD_LDFLAGS"
+CPPFLAGS="$ZLIB_OLD_CPPFLAGS"
+
+AC_SUBST([ZLIB_LIBS])
+AC_SUBST([ZLIB_LDFLAGS])
+AC_SUBST([ZLIB_CFLAGS])
+
+])
diff --git a/conf/config.guess b/conf/config.guess
new file mode 100755
index 0000000..da83314
--- /dev/null
+++ b/conf/config.guess
@@ -0,0 +1,1561 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
+
+timestamp='2009-04-27'
+
+# This file 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 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 to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per at bothner.com>.
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi at noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee at wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    s390x:SunOS:*:*)
+	echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+	eval $set_cc_for_build
+	SUN_ARCH="i386"
+	# If there is a compiler, see if it is configured for 64-bit objects.
+	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+	# This test works for both compilers.
+	if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+		(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_64BIT_ARCH >/dev/null
+	    then
+		SUN_ARCH="x86_64"
+	    fi
+	fi
+	echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[456])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    *:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    *:Interix*:[3456]*)
+    	case ${UNAME_MACHINE} in
+	    x86)
+		echo i586-pc-interix${UNAME_RELEASE}
+		exit ;;
+	    EM64T | authenticamd | genuineintel)
+		echo x86_64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	    IA64)
+		echo ia64-unknown-interix${UNAME_RELEASE}
+		exit ;;
+	esac ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	eval $set_cc_for_build
+	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_EABI__
+	then
+	    echo ${UNAME_MACHINE}-unknown-linux-gnu
+	else
+	    echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+	fi
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    padre:Linux:*:*)
+	echo sparc-unknown-linux-gnu
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    xtensa*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i586.
+	# Note: whatever this is, it MUST be the same as what config.sub
+	# prints for the "djgpp" host, or else GDB configury will decide that
+	# this is a cross-build.
+	echo i586-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+	OS_REL='.3'
+	test -r /etc/.relid \
+	    && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	    && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+	    && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel at ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes at openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf at swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green at stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
+	echo i586-pc-haiku
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-7:SUPER-UX:*:*)
+	echo sx7-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8R:SUPER-UX:*:*)
+	echo sx8r-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+    i*86:AROS:*:*)
+	echo ${UNAME_MACHINE}-pc-aros
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+  http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches at gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+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`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/conf/config.sub b/conf/config.sub
new file mode 100755
index 0000000..a39437d
--- /dev/null
+++ b/conf/config.sub
@@ -0,0 +1,1686 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+#   Free Software Foundation, Inc.
+
+timestamp='2009-04-17'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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 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 to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches at gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches at gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  kopensolaris*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fido | fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| lm32 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore | mep | metag \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64octeon | mips64octeonel \
+	| mips64orion | mips64orionel \
+	| mips64r5900 | mips64r5900el \
+	| mips64vr | mips64vrel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| moxie \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k | z80)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| lm32-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64octeon-* | mips64octeonel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64r5900-* | mips64r5900el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa*-* \
+	| ymp-* \
+	| z8k-* | z80-*)
+		;;
+	# Recognize the basic CPU types without company name, with glob match.
+	xtensa*)
+		basic_machine=$basic_machine-unknown
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aros)
+		basic_machine=i386-pc
+		os=-aros
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	blackfin)
+		basic_machine=bfin-unknown
+		os=-linux
+		;;
+	blackfin-*)
+		basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+        cegcc)
+		basic_machine=arm-unknown
+		os=-cegcc
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16)
+		basic_machine=cr16-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dicos)
+		basic_machine=i686-pc
+		os=-dicos
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m68knommu)
+		basic_machine=m68k-unknown
+		os=-linux
+		;;
+	m68knommu-*)
+		basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	mingw32ce)
+		basic_machine=arm-unknown
+		os=-mingw32ce
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	parisc)
+		basic_machine=hppa-unknown
+		os=-linux
+		;;
+	parisc-*)
+		basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+		os=-linux
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tile*)
+		basic_machine=tile-unknown
+		os=-linux-gnu
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	z80-*-coff)
+		basic_machine=z80-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -kopensolaris* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* | -aros* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* | -cegcc* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-dicos*)
+		os=-dicos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+        mep-*)
+		os=-elf
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/conf/cppunit.m4 b/conf/cppunit.m4
new file mode 100644
index 0000000..41f067b
--- /dev/null
+++ b/conf/cppunit.m4
@@ -0,0 +1,92 @@
+dnl
+dnl AM_PATH_CPPUNIT(MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
+dnl
+AC_DEFUN([AM_PATH_CPPUNIT],
+[
+
+AC_ARG_WITH(cppunit-prefix,[  --with-cppunit-prefix=PFX   Prefix where CppUnit is installed (optional)],
+            cppunit_config_prefix="$withval", cppunit_config_prefix="")
+AC_ARG_WITH(cppunit-exec-prefix,[  --with-cppunit-exec-prefix=PFX  Exec prefix where CppUnit is installed (optional)],
+            cppunit_config_exec_prefix="$withval", cppunit_config_exec_prefix="")
+
+  if test x$cppunit_config_exec_prefix != x ; then
+     cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix"
+     if test x${CPPUNIT_CONFIG+set} != xset ; then
+        CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config
+     fi
+  fi
+  if test x$cppunit_config_prefix != x ; then
+     cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix"
+     if test x${CPPUNIT_CONFIG+set} != xset ; then
+        CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config
+     fi
+  fi
+
+  AC_PATH_PROG(CPPUNIT_CONFIG, cppunit-config, no)
+  cppunit_version_min=$1
+
+  AC_MSG_CHECKING(for Cppunit - version >= $cppunit_version_min)
+  no_cppunit=""
+  if test "$CPPUNIT_CONFIG" = "no" ; then
+    AC_MSG_RESULT(no)
+    no_cppunit=yes
+  else
+    CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags`
+    CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs`
+    cppunit_version=`$CPPUNIT_CONFIG --version`
+
+    cppunit_major_version=`echo $cppunit_version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    cppunit_minor_version=`echo $cppunit_version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    cppunit_micro_version=`echo $cppunit_version | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+
+    cppunit_major_min=`echo $cppunit_version_min | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
+    if test "x${cppunit_major_min}" = "x" ; then
+       cppunit_major_min=0
+    fi
+    
+    cppunit_minor_min=`echo $cppunit_version_min | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
+    if test "x${cppunit_minor_min}" = "x" ; then
+       cppunit_minor_min=0
+    fi
+    
+    cppunit_micro_min=`echo $cppunit_version_min | \
+           sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
+    if test "x${cppunit_micro_min}" = "x" ; then
+       cppunit_micro_min=0
+    fi
+
+    cppunit_version_proper=`expr \
+        $cppunit_major_version \> $cppunit_major_min \| \
+        $cppunit_major_version \= $cppunit_major_min \& \
+        $cppunit_minor_version \> $cppunit_minor_min \| \
+        $cppunit_major_version \= $cppunit_major_min \& \
+        $cppunit_minor_version \= $cppunit_minor_min \& \
+        $cppunit_micro_version \>= $cppunit_micro_min `
+
+    if test "$cppunit_version_proper" = "1" ; then
+      AC_MSG_RESULT([$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version])
+    else
+      AC_MSG_RESULT(no)
+      no_cppunit=yes
+    fi
+  fi
+
+  if test "x$no_cppunit" = x ; then
+     ifelse([$2], , :, [$2])     
+  else
+     CPPUNIT_CFLAGS=""
+     CPPUNIT_LIBS=""
+     ifelse([$3], , :, [$3])
+  fi
+
+  AC_SUBST(CPPUNIT_CFLAGS)
+  AC_SUBST(CPPUNIT_LIBS)
+])
+
+
+
diff --git a/conf/depcomp b/conf/depcomp
new file mode 100755
index 0000000..df8eea7
--- /dev/null
+++ b/conf/depcomp
@@ -0,0 +1,630 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva at dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake at gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+cygpath_u="cygpath -u -f -"
+if test "$depmode" = msvcmsys; then
+   # This is just like msvisualcpp but w/o cygpath translation.
+   # Just convert the backslash-escaped backslashes to single forward
+   # slashes to satisfy depend.m4
+   cygpath_u="sed s,\\\\\\\\,/,g"
+   depmode=msvisualcpp
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+## Unfortunately, FreeBSD c89 acceptance of flags depends upon
+## the command line argument order; so add the flags where they
+## appear in depend2.am.  Note that the slowdown incurred here
+## affects only configure: in makefiles, %FASTDEP% shortcuts this.
+  for arg
+  do
+    case $arg in
+    -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
+    *)  set fnord "$@" "$arg" ;;
+    esac
+    shift # fnord
+    shift # $arg
+  done
+  "$@"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> "$depfile"
+    echo >> "$depfile"
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$base.u
+    tmpdepfile3=$dir.libs/$base.u
+    "$@" -Wc,-M
+  else
+    tmpdepfile1=$dir$base.u
+    tmpdepfile2=$dir$base.u
+    tmpdepfile3=$dir$base.u
+    "$@" -M
+  fi
+  stat=$?
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+    exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+    # That's a tab and a space in the [].
+    sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp2)
+  # The "hp" stanza above does not work with aCC (C++) and HP's ia64
+  # compilers, which have integrated preprocessors.  The correct option
+  # to use with these is +Maked; it writes dependencies to a file named
+  # 'foo.d', which lands next to the object file, wherever that
+  # happens to be.
+  # Much of this is similar to the tru64 case; see comments there.
+  dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+  test "x$dir" = "x$object" && dir=
+  base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+  if test "$libtool" = yes; then
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir.libs/$base.d
+    "$@" -Wc,+Maked
+  else
+    tmpdepfile1=$dir$base.d
+    tmpdepfile2=$dir$base.d
+    "$@" +Maked
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+     rm -f "$tmpdepfile1" "$tmpdepfile2"
+     exit $stat
+  fi
+
+  for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
+  do
+    test -f "$tmpdepfile" && break
+  done
+  if test -f "$tmpdepfile"; then
+    sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
+    # Add `dependent.h:' lines.
+    sed -ne '2,${
+	       s/^ *//
+	       s/ \\*$//
+	       s/$/:/
+	       p
+	     }' "$tmpdepfile" >> "$depfile"
+  else
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile" "$tmpdepfile2"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mechanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no eat=no
+  for arg
+  do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    if test $eat = yes; then
+      eat=no
+      continue
+    fi
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -arch)
+      eat=yes ;;
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix=`echo "$object" | sed 's/^.*\././'`
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
+       -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test "X$1" != 'X--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E 2>/dev/null |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvcmsys)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/conf/install-sh b/conf/install-sh
new file mode 100755
index 0000000..6781b98
--- /dev/null
+++ b/conf/install-sh
@@ -0,0 +1,520 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2009-04-28.21; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+
+nl='
+'
+IFS=" ""	$nl"
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit=${DOITPROG-}
+if test -z "$doit"; then
+  doit_exec=exec
+else
+  doit_exec=$doit
+fi
+
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.
+
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+no_target_directory=
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+	shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+	case $mode in
+	  *' '* | *'	'* | *'
+'*	  | *'*'* | *'?'* | *'['*)
+	    echo "$0: invalid mode: $mode" >&2
+	    exit 1;;
+	esac
+	shift;;
+
+    -o) chowncmd="$chownprog $2"
+	shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t) dst_arg=$2
+	shift;;
+
+    -T) no_target_directory=true;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --)	shift
+	break;;
+
+    -*)	echo "$0: invalid option: $1" >&2
+	exit 1;;
+
+    *)  break;;
+  esac
+  shift
+done
+
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+  done
+fi
+
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  trap '(exit $?); exit' 1 2 13 15
+
+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;
+
+    *[0-7])
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+	u_plus_rw=
+      else
+	u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dst_arg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dst_arg: Is a directory" >&2
+	exit 1
+      fi
+      dstdir=$dst
+      dst=$dstdir/`basename "$src"`
+      dstdir_status=0
+    else
+      # Prefer dirname, but fall back on a substitute if dirname fails.
+      dstdir=`
+	(dirname "$dst") 2>/dev/null ||
+	expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	     X"$dst" : 'X\(//\)[^/]' \| \
+	     X"$dst" : 'X\(//\)$' \| \
+	     X"$dst" : 'X\(/\)' \| . 2>/dev/null ||
+	echo X"$dst" |
+	    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)[^/].*/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\/\)$/{
+		   s//\1/
+		   q
+		 }
+		 /^X\(\/\).*/{
+		   s//\1/
+		   q
+		 }
+		 s/.*/./; q'
+      `
+
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+	# Create intermediate dirs using mode 755 as modified by the umask.
+	# This is like FreeBSD 'install' as of 1997-10-28.
+	umask=`umask`
+	case $stripcmd.$umask in
+	  # Optimize common cases.
+	  *[2367][2367]) mkdir_umask=$umask;;
+	  .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+	  *[0-7])
+	    mkdir_umask=`expr $umask + 22 \
+	      - $umask % 100 % 40 + $umask % 20 \
+	      - $umask % 10 % 4 + $umask % 2
+	    `;;
+	  *) mkdir_umask=$umask,go-w;;
+	esac
+
+	# With -d, create the new directory with the user-specified mode.
+	# Otherwise, rely on $mkdir_umask.
+	if test -n "$dir_arg"; then
+	  mkdir_mode=-m$mode
+	else
+	  mkdir_mode=
+	fi
+
+	posix_mkdir=false
+	case $umask in
+	  *[123567][0-7][0-7])
+	    # POSIX mkdir -p sets u+wx bits regardless of umask, which
+	    # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+	    ;;
+	  *)
+	    tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	    trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+	    if (umask $mkdir_umask &&
+		exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1
+	    then
+	      if test -z "$dir_arg" || {
+		   # Check for POSIX incompatibilities with -m.
+		   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+		   # other-writeable bit of parent directory when it shouldn't.
+		   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+		   ls_ld_tmpdir=`ls -ld "$tmpdir"`
+		   case $ls_ld_tmpdir in
+		     d????-?r-*) different_mode=700;;
+		     d????-?--*) different_mode=755;;
+		     *) false;;
+		   esac &&
+		   $mkdirprog -m$different_mode -p -- "$tmpdir" && {
+		     ls_ld_tmpdir_1=`ls -ld "$tmpdir"`
+		     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+		   }
+		 }
+	      then posix_mkdir=:
+	      fi
+	      rmdir "$tmpdir/d" "$tmpdir"
+	    else
+	      # Remove any dirs left behind by ancient mkdir implementations.
+	      rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null
+	    fi
+	    trap '' 0;;
+	esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+	umask $mkdir_umask &&
+	$doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+	/*) prefix='/';;
+	-*) prefix='./';;
+	*)  prefix='';;
+      esac
+
+      eval "$initialize_posix_glob"
+
+      oIFS=$IFS
+      IFS=/
+      $posix_glob set -f
+      set fnord $dstdir
+      shift
+      $posix_glob set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+	test -z "$d" && continue
+
+	prefix=$prefix$d
+	if test -d "$prefix"; then
+	  prefixes=
+	else
+	  if $posix_mkdir; then
+	    (umask=$mkdir_umask &&
+	     $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+	    # Don't fail if two instances are running concurrently.
+	    test -d "$prefix" || exit 1
+	  else
+	    case $prefix in
+	      *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+	      *) qprefix=$prefix;;
+	    esac
+	    prefixes="$prefixes '$qprefix'"
+	  fi
+	fi
+	prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+	# Don't fail if two instances are running concurrently.
+	(umask $mkdir_umask &&
+	 eval "\$doit_exec \$mkdirprog $prefixes") ||
+	  test -d "$dstdir" || exit 1
+	obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"	2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"	2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+	# Now remove or move aside any old file at destination location.
+	# We try this two ways since rm can't unlink itself on some
+	# systems and the destination file might be busy for other
+	# reasons.  In this case, the final cleanup might fail but the new
+	# file should still install successfully.
+	{
+	  test ! -f "$dst" ||
+	  $doit $rmcmd -f "$dst" 2>/dev/null ||
+	  { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+	    { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+	  } ||
+	  { echo "$0: cannot unlink or rename $dst" >&2
+	    (exit 1); exit 1
+	  }
+	} &&
+
+	# Now rename the file to the real destination.
+	$doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
+done
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/conf/libdap.m4 b/conf/libdap.m4
new file mode 100644
index 0000000..54d1aed
--- /dev/null
+++ b/conf/libdap.m4
@@ -0,0 +1,314 @@
+# -*- mode: autoconf -*-
+# Configure macros for Libdap
+#
+# Code for version detection and comparison comes from freetype2.m4
+# Marcelo Magallon 2001-10-26, based on gtk.m4 by Owen Taylor
+#
+# Copyright 2001, 2003 by
+# David Turner, Robert Wilhelm, and Werner Lemberg.
+#
+# This file is part of the FreeType project, and may only be used, modified,
+# and distributed under the terms of the FreeType project license,
+# LICENSE.TXT.  By continuing to use, modify, or distribute this file you
+# indicate that you have read the license and understand and accept it
+# fully.
+#
+# As a special exception to the FreeType project license, this file may be
+# distributed as part of a program that contains a configuration script
+# generated by Autoconf, under the same distribution terms as the rest of
+# that program.
+#
+# modified by Patrice Dumas 2005 for libdap
+#
+# AC_CHECK_DODS is based on code from gdal configure.in
+
+# AC_CHECK_LIBDAP([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libdap and define DAP_CFLAGS and DAP_LIBS.
+# Check that the version is above MINIMUM-VERSION 
+# use when linking with a c++ aware linker, with a c linker you may also
+# need -lstdc++
+
+AC_DEFUN([AC_CHECK_LIBDAP],
+[
+  dap_min_version=m4_if([$1], [], [3.5.0], [$1])
+  dap_no=
+  dap_pkgconfig_libdap=yes 
+  PKG_CHECK_MODULES([DAP],[libdap >= $dap_min_version],,
+    [dap_pkgconfig_libdap=no])
+  PKG_CHECK_MODULES([DAP_CLIENT],[libdapclient >= $dap_min_version],,
+    [dap_pkgconfig_libdap=no])
+  PKG_CHECK_MODULES([DAP_SERVER],[libdapserver >= $dap_min_version],,
+    [dap_pkgconfig_libdap=no])
+  
+  if test $dap_pkgconfig_libdap = no; then
+    AC_PATH_PROG([DAP_CONFIG], [dap-config], [no])
+    if test "$DAP_CONFIG" = "no" ; then
+      dap_no=yes
+    else
+      dap_config_major_version=`$DAP_CONFIG --version | sed 's/^libdap \([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)[[ab]]*$/\1/'`
+      dap_config_minor_version=`$DAP_CONFIG --version | sed 's/^libdap \([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)[[ab]]*$/\2/'`
+      dap_config_micro_version=`$DAP_CONFIG --version | sed 's/^libdap \([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)\.\([[0-9]][[0-9]]*\)[[ab]]*$/\3/'`
+      dap_min_major_version=`echo $dap_min_version | sed 's/\([[0-9]][[0-9]]*\).\([[0-9]][[0-9]]*\).\([[0-9]][[0-9]]*\)$/\1/'`
+      dap_min_minor_version=`echo $dap_min_version | sed 's/\([[0-9]][[0-9]]*\).\([[0-9]][[0-9]]*\).\([[0-9]][[0-9]]*\)$/\2/'`
+      dap_min_micro_version=`echo $dap_min_version | sed 's/\([[0-9]][[0-9]]*\).\([[0-9]][[0-9]]*\).\([[0-9]][[0-9]]*\)$/\3/'`
+
+      dap_config_is_lt=""
+      if test $dap_config_major_version -lt $dap_min_major_version ; then
+        dap_config_is_lt=yes
+      else
+        if test $dap_config_major_version -eq $dap_min_major_version ; then
+          if test $dap_config_minor_version -lt $dap_min_minor_version ; then
+            dap_config_is_lt=yes
+          else
+            if test $dap_config_minor_version -eq $dap_min_minor_version ; then
+              if test $dap_config_micro_version -lt $dap_min_micro_version ; then
+                dap_config_is_lt=yes
+              fi
+            fi
+          fi
+        fi
+      fi
+      if test x$dap_config_is_lt = xyes ; then
+        dap_no=yes
+      else
+        DAP_LIBS="`$DAP_CONFIG --libs`"
+        if ($DAP_CONFIG --client-libs 2>&1 | grep unknown) >/dev/null 2>&1; then
+          DAP_CLIENT_LIBS=$DAP_LIBS
+          DAP_SERVER_LIBS=$DAP_LIBS
+        else
+          DAP_CLIENT_LIBS="`$DAP_CONFIG --client-libs`"
+          DAP_SERVER_LIBS="`$DAP_CONFIG --server-libs`"
+        fi
+        DAP_CFLAGS="`$DAP_CONFIG --cflags`"
+      fi
+    fi
+  else
+     DAP_STATIC_LIBS="`$PKG_CONFIG --static --libs libdap`"
+     DAP_CLIENT_STATIC_LIBS="`$PKG_CONFIG --static --libs libdapclient`"
+     DAP_SERVER_STATIC_LIBS="`$PKG_CONFIG --static --libs libdapserver`"
+  fi
+  AC_MSG_CHECKING([for libdap version >= $dap_min_version])
+  if test x$dap_no = x ; then
+    AC_MSG_RESULT([yes])
+    m4_if([$2], [], [:], [$2])
+  else
+    AC_MSG_RESULT([no])
+    if test "$DAP_CONFIG" = "no" ; then
+    AC_MSG_NOTICE([The dap-config script could not be found.])
+    else
+      if test x$dap_config_is_lt = xyes ; then
+        AC_MSG_NOTICE([the installed libdap library is too old.])
+      fi
+    fi
+    DAP_LIBS=""
+    DAP_CFLAGS=""
+    m4_if([$3], [], [:], [$3])
+  fi
+  if test x"$DAP_CFLAGS" != x -a x"$DAP_CLIENT_CFLAGS" = x ; then
+    DAP_CLIENT_CFLAGS=$DAP_CFLAGS
+  fi
+  if test x"$DAP_CFLAGS" != x -a x"$DAP_SERVER_CFLAGS" = x ; then
+    DAP_SERVER_CFLAGS=$DAP_CFLAGS
+  fi
+  if test x"$DAP_STATIC_LIBS" = x ; then
+    DAP_STATIC_LIBS=$DAP_LIBS
+    DAP_CLIENT_STATIC_LIBS=$DAP_CLIENT_LIBS
+    DAP_SERVER_STATIC_LIBS=$DAP_SERVER_LIBS
+  fi
+  AC_SUBST([DAP_CFLAGS])
+  AC_SUBST([DAP_CLIENT_CFLAGS])
+  AC_SUBST([DAP_SERVER_CFLAGS])
+  AC_SUBST([DAP_LIBS])
+  AC_SUBST([DAP_CLIENT_LIBS])
+  AC_SUBST([DAP_SERVER_LIBS])
+  AC_SUBST([DAP_STATIC_LIBS])
+  AC_SUBST([DAP_CLIENT_STATIC_LIBS])
+  AC_SUBST([DAP_SERVER_STATIC_LIBS])
+]) 
+
+# AC_CHECK_DODS([ ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
+# Test for Libdap or older versions. Define DAP_CFLAGS and DAP_LIBS and
+# optionnaly DAP_ROOT
+
+AC_DEFUN([AC_CHECK_DODS],
+[
+  AC_ARG_WITH([dods_root],
+    [AS_HELP_STRING([--with-dods-root=ARG],[DODS root fallback])],
+    ,,)
+
+  ac_dods_ok='no'
+  DAP_ROOT=
+  AC_MSG_CHECKING([DODS specific root])
+  if test -z "$with_dods_root" -o "$with_dods_root" = "no"; then
+    AC_MSG_RESULT([disabled])
+  else
+    AC_MSG_RESULT([$with_dods_root])
+    DODS_ROOT=$with_dods_root
+    DODS_LIB=$with_dods_root/lib
+    DODS_INC=$with_dods_root/include
+    DODS_BIN=$with_dods_root/bin
+
+    dnl Add the DODS libraries to LIBS
+    if test -x "$DODS_BIN/opendap-config" ; then 
+      dnl OPeNDAP 3.4 and earlier lack opendap-config, but use it if avail.
+      DAP_LIBS="`$DODS_BIN/opendap-config --libs`"
+      DAP_CFLAGS="`$DODS_BIN/opendap-config --cflags`"
+      ac_dods_ok='yes'
+    elif test -x "$DODS_BIN/dap-config" ; then
+      dnl for OPeNDAP 3.5
+      DAP_LIBS="`$DODS_BIN/dap-config --libs`"
+      DAP_CFLAGS="`$DODS_BIN/dap-config --cflags`"
+      ac_dods_ok='yes'
+    else
+      dnl Otherwise try to put things together in a more primitive way.
+      DAP_LIBS="-L$DODS_LIB -ldap++ -lpthread"
+      DAP_CFLAGS="-I$DODS_INC"
+    
+      ac_dods_curl='yes'
+      dnl Add curl to LIBS; it might be local to DODS or generally installed
+      AC_MSG_CHECKING([For curl])
+      if test -x "$DODS_BIN/curl-config"; then
+         DAP_LIBS="$DAP_LIBS  `$DODS_BIN/curl-config --libs`"
+      elif which curl-config > /dev/null 2>&1; then
+         DAP_LIBS="$DAP_LIBS  `curl-config --libs`"
+      else
+         ac_dods_curl='no'
+      fi
+      if test $ac_dods_curl = 'no' ; then
+         AC_MSG_RESULT([no]) 
+         dnl AC_MSG_WARN([You gave a dods root, but I can't find curl!])
+      else
+         AC_MSG_RESULT([yes])
+      fi 
+         
+      
+      AC_MSG_CHECKING([For libxml2])
+      ac_dods_xml2='yes'
+      if test -x "$DODS_BIN/xml2-config"; then
+         DAP_LIBS="$DAP_LIBS `$DODS_BIN/xml2-config --libs`"
+      elif which xml2-config > /dev/null 2>&1; then
+         DAP_LIBS="$DAP_LIBS  `xml2-config --libs`"
+      else
+         ac_dods_xml2='no'
+      fi
+      if test $ac_dods_xml2 = 'no' ; then
+         AC_MSG_RESULT([no]) 
+         dnl AC_MSG_WARN([You gave a dods root, but I can't find xml2!])
+      else
+         AC_MSG_RESULT([yes])
+      fi 
+         
+      AC_LANG_PUSH([C++])
+      if test $ac_dods_xml2 = 'yes' -a $ac_dods_curl = 'yes'; then
+         dnl We check that linking is succesfull
+         ac_save_LIBS=$LIBS
+         ac_save_CFLAGS=$CFLAGS
+         LIBS="$LIBS $DAP_LIBS"
+         CFLAGS="$CFLAGS $DAP_CFLAGS"
+         dnl AC_CHECK_LIB is not used because it caches results
+         dnl AC_CHECK_LIB([dap++],[main],[ac_dods_ok='yes'],[ac_dods_ok='no'])
+         AC_MSG_CHECKING([for DODS with curl and libxml2])
+         AC_LINK_IFELSE([AC_LANG_CALL([],[main])],[
+           ac_dods_ok='yes'
+           AC_MSG_RESULT([yes])
+         ],[
+           ac_dods_ok='no'
+           AC_MSG_RESULT([no])
+         ])
+         LIBS=$ac_save_LIBS
+         CFLAGS=$ac_save_CFLAGS
+         if test "z$ac_dods_ok" = "zno"; then
+           ac_save_LIBS=$LIBS
+           ac_save_CFLAGS=$CFLAGS
+           LIBS="$LIBS $DAP_LIBS -lrx"
+           CFLAGS="$CFLAGS $DAP_CFLAGS"
+           AC_MSG_CHECKING([for DODS with curl, libxml2 and librx])
+           AC_LINK_IFELSE([AC_LANG_CALL([],[main])],[
+               AC_MSG_RESULT([yes])
+               ac_dods_ok='yes'
+               DAP_LIBS="$DAP_LIBS -lrx"
+           ],[
+               ac_dods_ok='no'
+               AC_MSG_RESULT([no])
+           ])
+           LIBS=$ac_save_LIBS
+           CFLAGS=$ac_save_CFLAGS
+         fi
+      fi
+      if test $ac_dods_ok = 'no'; then
+         dnl assume it is an old version of DODS
+         AC_MSG_NOTICE([Checking for DODS with libwww and librx])
+         DAP_LIBS="-L$DODS_LIB -ldap++ -lwww -lpthread -lrx"
+         DAP_CFLAGS="-I$DODS_INC"
+         ac_save_LIBS=$LIBS
+         ac_save_CFLAGS=$CFLAGS
+         LIBS="$LIBS $DAP_LIBS"
+         CFLAGS="$CFLAGS $DAP_CFLAGS"
+         AC_CHECK_LIB([dap++],[main],[ac_dods_ok='yes'],[ac_dods_ok='no'])
+         LIBS=$ac_save_LIBS
+         CFLAGS=$ac_save_CFLAGS
+      fi
+      AC_LANG_POP
+    fi
+      
+    AC_MSG_CHECKING([for DODS in a specific root])
+    if test "z$ac_dods_ok" = "zyes"; then
+       AC_MSG_RESULT([yes])
+       AC_MSG_NOTICE([setting DAP_ROOT directory to $DODS_ROOT])
+       DAP_ROOT=$DODS_ROOT
+    else
+       AC_MSG_RESULT([no])
+    fi
+  fi
+  if test "z$ac_dods_ok" = "zno" ; then
+     AC_CHECK_LIBDAP([],[ac_dods_ok='yes'],[ac_dods_ok='no'])
+     if test "z$ac_dods_ok" = "zno" ; then
+       AC_PATH_PROG([OPENDAP_CONFIG], [opendap-config], [no])
+       AC_MSG_CHECKING([for libdap with opendap-config])
+       if test "$OPENDAP_CONFIG" = "no" ; then
+         ac_dods_ok='no'
+         AC_MSG_RESULT([no])
+       else
+         DAP_LIBS="`$OPENDAP_CONFIG --libs`"
+         DAP_CFLAGS="`$OPENDAP_CONFIG --cflags`"
+         ac_dods_ok='yes'
+         AC_MSG_RESULT([yes])
+       fi
+     fi
+  fi 
+  if test "x$ac_dods_ok" = "xyes" ; then
+     if test "z$DAP_CLIENT_LIBS" = 'z' ; then
+       DAP_CLIENT_LIBS=$DAP_LIBS
+       DAP_SERVER_LIBS=$DAP_LIBS
+     fi
+     if test x"$DAP_CFLAGS" != x -a x"$DAP_CLIENT_CFLAGS" = x ; then
+        DAP_CLIENT_CFLAGS=$DAP_CFLAGS
+     fi
+     if test x"$DAP_CFLAGS" != x -a x"$DAP_SERVER_CFLAGS" = x ; then
+       DAP_SERVER_CFLAGS=$DAP_CFLAGS
+     fi
+     if test x"$DAP_STATIC_LIBS" = x ; then
+       DAP_STATIC_LIBS=$DAP_LIBS
+       DAP_CLIENT_STATIC_LIBS=$DAP_CLIENT_LIBS
+       DAP_SERVER_STATIC_LIBS=$DAP_SERVER_LIBS
+     fi
+     m4_if([$1], [], [:], [$1])
+  else
+     DAP_LIBS=""
+     DAP_CFLAGS=""
+     DAP_CLIENT_LIBS=""
+     DAP_SERVER_LIBS=""
+     m4_if([$2], [], [:], [$2])
+  fi
+dnl done above
+dnl  AC_SUBST([DAP_CFLAGS])
+dnl  AC_SUBST([DAP_CLIENT_CFLAGS])
+dnl  AC_SUBST([DAP_SERVER_CFLAGS])
+dnl  AC_SUBST([DAP_LIBS])
+dnl  AC_SUBST([DAP_CLIENT_LIBS])
+dnl  AC_SUBST([DAP_SERVER_LIBS])
+dnl  AC_SUBST([DAP_STATIC_LIBS])
+dnl  AC_SUBST([DAP_CLIENT_STATIC_LIBS])
+dnl  AC_SUBST([DAP_SERVER_STATIC_LIBS])
+dnl  AC_SUBST([DAP_ROOT])
+])
diff --git a/conf/libtool.m4 b/conf/libtool.m4
new file mode 100644
index 0000000..39ba996
--- /dev/null
+++ b/conf/libtool.m4
@@ -0,0 +1,7357 @@
+# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+m4_define([_LT_COPYING], [dnl
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+])
+
+# serial 56 LT_INIT
+
+
+# LT_PREREQ(VERSION)
+# ------------------
+# Complain and exit if this libtool version is less that VERSION.
+m4_defun([LT_PREREQ],
+[m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1,
+       [m4_default([$3],
+		   [m4_fatal([Libtool version $1 or higher is required],
+		             63)])],
+       [$2])])
+
+
+# _LT_CHECK_BUILDDIR
+# ------------------
+# Complain if the absolute build directory name contains unusual characters
+m4_defun([_LT_CHECK_BUILDDIR],
+[case `pwd` in
+  *\ * | *\	*)
+    AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;;
+esac
+])
+
+
+# LT_INIT([OPTIONS])
+# ------------------
+AC_DEFUN([LT_INIT],
+[AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_BEFORE([$0], [LT_LANG])dnl
+AC_BEFORE([$0], [LT_OUTPUT])dnl
+AC_BEFORE([$0], [LTDL_INIT])dnl
+m4_require([_LT_CHECK_BUILDDIR])dnl
+
+dnl Autoconf doesn't catch unexpanded LT_ macros by default:
+m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl
+m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl
+dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4
+dnl unless we require an AC_DEFUNed macro:
+AC_REQUIRE([LTOPTIONS_VERSION])dnl
+AC_REQUIRE([LTSUGAR_VERSION])dnl
+AC_REQUIRE([LTVERSION_VERSION])dnl
+AC_REQUIRE([LTOBSOLETE_VERSION])dnl
+m4_require([_LT_PROG_LTMAIN])dnl
+
+dnl Parse OPTIONS
+_LT_SET_OPTIONS([$0], [$1])
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+_LT_SETUP
+
+# Only expand once:
+m4_define([LT_INIT])
+])# LT_INIT
+
+# Old names:
+AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT])
+AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PROG_LIBTOOL], [])
+dnl AC_DEFUN([AM_PROG_LIBTOOL], [])
+
+
+# _LT_CC_BASENAME(CC)
+# -------------------
+# Calculate cc_basename.  Skip known compiler wrappers and cross-prefix.
+m4_defun([_LT_CC_BASENAME],
+[for cc_temp in $1""; do
+  case $cc_temp in
+    compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;;
+    distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+])
+
+
+# _LT_FILEUTILS_DEFAULTS
+# ----------------------
+# It is okay to use these file commands and assume they have been set
+# sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'.
+m4_defun([_LT_FILEUTILS_DEFAULTS],
+[: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+])# _LT_FILEUTILS_DEFAULTS
+
+
+# _LT_SETUP
+# ---------
+m4_defun([_LT_SETUP],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+_LT_DECL([], [host_alias], [0], [The host system])dnl
+_LT_DECL([], [host], [0])dnl
+_LT_DECL([], [host_os], [0])dnl
+dnl
+_LT_DECL([], [build_alias], [0], [The build system])dnl
+_LT_DECL([], [build], [0])dnl
+_LT_DECL([], [build_os], [0])dnl
+dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+test -z "$LN_S" && LN_S="ln -s"
+_LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl
+dnl
+AC_REQUIRE([LT_CMD_MAX_LEN])dnl
+_LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl
+_LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
+dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_CMD_RELOAD])dnl
+m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CMD_OLD_ARCHIVE])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+
+_LT_CONFIG_LIBTOOL_INIT([
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+])
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+_LT_CHECK_OBJDIR
+
+m4_require([_LT_TAG_COMPILER])dnl
+_LT_PROG_ECHO_BACKSLASH
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+_LT_CC_BASENAME([$compiler])
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    _LT_PATH_MAGIC
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+LT_SUPPORTED_TAG([CC])
+_LT_LANG_C_CONFIG
+_LT_LANG_DEFAULT_CONFIG
+_LT_CONFIG_COMMANDS
+])# _LT_SETUP
+
+
+# _LT_PROG_LTMAIN
+# ---------------
+# Note that this code is called both from `configure', and `config.status'
+# now that we use AC_CONFIG_COMMANDS to generate libtool.  Notably,
+# `config.status' has no value for ac_aux_dir unless we are using Automake,
+# so we pass a copy along to make sure it has a sensible value anyway.
+m4_defun([_LT_PROG_LTMAIN],
+[m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl
+_LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir'])
+ltmain="$ac_aux_dir/ltmain.sh"
+])# _LT_PROG_LTMAIN
+
+
+## ------------------------------------- ##
+## Accumulate code for creating libtool. ##
+## ------------------------------------- ##
+
+# So that we can recreate a full libtool script including additional
+# tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS
+# in macros and then make a single call at the end using the `libtool'
+# label.
+
+
+# _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS])
+# ----------------------------------------
+# Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL_INIT],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_INIT],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_INIT])
+
+
+# _LT_CONFIG_LIBTOOL([COMMANDS])
+# ------------------------------
+# Register COMMANDS to be passed to AC_CONFIG_COMMANDS later.
+m4_define([_LT_CONFIG_LIBTOOL],
+[m4_ifval([$1],
+          [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS],
+                     [$1
+])])])
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS])
+
+
+# _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS])
+# -----------------------------------------------------
+m4_defun([_LT_CONFIG_SAVE_COMMANDS],
+[_LT_CONFIG_LIBTOOL([$1])
+_LT_CONFIG_LIBTOOL_INIT([$2])
+])
+
+
+# _LT_FORMAT_COMMENT([COMMENT])
+# -----------------------------
+# Add leading comment marks to the start of each line, and a trailing
+# full-stop to the whole comment if one is not present already.
+m4_define([_LT_FORMAT_COMMENT],
+[m4_ifval([$1], [
+m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])],
+              [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.])
+)])
+
+
+
+## ------------------------ ##
+## FIXME: Eliminate VARNAME ##
+## ------------------------ ##
+
+
+# _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?])
+# -------------------------------------------------------------------
+# CONFIGNAME is the name given to the value in the libtool script.
+# VARNAME is the (base) name used in the configure script.
+# VALUE may be 0, 1 or 2 for a computed quote escaped value based on
+# VARNAME.  Any other value will be used directly.
+m4_define([_LT_DECL],
+[lt_if_append_uniq([lt_decl_varnames], [$2], [, ],
+    [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name],
+	[m4_ifval([$1], [$1], [$2])])
+    lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3])
+    m4_ifval([$4],
+	[lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])])
+    lt_dict_add_subkey([lt_decl_dict], [$2],
+	[tagged?], [m4_ifval([$5], [yes], [no])])])
+])
+
+
+# _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION])
+# --------------------------------------------------------
+m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])])
+
+
+# lt_decl_tag_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_tag_varnames],
+[_lt_decl_filter([tagged?], [yes], $@)])
+
+
+# _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..])
+# ---------------------------------------------------------
+m4_define([_lt_decl_filter],
+[m4_case([$#],
+  [0], [m4_fatal([$0: too few arguments: $#])],
+  [1], [m4_fatal([$0: too few arguments: $#: $1])],
+  [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)],
+  [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)],
+  [lt_dict_filter([lt_decl_dict], $@)])[]dnl
+])
+
+
+# lt_decl_quote_varnames([SEPARATOR], [VARNAME1...])
+# --------------------------------------------------
+m4_define([lt_decl_quote_varnames],
+[_lt_decl_filter([value], [1], $@)])
+
+
+# lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_dquote_varnames],
+[_lt_decl_filter([value], [2], $@)])
+
+
+# lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...])
+# ---------------------------------------------------
+m4_define([lt_decl_varnames_tagged],
+[m4_assert([$# <= 2])dnl
+_$0(m4_quote(m4_default([$1], [[, ]])),
+    m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]),
+    m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))])
+m4_define([_lt_decl_varnames_tagged],
+[m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])])
+
+
+# lt_decl_all_varnames([SEPARATOR], [VARNAME1...])
+# ------------------------------------------------
+m4_define([lt_decl_all_varnames],
+[_$0(m4_quote(m4_default([$1], [[, ]])),
+     m4_if([$2], [],
+	   m4_quote(lt_decl_varnames),
+	m4_quote(m4_shift($@))))[]dnl
+])
+m4_define([_lt_decl_all_varnames],
+[lt_join($@, lt_decl_varnames_tagged([$1],
+			lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl
+])
+
+
+# _LT_CONFIG_STATUS_DECLARE([VARNAME])
+# ------------------------------------
+# Quote a variable value, and forward it to `config.status' so that its
+# declaration there will have the same value as in `configure'.  VARNAME
+# must have a single quote delimited value for this to work.
+m4_define([_LT_CONFIG_STATUS_DECLARE],
+[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+
+
+# _LT_CONFIG_STATUS_DECLARATIONS
+# ------------------------------
+# We delimit libtool config variables with single quotes, so when
+# we write them to config.status, we have to be sure to quote all
+# embedded single quotes properly.  In configure, this macro expands
+# each variable declared with _LT_DECL (and _LT_TAGDECL) into:
+#
+#    <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
+    [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAGS
+# ----------------
+# Output comment and list of tags supported by the script
+m4_defun([_LT_LIBTOOL_TAGS],
+[_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl
+available_tags="_LT_TAGS"dnl
+])
+
+
+# _LT_LIBTOOL_DECLARE(VARNAME, [TAG])
+# -----------------------------------
+# Extract the dictionary values for VARNAME (optionally with TAG) and
+# expand to a commented shell variable setting:
+#
+#    # Some comment about what VAR is for.
+#    visible_name=$lt_internal_name
+m4_define([_LT_LIBTOOL_DECLARE],
+[_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1],
+					   [description])))[]dnl
+m4_pushdef([_libtool_name],
+    m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl
+m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])),
+    [0], [_libtool_name=[$]$1],
+    [1], [_libtool_name=$lt_[]$1],
+    [2], [_libtool_name=$lt_[]$1],
+    [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl
+m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl
+])
+
+
+# _LT_LIBTOOL_CONFIG_VARS
+# -----------------------
+# Produce commented declarations of non-tagged libtool config variables
+# suitable for insertion in the LIBTOOL CONFIG section of the `libtool'
+# script.  Tagged libtool config variables (even for the LIBTOOL CONFIG
+# section) are produced by _LT_LIBTOOL_TAG_VARS.
+m4_defun([_LT_LIBTOOL_CONFIG_VARS],
+[m4_foreach([_lt_var],
+    m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])])
+
+
+# _LT_LIBTOOL_TAG_VARS(TAG)
+# -------------------------
+m4_define([_LT_LIBTOOL_TAG_VARS],
+[m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames),
+    [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])])
+
+
+# _LT_TAGVAR(VARNAME, [TAGNAME])
+# ------------------------------
+m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])])
+
+
+# _LT_CONFIG_COMMANDS
+# -------------------
+# Send accumulated output to $CONFIG_STATUS.  Thanks to the lists of
+# variables for single and double quote escaping we saved from calls
+# to _LT_DECL, we can put quote escaped variables declarations
+# into `config.status', and then the shell code to quote escape them in
+# for loops in `config.status'.  Finally, any additional code accumulated
+# from calls to _LT_CONFIG_LIBTOOL_INIT is expanded.
+m4_defun([_LT_CONFIG_COMMANDS],
+[AC_PROVIDE_IFELSE([LT_OUTPUT],
+	dnl If the libtool generation code has been placed in $CONFIG_LT,
+	dnl instead of duplicating it all over again into config.status,
+	dnl then we will have config.status run $CONFIG_LT later, so it
+	dnl needs to know what name is stored there:
+        [AC_CONFIG_COMMANDS([libtool],
+            [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])],
+    dnl If the libtool generation code is destined for config.status,
+    dnl expand the accumulated commands and init code now:
+    [AC_CONFIG_COMMANDS([libtool],
+        [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])])
+])#_LT_CONFIG_COMMANDS
+
+
+# Initialize.
+m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT],
+[
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+_LT_CONFIG_STATUS_DECLARATIONS
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_quote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in lt_decl_all_varnames([[ \
+]], lt_decl_dquote_varnames); do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[[\\\\\\\`\\"\\\$]]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\[$]0 --fallback-echo"')dnl "
+  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
+  ;;
+esac
+
+_LT_OUTPUT_LIBTOOL_INIT
+])
+
+
+# LT_OUTPUT
+# ---------
+# This macro allows early generation of the libtool script (before
+# AC_OUTPUT is called), incase it is used in configure for compilation
+# tests.
+AC_DEFUN([LT_OUTPUT],
+[: ${CONFIG_LT=./config.lt}
+AC_MSG_NOTICE([creating $CONFIG_LT])
+cat >"$CONFIG_LT" <<_LTEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate a libtool stub with the current configuration.
+
+lt_cl_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AS_SHELL_SANITIZE
+_AS_PREPARE
+
+exec AS_MESSAGE_FD>&1
+exec AS_MESSAGE_LOG_FD>>config.log
+{
+  echo
+  AS_BOX([Running $as_me.])
+} >&AS_MESSAGE_LOG_FD
+
+lt_cl_help="\
+\`$as_me' creates a local libtool stub from the current configuration,
+for use in further configure time tests before the real libtool is
+generated.
+
+Usage: $[0] [[OPTIONS]]
+
+  -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
+
+Report bugs to <bug-libtool at gnu.org>."
+
+lt_cl_version="\
+m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
+m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
+configured by $[0], generated by m4_PACKAGE_STRING.
+
+Copyright (C) 2008 Free Software Foundation, Inc.
+This config.lt script is free software; the Free Software Foundation
+gives unlimited permision to copy, distribute and modify it."
+
+while test $[#] != 0
+do
+  case $[1] in
+    --version | --v* | -V )
+      echo "$lt_cl_version"; exit 0 ;;
+    --help | --h* | -h )
+      echo "$lt_cl_help"; exit 0 ;;
+    --debug | --d* | -d )
+      debug=: ;;
+    --quiet | --q* | --silent | --s* | -q )
+      lt_cl_silent=: ;;
+
+    -*) AC_MSG_ERROR([unrecognized option: $[1]
+Try \`$[0] --help' for more information.]) ;;
+
+    *) AC_MSG_ERROR([unrecognized argument: $[1]
+Try \`$[0] --help' for more information.]) ;;
+  esac
+  shift
+done
+
+if $lt_cl_silent; then
+  exec AS_MESSAGE_FD>/dev/null
+fi
+_LTEOF
+
+cat >>"$CONFIG_LT" <<_LTEOF
+_LT_OUTPUT_LIBTOOL_COMMANDS_INIT
+_LTEOF
+
+cat >>"$CONFIG_LT" <<\_LTEOF
+AC_MSG_NOTICE([creating $ofile])
+_LT_OUTPUT_LIBTOOL_COMMANDS
+AS_EXIT(0)
+_LTEOF
+chmod +x "$CONFIG_LT"
+
+# configure is writing to config.log, but config.lt does its own redirection,
+# appending to config.log, which fails on DOS, as config.log is still kept
+# open by configure.  Here we exec the FD to /dev/null, effectively closing
+# config.log, so it can be properly (re)opened and appended to by config.lt.
+if test "$no_create" != yes; then
+  lt_cl_success=:
+  test "$silent" = yes &&
+    lt_config_lt_args="$lt_config_lt_args --quiet"
+  exec AS_MESSAGE_LOG_FD>/dev/null
+  $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+  exec AS_MESSAGE_LOG_FD>>config.log
+  $lt_cl_success || AS_EXIT(1)
+fi
+])# LT_OUTPUT
+
+
+# _LT_CONFIG(TAG)
+# ---------------
+# If TAG is the built-in tag, create an initial libtool script with a
+# default configuration from the untagged config vars.  Otherwise add code
+# to config.status for appending the configuration named by TAG from the
+# matching tagged config vars.
+m4_defun([_LT_CONFIG],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_CONFIG_SAVE_COMMANDS([
+  m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl
+  m4_if(_LT_TAG, [C], [
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+_LT_COPYING
+_LT_LIBTOOL_TAGS
+
+# ### BEGIN LIBTOOL CONFIG
+_LT_LIBTOOL_CONFIG_VARS
+_LT_LIBTOOL_TAG_VARS
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+  _LT_PROG_LTMAIN
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  _LT_PROG_XSI_SHELLFNS
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+],
+[cat <<_LT_EOF >> "$ofile"
+
+dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded
+dnl in a comment (ie after a #).
+# ### BEGIN LIBTOOL TAG CONFIG: $1
+_LT_LIBTOOL_TAG_VARS(_LT_TAG)
+# ### END LIBTOOL TAG CONFIG: $1
+_LT_EOF
+])dnl /m4_if
+],
+[m4_if([$1], [], [
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'], [])
+])dnl /_LT_CONFIG_SAVE_COMMANDS
+])# _LT_CONFIG
+
+
+# LT_SUPPORTED_TAG(TAG)
+# ---------------------
+# Trace this macro to discover what tags are supported by the libtool
+# --tag option, using:
+#    autoconf --trace 'LT_SUPPORTED_TAG:$1'
+AC_DEFUN([LT_SUPPORTED_TAG], [])
+
+
+# C support is built-in for now
+m4_define([_LT_LANG_C_enabled], [])
+m4_define([_LT_TAGS], [])
+
+
+# LT_LANG(LANG)
+# -------------
+# Enable libtool support for the given language if not already enabled.
+AC_DEFUN([LT_LANG],
+[AC_BEFORE([$0], [LT_OUTPUT])dnl
+m4_case([$1],
+  [C],			[_LT_LANG(C)],
+  [C++],		[_LT_LANG(CXX)],
+  [Java],		[_LT_LANG(GCJ)],
+  [Fortran 77],		[_LT_LANG(F77)],
+  [Fortran],		[_LT_LANG(FC)],
+  [Windows Resource],	[_LT_LANG(RC)],
+  [m4_ifdef([_LT_LANG_]$1[_CONFIG],
+    [_LT_LANG($1)],
+    [m4_fatal([$0: unsupported language: "$1"])])])dnl
+])# LT_LANG
+
+
+# _LT_LANG(LANGNAME)
+# ------------------
+m4_defun([_LT_LANG],
+[m4_ifdef([_LT_LANG_]$1[_enabled], [],
+  [LT_SUPPORTED_TAG([$1])dnl
+  m4_append([_LT_TAGS], [$1 ])dnl
+  m4_define([_LT_LANG_]$1[_enabled], [])dnl
+  _LT_LANG_$1_CONFIG($1)])dnl
+])# _LT_LANG
+
+
+# _LT_LANG_DEFAULT_CONFIG
+# -----------------------
+m4_defun([_LT_LANG_DEFAULT_CONFIG],
+[AC_PROVIDE_IFELSE([AC_PROG_CXX],
+  [LT_LANG(CXX)],
+  [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_F77],
+  [LT_LANG(F77)],
+  [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])])
+
+AC_PROVIDE_IFELSE([AC_PROG_FC],
+  [LT_LANG(FC)],
+  [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])])
+
+dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal
+dnl pulling things in needlessly.
+AC_PROVIDE_IFELSE([AC_PROG_GCJ],
+  [LT_LANG(GCJ)],
+  [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],
+    [LT_LANG(GCJ)],
+    [AC_PROVIDE_IFELSE([LT_PROG_GCJ],
+      [LT_LANG(GCJ)],
+      [m4_ifdef([AC_PROG_GCJ],
+	[m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([A][M_PROG_GCJ],
+	[m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])])
+       m4_ifdef([LT_PROG_GCJ],
+	[m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
+
+AC_PROVIDE_IFELSE([LT_PROG_RC],
+  [LT_LANG(RC)],
+  [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
+])# _LT_LANG_DEFAULT_CONFIG
+
+# Obsolete macros:
+AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
+AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
+AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
+AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
+dnl AC_DEFUN([AC_LIBTOOL_F77], [])
+dnl AC_DEFUN([AC_LIBTOOL_FC], [])
+dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+
+
+# _LT_TAG_COMPILER
+# ----------------
+m4_defun([_LT_TAG_COMPILER],
+[AC_REQUIRE([AC_PROG_CC])dnl
+
+_LT_DECL([LTCC], [CC], [1], [A C compiler])dnl
+_LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl
+_LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl
+_LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+])# _LT_TAG_COMPILER
+
+
+# _LT_COMPILER_BOILERPLATE
+# ------------------------
+# Check for compiler boilerplate output or warnings with
+# the simple compiler test code.
+m4_defun([_LT_COMPILER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+])# _LT_COMPILER_BOILERPLATE
+
+
+# _LT_LINKER_BOILERPLATE
+# ----------------------
+# Check for linker boilerplate output or warnings with
+# the simple link test code.
+m4_defun([_LT_LINKER_BOILERPLATE],
+[m4_require([_LT_DECL_SED])dnl
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+])# _LT_LINKER_BOILERPLATE
+
+# _LT_REQUIRED_DARWIN_CHECKS
+# -------------------------
+m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
+  case $host_os in
+    rhapsody* | darwin*)
+    AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:])
+    AC_CHECK_TOOL([NMEDIT], [nmedit], [:])
+    AC_CHECK_TOOL([LIPO], [lipo], [:])
+    AC_CHECK_TOOL([OTOOL], [otool], [:])
+    AC_CHECK_TOOL([OTOOL64], [otool64], [:])
+    _LT_DECL([], [DSYMUTIL], [1],
+      [Tool to manipulate archived DWARF debug symbol files on Mac OS X])
+    _LT_DECL([], [NMEDIT], [1],
+      [Tool to change global to local symbols on Mac OS X])
+    _LT_DECL([], [LIPO], [1],
+      [Tool to manipulate fat objects and archives on Mac OS X])
+    _LT_DECL([], [OTOOL], [1],
+      [ldd/readelf like tool for Mach-O binaries on Mac OS X])
+    _LT_DECL([], [OTOOL64], [1],
+      [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4])
+
+    AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod],
+      [lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&AS_MESSAGE_LOG_FD
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi])
+    AC_CACHE_CHECK([for -exported_symbols_list linker flag],
+      [lt_cv_ld_exported_symbols_list],
+      [lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+	[lt_cv_ld_exported_symbols_list=yes],
+	[lt_cv_ld_exported_symbols_list=no])
+	LDFLAGS="$save_LDFLAGS"
+    ])
+    case $host_os in
+    rhapsody* | darwin1.[[012]])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[[012]]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+])
+
+
+# _LT_DARWIN_LINKER_FEATURES
+# --------------------------
+# Checks for linker and compiler features on darwin
+m4_defun([_LT_DARWIN_LINKER_FEATURES],
+[
+  m4_require([_LT_REQUIRED_DARWIN_CHECKS])
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_automatic, $1)=yes
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  _LT_TAGVAR(link_all_deplibs, $1)=yes
+  _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+    m4_if([$1], [CXX],
+[   if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+],[])
+  else
+  _LT_TAGVAR(ld_shlibs, $1)=no
+  fi
+])
+
+# _LT_SYS_MODULE_PATH_AIX
+# -----------------------
+# Links a minimal program and checks the executable
+# for the system default hardcoded library path. In most cases,
+# this is /usr/lib:/lib, but when the MPI compilers are used
+# the location of the communication and MPI libs are included too.
+# If we don't find anything, use the default library path according
+# to the aix ld manual.
+m4_defun([_LT_SYS_MODULE_PATH_AIX],
+[m4_require([_LT_DECL_SED])dnl
+AC_LINK_IFELSE(AC_LANG_PROGRAM,[
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi],[])
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+])# _LT_SYS_MODULE_PATH_AIX
+
+
+# _LT_SHELL_INIT(ARG)
+# -------------------
+m4_define([_LT_SHELL_INIT],
+[ifdef([AC_DIVERSION_NOTICE],
+	     [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
+	 [AC_DIVERT_PUSH(NOTICE)])
+$1
+AC_DIVERT_POP
+])# _LT_SHELL_INIT
+
+
+# _LT_PROG_ECHO_BACKSLASH
+# -----------------------
+# Add some code to the start of the generated configure script which
+# will find an echo command which doesn't interpret backslashes.
+m4_defun([_LT_PROG_ECHO_BACKSLASH],
+[_LT_SHELL_INIT([
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X[$]1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X[$]1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
+fi
+
+if test "X[$]1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+[$]*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "[$]0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
+fi
+
+AC_SUBST(lt_ECHO)
+])
+_LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
+_LT_DECL([], [ECHO], [1],
+    [An echo program that does not interpret backslashes])
+])# _LT_PROG_ECHO_BACKSLASH
+
+
+# _LT_ENABLE_LOCK
+# ---------------
+m4_defun([_LT_ENABLE_LOCK],
+[AC_ARG_ENABLE([libtool-lock],
+  [AS_HELP_STRING([--disable-libtool-lock],
+    [avoid locking (might break parallel builds)])])
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+    [AC_LANG_PUSH(C)
+     AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])
+     AC_LANG_POP])
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if AC_TRY_EVAL(ac_compile); then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+])# _LT_ENABLE_LOCK
+
+
+# _LT_CMD_OLD_ARCHIVE
+# -------------------
+m4_defun([_LT_CMD_OLD_ARCHIVE],
+[AC_CHECK_TOOL(AR, ar, false)
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1])
+
+AC_CHECK_TOOL(STRIP, strip, :)
+test -z "$STRIP" && STRIP=:
+_LT_DECL([], [STRIP], [1], [A symbol stripping program])
+
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+test -z "$RANLIB" && RANLIB=:
+_LT_DECL([], [RANLIB], [1],
+    [Commands used to install an old-style archive])
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+_LT_DECL([], [old_postinstall_cmds], [2])
+_LT_DECL([], [old_postuninstall_cmds], [2])
+_LT_TAGDECL([], [old_archive_cmds], [2],
+    [Commands used to build an old-style archive])
+])# _LT_CMD_OLD_ARCHIVE
+
+
+# _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#		[OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------------------
+# Check whether the given compiler option works
+AC_DEFUN([_LT_COMPILER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4])
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$3"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       $2=yes
+     fi
+   fi
+   $RM conftest*
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$5], , :, [$5])
+else
+    m4_if([$6], , :, [$6])
+fi
+])# _LT_COMPILER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], [])
+
+
+# _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS,
+#                  [ACTION-SUCCESS], [ACTION-FAILURE])
+# ----------------------------------------------------
+# Check whether the given linker option works
+AC_DEFUN([_LT_LINKER_OPTION],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_CACHE_CHECK([$1], [$2],
+  [$2=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $3"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&AS_MESSAGE_LOG_FD
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         $2=yes
+       fi
+     else
+       $2=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+])
+
+if test x"[$]$2" = xyes; then
+    m4_if([$4], , :, [$4])
+else
+    m4_if([$5], , :, [$5])
+fi
+])# _LT_LINKER_OPTION
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], [])
+
+
+# LT_CMD_MAX_LEN
+#---------------
+AC_DEFUN([LT_CMD_MAX_LEN],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+# find the maximum length of command line arguments
+AC_MSG_CHECKING([the maximum length of command line arguments])
+AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
+  i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[	 ]]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+])
+if test -n $lt_cv_sys_max_cmd_len ; then
+  AC_MSG_RESULT($lt_cv_sys_max_cmd_len)
+else
+  AC_MSG_RESULT(none)
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+_LT_DECL([], [max_cmd_len], [0],
+    [What is the maximum length of a command?])
+])# LT_CMD_MAX_LEN
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], [])
+
+
+# _LT_HEADER_DLFCN
+# ----------------
+m4_defun([_LT_HEADER_DLFCN],
+[AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl
+])# _LT_HEADER_DLFCN
+
+
+# _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE,
+#                      ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING)
+# ----------------------------------------------------------------
+m4_defun([_LT_TRY_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "$cross_compiling" = yes; then :
+  [$4]
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+[#line __oline__ "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}]
+_LT_EOF
+  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) $1 ;;
+      x$lt_dlneed_uscore) $2 ;;
+      x$lt_dlunknown|x*) $3 ;;
+    esac
+  else :
+    # compilation failed
+    $3
+  fi
+fi
+rm -fr conftest*
+])# _LT_TRY_DLOPEN_SELF
+
+
+# LT_SYS_DLOPEN_SELF
+# ------------------
+AC_DEFUN([LT_SYS_DLOPEN_SELF],
+[m4_require([_LT_HEADER_DLFCN])dnl
+if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ])
+    ;;
+
+  *)
+    AC_CHECK_FUNC([shl_load],
+	  [lt_cv_dlopen="shl_load"],
+      [AC_CHECK_LIB([dld], [shl_load],
+	    [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"],
+	[AC_CHECK_FUNC([dlopen],
+	      [lt_cv_dlopen="dlopen"],
+	  [AC_CHECK_LIB([dl], [dlopen],
+		[lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],
+	    [AC_CHECK_LIB([svld], [dlopen],
+		  [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"],
+	      [AC_CHECK_LIB([dld], [dld_link],
+		    [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"])
+	      ])
+	    ])
+	  ])
+	])
+      ])
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    AC_CACHE_CHECK([whether a program can dlopen itself],
+	  lt_cv_dlopen_self, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes,
+	    lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross)
+    ])
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      AC_CACHE_CHECK([whether a statically linked program can dlopen itself],
+	  lt_cv_dlopen_self_static, [dnl
+	  _LT_TRY_DLOPEN_SELF(
+	    lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes,
+	    lt_cv_dlopen_self_static=no,  lt_cv_dlopen_self_static=cross)
+      ])
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+_LT_DECL([dlopen_support], [enable_dlopen], [0],
+	 [Whether dlopen is supported])
+_LT_DECL([dlopen_self], [enable_dlopen_self], [0],
+	 [Whether dlopen of programs is supported])
+_LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0],
+	 [Whether dlopen of statically linked programs is supported])
+])# LT_SYS_DLOPEN_SELF
+
+# Old name:
+AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [])
+
+
+# _LT_COMPILER_C_O([TAGNAME])
+# ---------------------------
+# Check to see if options -c and -o are simultaneously supported by compiler.
+# This macro does not hard code the compiler like AC_PROG_CC_C_O.
+m4_defun([_LT_COMPILER_C_O],
+[m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&AS_MESSAGE_LOG_FD
+   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+     fi
+   fi
+   chmod u+w . 2>&AS_MESSAGE_LOG_FD
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+])
+_LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1],
+	[Does compiler simultaneously support -c and -o options?])
+])# _LT_COMPILER_C_O
+
+
+# _LT_COMPILER_FILE_LOCKS([TAGNAME])
+# ----------------------------------
+# Check to see if we can do hard links to lock some files if needed
+m4_defun([_LT_COMPILER_FILE_LOCKS],
+[m4_require([_LT_ENABLE_LOCK])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+_LT_COMPILER_C_O([$1])
+
+hard_links="nottested"
+if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  AC_MSG_CHECKING([if we can lock with hard links])
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  AC_MSG_RESULT([$hard_links])
+  if test "$hard_links" = no; then
+    AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe])
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+_LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?])
+])# _LT_COMPILER_FILE_LOCKS
+
+
+# _LT_CHECK_OBJDIR
+# ----------------
+m4_defun([_LT_CHECK_OBJDIR],
+[AC_CACHE_CHECK([for objdir], [lt_cv_objdir],
+[rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null])
+objdir=$lt_cv_objdir
+_LT_DECL([], [objdir], [0],
+         [The name of the directory that contains temporary libtool files])dnl
+m4_pattern_allow([LT_OBJDIR])dnl
+AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/",
+  [Define to the sub-directory in which libtool stores uninstalled libraries.])
+])# _LT_CHECK_OBJDIR
+
+
+# _LT_LINKER_HARDCODE_LIBPATH([TAGNAME])
+# --------------------------------------
+# Check hardcoding attributes.
+m4_defun([_LT_LINKER_HARDCODE_LIBPATH],
+[AC_MSG_CHECKING([how to hardcode library paths into programs])
+_LT_TAGVAR(hardcode_action, $1)=
+if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" ||
+   test -n "$_LT_TAGVAR(runpath_var, $1)" ||
+   test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$_LT_TAGVAR(hardcode_direct, $1)" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no &&
+     test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then
+    # Linking always hardcodes the temporary library directory.
+    _LT_TAGVAR(hardcode_action, $1)=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    _LT_TAGVAR(hardcode_action, $1)=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  _LT_TAGVAR(hardcode_action, $1)=unsupported
+fi
+AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)])
+
+if test "$_LT_TAGVAR(hardcode_action, $1)" = relink ||
+   test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+_LT_TAGDECL([], [hardcode_action], [0],
+    [How to hardcode a shared library path into an executable])
+])# _LT_LINKER_HARDCODE_LIBPATH
+
+
+# _LT_CMD_STRIPLIB
+# ----------------
+m4_defun([_LT_CMD_STRIPLIB],
+[m4_require([_LT_DECL_EGREP])
+striplib=
+old_striplib=
+AC_MSG_CHECKING([whether stripping libraries is possible])
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  AC_MSG_RESULT([yes])
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      AC_MSG_RESULT([yes])
+    else
+      AC_MSG_RESULT([no])
+    fi
+    ;;
+  *)
+    AC_MSG_RESULT([no])
+    ;;
+  esac
+fi
+_LT_DECL([], [old_striplib], [1], [Commands to strip libraries])
+_LT_DECL([], [striplib], [1])
+])# _LT_CMD_STRIPLIB
+
+
+# _LT_SYS_DYNAMIC_LINKER([TAG])
+# -----------------------------
+# PORTME Fill in your ld.so characteristics
+m4_defun([_LT_SYS_DYNAMIC_LINKER],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_OBJDUMP])dnl
+m4_require([_LT_DECL_SED])dnl
+AC_MSG_CHECKING([dynamic linker characteristics])
+m4_if([$1],
+	[], [
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[[lt_foo]]++; }
+  if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi])
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[[4-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[[01]] | aix4.[[01]].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[[45]]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+m4_if([$1], [],[
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"])
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[[123]]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[[01]]* | freebsdelf3.[[01]]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \
+  freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[[3-9]]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+       LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+    [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+       [shlibpath_overrides_runpath=yes])])
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[[89]] | openbsd2.[[89]].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+AC_MSG_RESULT([$dynamic_linker])
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+_LT_DECL([], [variables_saved_for_relink], [1],
+    [Variables whose values should be saved in libtool wrapper scripts and
+    restored at link time])
+_LT_DECL([], [need_lib_prefix], [0],
+    [Do we need the "lib" prefix for modules?])
+_LT_DECL([], [need_version], [0], [Do we need a version for libraries?])
+_LT_DECL([], [version_type], [0], [Library versioning type])
+_LT_DECL([], [runpath_var], [0],  [Shared library runtime path variable])
+_LT_DECL([], [shlibpath_var], [0],[Shared library path variable])
+_LT_DECL([], [shlibpath_overrides_runpath], [0],
+    [Is shlibpath searched before the hard-coded library search path?])
+_LT_DECL([], [libname_spec], [1], [Format of library name prefix])
+_LT_DECL([], [library_names_spec], [1],
+    [[List of archive names.  First name is the real one, the rest are links.
+    The last name is the one that the linker finds with -lNAME]])
+_LT_DECL([], [soname_spec], [1],
+    [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [postinstall_cmds], [2],
+    [Command to use after installation of a shared archive])
+_LT_DECL([], [postuninstall_cmds], [2],
+    [Command to use after uninstallation of a shared archive])
+_LT_DECL([], [finish_cmds], [2],
+    [Commands used to finish a libtool library installation in a directory])
+_LT_DECL([], [finish_eval], [1],
+    [[As "finish_cmds", except a single script fragment to be evaled but
+    not shown]])
+_LT_DECL([], [hardcode_into_libs], [0],
+    [Whether we should hardcode library paths into libraries])
+_LT_DECL([], [sys_lib_search_path_spec], [2],
+    [Compile-time system search path for libraries])
+_LT_DECL([], [sys_lib_dlsearch_path_spec], [2],
+    [Run-time system search path for libraries])
+])# _LT_SYS_DYNAMIC_LINKER
+
+
+# _LT_PATH_TOOL_PREFIX(TOOL)
+# --------------------------
+# find a file program which can recognize shared library
+AC_DEFUN([_LT_PATH_TOOL_PREFIX],
+[m4_require([_LT_DECL_EGREP])dnl
+AC_MSG_CHECKING([for $1])
+AC_CACHE_VAL(lt_cv_path_MAGIC_CMD,
+[case $MAGIC_CMD in
+[[\\/*] |  ?:[\\/]*])
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+dnl $ac_dummy forces splitting on constant user-supplied paths.
+dnl POSIX.2 word splitting is done only on the output of word expansions,
+dnl not every word.  This closes a longstanding sh security hole.
+  ac_dummy="m4_if([$2], , $PATH, [$2])"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$1; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/$1"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac])
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  AC_MSG_RESULT($MAGIC_CMD)
+else
+  AC_MSG_RESULT(no)
+fi
+_LT_DECL([], [MAGIC_CMD], [0],
+	 [Used to examine libraries when file_magic_cmd begins with "file"])dnl
+])# _LT_PATH_TOOL_PREFIX
+
+# Old name:
+AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], [])
+
+
+# _LT_PATH_MAGIC
+# --------------
+# find a file program which can recognize a shared library
+m4_defun([_LT_PATH_MAGIC],
+[_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH)
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH)
+  else
+    MAGIC_CMD=:
+  fi
+fi
+])# _LT_PATH_MAGIC
+
+
+# LT_PATH_LD
+# ----------
+# find the pathname to the GNU or non-GNU linker
+AC_DEFUN([LT_PATH_LD],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_ARG_WITH([gnu-ld],
+    [AS_HELP_STRING([--with-gnu-ld],
+	[assume the C compiler uses GNU ld @<:@default=no@:>@])],
+    [test "$withval" = no || with_gnu_ld=yes],
+    [with_gnu_ld=no])dnl
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  AC_MSG_CHECKING([for ld used by $CC])
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [[\\/]]* | ?:[[\\/]]*)
+      re_direlt='/[[^/]][[^/]]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  AC_MSG_CHECKING([for GNU ld])
+else
+  AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(lt_cv_path_LD,
+[if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  AC_MSG_RESULT($LD)
+else
+  AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+_LT_PATH_LD_GNU
+AC_SUBST([LD])
+
+_LT_TAGDECL([], [LD], [1], [The linker used to build libraries])
+])# LT_PATH_LD
+
+# Old names:
+AU_ALIAS([AM_PROG_LD], [LT_PATH_LD])
+AU_ALIAS([AC_PROG_LD], [LT_PATH_LD])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_LD], [])
+dnl AC_DEFUN([AC_PROG_LD], [])
+
+
+# _LT_PATH_LD_GNU
+#- --------------
+m4_defun([_LT_PATH_LD_GNU],
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac])
+with_gnu_ld=$lt_cv_prog_gnu_ld
+])# _LT_PATH_LD_GNU
+
+
+# _LT_CMD_RELOAD
+# --------------
+# find reload flag for linker
+#   -- PORTME Some linkers may need a different reload flag.
+m4_defun([_LT_CMD_RELOAD],
+[AC_CACHE_CHECK([for $LD option to reload object files],
+  lt_cv_ld_reload_flag,
+  [lt_cv_ld_reload_flag='-r'])
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_DECL([], [reload_cmds], [2])dnl
+])# _LT_CMD_RELOAD
+
+
+# _LT_CHECK_MAGIC_METHOD
+# ----------------------
+# how to check for library dependencies
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_MAGIC_METHOD],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+AC_CACHE_CHECK([how to recognize dependent libraries],
+lt_cv_deplibs_check_method,
+[lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[[4-9]]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[[45]]*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[[3-9]]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+])
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+_LT_DECL([], [deplibs_check_method], [1],
+    [Method to check whether dependent libraries are shared objects])
+_LT_DECL([], [file_magic_cmd], [1],
+    [Command to use when deplibs_check_method == "file_magic"])
+])# _LT_CHECK_MAGIC_METHOD
+
+
+# LT_PATH_NM
+# ----------
+# find the pathname to a BSD- or MS-compatible name lister
+AC_DEFUN([LT_PATH_NM],
+[AC_REQUIRE([AC_PROG_CC])dnl
+AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM,
+[if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi])
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+  AC_SUBST([DUMPBIN])
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+AC_SUBST([NM])
+_LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
+
+AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
+  [lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+  cat conftest.out >&AS_MESSAGE_LOG_FD
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*])
+])# LT_PATH_NM
+
+# Old names:
+AU_ALIAS([AM_PROG_NM], [LT_PATH_NM])
+AU_ALIAS([AC_PROG_NM], [LT_PATH_NM])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_PROG_NM], [])
+dnl AC_DEFUN([AC_PROG_NM], [])
+
+
+# LT_LIB_M
+# --------
+# check for math library
+AC_DEFUN([LT_LIB_M],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case $host in
+*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+  # These system don't have libm, or don't need it
+  ;;
+*-ncr-sysv4.3*)
+  AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+  AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm")
+  ;;
+*)
+  AC_CHECK_LIB(m, cos, LIBM="-lm")
+  ;;
+esac
+AC_SUBST([LIBM])
+])# LT_LIB_M
+
+# Old name:
+AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_CHECK_LIBM], [])
+
+
+# _LT_COMPILER_NO_RTTI([TAGNAME])
+# -------------------------------
+m4_defun([_LT_COMPILER_NO_RTTI],
+[m4_require([_LT_TAG_COMPILER])dnl
+
+_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+
+if test "$GCC" = yes; then
+  _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+
+  _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
+    lt_cv_prog_compiler_rtti_exceptions,
+    [-fno-rtti -fno-exceptions], [],
+    [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"])
+fi
+_LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
+	[Compiler flag to turn off builtin functions])
+])# _LT_COMPILER_NO_RTTI
+
+
+# _LT_CMD_GLOBAL_SYMBOLS
+# ----------------------
+m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+AC_REQUIRE([LT_PATH_LD])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output from $compiler object])
+AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe],
+[
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[[BCDEGRST]]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[[BCDT]]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[[ABCDGISTW]]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[[ABCDEGRST]]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[[BCDEGRST]]'
+  ;;
+osf*)
+  symcode='[[BCDEGQRST]]'
+  ;;
+solaris*)
+  symcode='[[BDRT]]'
+  ;;
+sco3.2v5*)
+  symcode='[[DT]]'
+  ;;
+sysv4.2uw2*)
+  symcode='[[DT]]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[[ABDT]]'
+  ;;
+sysv4)
+  symcode='[[DFNSTU]]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[[ABCDGIRSTW]]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK ['"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx]"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[	 ]]\($symcode$symcode*\)[[	 ]][[	 ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if AC_TRY_EVAL(ac_compile); then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[[]] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
+	  if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD
+    fi
+  else
+    echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+])
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  AC_MSG_RESULT(failed)
+else
+  AC_MSG_RESULT(ok)
+fi
+
+_LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
+    [Take the output of nm and produce a listing of raw symbols and C names])
+_LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
+    [Transform the output of nm in a proper C declaration])
+_LT_DECL([global_symbol_to_c_name_address],
+    [lt_cv_sys_global_symbol_to_c_name_address], [1],
+    [Transform the output of nm in a C name address pair])
+_LT_DECL([global_symbol_to_c_name_address_lib_prefix],
+    [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
+    [Transform the output of nm in a C name address pair when lib prefix is needed])
+]) # _LT_CMD_GLOBAL_SYMBOLS
+
+
+# _LT_COMPILER_PIC([TAGNAME])
+# ---------------------------
+m4_defun([_LT_COMPILER_PIC],
+[m4_require([_LT_TAG_COMPILER])dnl
+_LT_TAGVAR(lt_prog_compiler_wl, $1)=
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+_LT_TAGVAR(lt_prog_compiler_static, $1)=
+
+AC_MSG_CHECKING([for $compiler option to produce PIC])
+m4_if([$1], [CXX], [
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+      ;;
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[[4-9]]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	else
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  xlc* | xlC*)
+	    # IBM XL 8.0 on PPC
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+	;;
+    esac
+  fi
+],
+[
+  if test "$GCC" = yes; then
+    _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+    _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[[3-9]]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      else
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      m4_if([$1], [GCJ], [],
+	[_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # PIC (with -KPIC) is the default.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+        ;;
+      ccc*)
+        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+        # All Alpha code is PIC.
+        _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+	  _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+	  _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      # All OSF/1 code is PIC.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    rdos*)
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
+      *)
+	_LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	_LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic'
+	_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    unicos*)
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic'
+      _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+      ;;
+
+    *)
+      _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no
+      ;;
+    esac
+  fi
+])
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)=
+    ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
+    ;;
+esac
+AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+	[How to pass a linker flag through the compiler])
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+  _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works],
+    [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)],
+    [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t at m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [],
+    [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in
+     "" | " "*) ;;
+     *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;;
+     esac],
+    [_LT_TAGVAR(lt_prog_compiler_pic, $1)=
+     _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no])
+fi
+_LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
+	[Additional compiler flags for building library objects])
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\"
+_LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works],
+  _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1),
+  $lt_tmp_static_flag,
+  [],
+  [_LT_TAGVAR(lt_prog_compiler_static, $1)=])
+_LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
+	[Compiler flag to prevent dynamic linking])
+])# _LT_COMPILER_PIC
+
+
+# _LT_LINKER_SHLIBS([TAGNAME])
+# ----------------------------
+# See if the linker supports building shared libraries.
+m4_defun([_LT_LINKER_SHLIBS],
+[AC_REQUIRE([LT_PATH_LD])dnl
+AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_TAG_COMPILER])dnl
+AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+m4_if([$1], [CXX], [
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix[[4-9]]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
+  ;;
+  cygwin* | mingw* | cegcc*)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+], [
+  runpath_var=
+  _LT_TAGVAR(allow_undefined_flag, $1)=
+  _LT_TAGVAR(always_export_symbols, $1)=no
+  _LT_TAGVAR(archive_cmds, $1)=
+  _LT_TAGVAR(archive_expsym_cmds, $1)=
+  _LT_TAGVAR(compiler_needs_object, $1)=no
+  _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+  _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+  _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(hardcode_automatic, $1)=no
+  _LT_TAGVAR(hardcode_direct, $1)=no
+  _LT_TAGVAR(hardcode_direct_absolute, $1)=no
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+  _LT_TAGVAR(hardcode_minus_L, $1)=no
+  _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+  _LT_TAGVAR(inherit_rpath, $1)=no
+  _LT_TAGVAR(link_all_deplibs, $1)=unknown
+  _LT_TAGVAR(module_cmds, $1)=
+  _LT_TAGVAR(module_expsym_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_new_cmds, $1)=
+  _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)=
+  _LT_TAGVAR(thread_safe_flag_spec, $1)=
+  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  _LT_TAGVAR(include_expsyms, $1)=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+dnl Note also adjust exclude_expsyms for C++ above.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  _LT_TAGVAR(ld_shlibs, $1)=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[[3-9]]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	_LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+      # as there is no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=no
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	_LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    interix[[3-9]]*)
+      _LT_TAGVAR(hardcode_direct, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)=
+	  tmp_sharedflag='--shared' ;;
+	xl[[cC]]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  _LT_TAGVAR(compiler_needs_object, $1)=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	_LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        _LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*)
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+    esac
+
+    if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then
+      runpath_var=
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=
+      _LT_TAGVAR(whole_archive_flag_spec, $1)=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	_LT_TAGVAR(hardcode_direct, $1)=unsupported
+      fi
+      ;;
+
+    aix[[4-9]]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      _LT_TAGVAR(archive_cmds, $1)=''
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[[012]]|aix4.[[012]].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      _LT_TAGVAR(always_export_symbols, $1)=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	_LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        _LT_SYS_MODULE_PATH_AIX
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	  _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 _LT_SYS_MODULE_PATH_AIX
+	 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	  _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            _LT_TAGVAR(archive_expsym_cmds, $1)=''
+        ;;
+      m68k)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[[45]]*)
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+      # FIXME: Should let the user specify the lib program.
+      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
+      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      ;;
+
+    darwin* | rhapsody*)
+      _LT_DARWIN_LINKER_FEATURES($1)
+      ;;
+
+    dgux*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    freebsd1*)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	_LT_TAGVAR(hardcode_minus_L, $1)=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  ;;
+	*)
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        AC_LINK_IFELSE(int foo(void) {},
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+        )
+        LDFLAGS="$save_LDFLAGS"
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(inherit_rpath, $1)=yes
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    newsos6)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	_LT_TAGVAR(hardcode_direct, $1)=yes
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*)
+	     _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	     ;;
+	   *)
+	     _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	_LT_TAGVAR(ld_shlibs, $1)=no
+      fi
+      ;;
+
+    os2*)
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+      else
+	_LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+      fi
+      _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+      ;;
+
+    solaris*)
+      _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      case $host_os in
+      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_direct, $1)=yes
+      _LT_TAGVAR(hardcode_minus_L, $1)=yes
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs'
+	  _LT_TAGVAR(hardcode_direct, $1)=no
+        ;;
+	motorola)
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    sysv4.3*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	_LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	_LT_TAGVAR(ld_shlibs, $1)=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+      _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	_LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      ;;
+
+    *)
+      _LT_TAGVAR(ld_shlibs, $1)=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+])
+AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+_LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld
+
+_LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl
+_LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl
+_LT_DECL([], [extract_expsyms_cmds], [2],
+    [The commands to extract the exported symbol list from a shared archive])
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in
+x|xyes)
+  # Assume -lc should be added
+  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $_LT_TAGVAR(archive_cmds, $1) in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+	pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+        _LT_TAGVAR(allow_undefined_flag, $1)=
+        if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+        then
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        else
+	  _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+        fi
+        _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+_LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0],
+    [Whether or not to add -lc for building shared libraries])
+_LT_TAGDECL([allow_libtool_libs_with_static_runtimes],
+    [enable_shared_with_static_runtimes], [0],
+    [Whether or not to disallow shared libs when runtime libs are static])
+_LT_TAGDECL([], [export_dynamic_flag_spec], [1],
+    [Compiler flag to allow reflexive dlopens])
+_LT_TAGDECL([], [whole_archive_flag_spec], [1],
+    [Compiler flag to generate shared objects directly from archives])
+_LT_TAGDECL([], [compiler_needs_object], [1],
+    [Whether the compiler copes with passing no objects directly])
+_LT_TAGDECL([], [old_archive_from_new_cmds], [2],
+    [Create an old-style archive from a shared archive])
+_LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2],
+    [Create a temporary old-style archive to link instead of a shared archive])
+_LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive])
+_LT_TAGDECL([], [archive_expsym_cmds], [2])
+_LT_TAGDECL([], [module_cmds], [2],
+    [Commands used to build a loadable module if different from building
+    a shared archive.])
+_LT_TAGDECL([], [module_expsym_cmds], [2])
+_LT_TAGDECL([], [with_gnu_ld], [1],
+    [Whether we are building with GNU ld or not])
+_LT_TAGDECL([], [allow_undefined_flag], [1],
+    [Flag that allows shared libraries with undefined symbols to be built])
+_LT_TAGDECL([], [no_undefined_flag], [1],
+    [Flag that enforces no undefined symbols])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
+    [Flag to hardcode $libdir into a binary during linking.
+    This must work even if $libdir does not exist])
+_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
+    [[If ld is used when linking, flag to hardcode $libdir into a binary
+    during linking.  This must work even if $libdir does not exist]])
+_LT_TAGDECL([], [hardcode_libdir_separator], [1],
+    [Whether we need a single "-rpath" flag with a separated argument])
+_LT_TAGDECL([], [hardcode_direct], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary])
+_LT_TAGDECL([], [hardcode_direct_absolute], [0],
+    [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes
+    DIR into the resulting binary and the resulting library dependency is
+    "absolute", i.e impossible to change by setting ${shlibpath_var} if the
+    library is relocated])
+_LT_TAGDECL([], [hardcode_minus_L], [0],
+    [Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_shlibpath_var], [0],
+    [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+    into the resulting binary])
+_LT_TAGDECL([], [hardcode_automatic], [0],
+    [Set to "yes" if building a shared library automatically hardcodes DIR
+    into the library and all subsequent libraries and executables linked
+    against it])
+_LT_TAGDECL([], [inherit_rpath], [0],
+    [Set to yes if linker adds runtime paths of dependent libraries
+    to runtime path list])
+_LT_TAGDECL([], [link_all_deplibs], [0],
+    [Whether libtool must link a program against all its dependency libraries])
+_LT_TAGDECL([], [fix_srcfile_path], [1],
+    [Fix the shell variable $srcfile for the compiler])
+_LT_TAGDECL([], [always_export_symbols], [0],
+    [Set to "yes" if exported symbols are required])
+_LT_TAGDECL([], [export_symbols_cmds], [2],
+    [The commands to list exported symbols])
+_LT_TAGDECL([], [exclude_expsyms], [1],
+    [Symbols that should not be listed in the preloaded symbols])
+_LT_TAGDECL([], [include_expsyms], [1],
+    [Symbols that must always be exported])
+_LT_TAGDECL([], [prelink_cmds], [2],
+    [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [file_list_spec], [1],
+    [Specify filename containing input files])
+dnl FIXME: Not yet implemented
+dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1],
+dnl    [Compiler flag to generate thread safe objects])
+])# _LT_LINKER_SHLIBS
+
+
+# _LT_LANG_C_CONFIG([TAG])
+# ------------------------
+# Ensure that the configuration variables for a C compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_C_CONFIG],
+[m4_require([_LT_DECL_EGREP])dnl
+lt_save_CC="$CC"
+AC_LANG_PUSH(C)
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+_LT_TAG_COMPILER
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_SYS_DYNAMIC_LINKER($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+  LT_SYS_DLOPEN_SELF
+  _LT_CMD_STRIPLIB
+
+  # Report which library types will actually be built
+  AC_MSG_CHECKING([if libtool supports shared libraries])
+  AC_MSG_RESULT([$can_build_shared])
+
+  AC_MSG_CHECKING([whether to build shared libraries])
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[[4-9]]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  AC_MSG_RESULT([$enable_shared])
+
+  AC_MSG_CHECKING([whether to build static libraries])
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  AC_MSG_RESULT([$enable_static])
+
+  _LT_CONFIG($1)
+fi
+AC_LANG_POP
+CC="$lt_save_CC"
+])# _LT_LANG_C_CONFIG
+
+
+# _LT_PROG_CXX
+# ------------
+# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
+# compiler, we have our own version here.
+m4_defun([_LT_PROG_CXX],
+[
+pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
+AC_PROG_CXX
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_CXX
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_CXX], [])
+
+
+# _LT_LANG_CXX_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a C++ compiler are suitably
+# defined.  These variables are subsequently used by _LT_CONFIG to write
+# the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_CXX_CONFIG],
+[AC_REQUIRE([_LT_PROG_CXX])dnl
+m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+m4_require([_LT_DECL_EGREP])dnl
+
+AC_LANG_PUSH(C++)
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(compiler_needs_object, $1)=no
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+    else
+      _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+      LT_PATH_LD
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          _LT_TAGVAR(whole_archive_flag_spec, $1)=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
+    _LT_TAGVAR(ld_shlibs, $1)=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+      aix[[4-9]]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        _LT_TAGVAR(archive_cmds, $1)=''
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        _LT_TAGVAR(file_list_spec, $1)='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[[012]]|aix4.[[012]].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    _LT_TAGVAR(hardcode_direct, $1)=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    _LT_TAGVAR(hardcode_minus_L, $1)=yes
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        _LT_TAGVAR(always_export_symbols, $1)=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          _LT_SYS_MODULE_PATH_AIX
+          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
+	    _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs"
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    _LT_SYS_MODULE_PATH_AIX
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
+	    _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
+	    # Exported symbols can be pulled into shared objects from archives
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+        # as there is no search path for DLLs.
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+        _LT_TAGVAR(always_export_symbols, $1)=no
+        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+          # If the export-symbols file already is a .def file (1st line
+          # is EXPORTS), use it as is; otherwise, prepend...
+          _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    cp $export_symbols $output_objdir/$soname.def;
+          else
+	    echo EXPORTS > $output_objdir/$soname.def;
+	    cat $export_symbols >> $output_objdir/$soname.def;
+          fi~
+          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        else
+          _LT_TAGVAR(ld_shlibs, $1)=no
+        fi
+        ;;
+      darwin* | rhapsody*)
+        _LT_DARWIN_LINKER_FEATURES($1)
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[[12]]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      freebsd-elf*)
+        _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      hpux9*)
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+        _LT_TAGVAR(hardcode_direct, $1)=yes
+        _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            _LT_TAGVAR(ld_shlibs, $1)=no
+            ;;
+          aCC*)
+            _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              _LT_TAGVAR(ld_shlibs, $1)=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
+	  _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            _LT_TAGVAR(hardcode_direct, $1)=no
+            _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+            ;;
+          *)
+            _LT_TAGVAR(hardcode_direct, $1)=yes
+            _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+            _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[[3-9]]*)
+	_LT_TAGVAR(hardcode_direct, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	_LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	_LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+	      fi
+	    fi
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+	    ;;
+        esac
+        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+        _LT_TAGVAR(inherit_rpath, $1)=yes
+        ;;
+
+      linux* | k*bsd*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		_LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+	      _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+	      _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+		$RANLIB $oldlib'
+	      _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 will use weak symbols
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  xl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	      _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	      _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	      _LT_TAGVAR(compiler_needs_object, $1)=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='echo'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        _LT_TAGVAR(ld_shlibs, $1)=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	_LT_TAGVAR(ld_shlibs, $1)=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  _LT_TAGVAR(hardcode_direct, $1)=yes
+	  _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	  _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
+	    _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=echo
+	else
+	  _LT_TAGVAR(ld_shlibs, $1)=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
+		;;
+	    esac
+
+	    _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+	      _LT_TAGVAR(hardcode_libdir_separator, $1)=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      _LT_TAGVAR(ld_shlibs, $1)=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
+	    _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
+	    _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	    case $host_os in
+	      solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		_LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    _LT_TAGVAR(link_all_deplibs, $1)=yes
+
+	    output_verbose_link_cmd='echo'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      fi
+
+	      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[[0-5]] | solaris2.[[0-5]].*) ;;
+		*)
+		  _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*)
+      _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=no
+      _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	_LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text'
+	_LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs'
+	_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+	_LT_TAGVAR(hardcode_shlibpath_var, $1)=no
+	_LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir'
+	_LT_TAGVAR(hardcode_libdir_separator, $1)=':'
+	_LT_TAGVAR(link_all_deplibs, $1)=yes
+	_LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	  *)
+	    _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    _LT_TAGVAR(ld_shlibs, $1)=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        _LT_TAGVAR(ld_shlibs, $1)=no
+        ;;
+    esac
+
+    AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)])
+    test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no
+
+    _LT_TAGVAR(GCC, $1)="$GXX"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+AC_LANG_POP
+])# _LT_LANG_CXX_CONFIG
+
+
+# _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
+# ---------------------------------
+# Figure out "hidden" library dependencies from verbose
+# compiler output when linking a shared library.
+# Parse the compiler output and extract the necessary
+# objects, libraries and library flags.
+m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+# Dependencies to place before and after the object being linked:
+_LT_TAGVAR(predep_objects, $1)=
+_LT_TAGVAR(postdep_objects, $1)=
+_LT_TAGVAR(predeps, $1)=
+_LT_TAGVAR(postdeps, $1)=
+_LT_TAGVAR(compiler_lib_search_path, $1)=
+
+dnl we can't use the lt_simple_compile_test_code here,
+dnl because it contains code intended for an executable,
+dnl not a library.  It's possible we should let each
+dnl tag define a new lt_????_link_test_code variable,
+dnl but it's only used here...
+m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF
+int a;
+void foo (void) { a = 0; }
+_LT_EOF
+], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer*4 a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF
+      subroutine foo
+      implicit none
+      integer a
+      a=0
+      return
+      end
+_LT_EOF
+], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF
+public class foo {
+  private int a;
+  public void bar (void) {
+    a = 0;
+  }
+};
+_LT_EOF
+])
+dnl Parse the compiler output and extract the necessary
+dnl objects, libraries and library flags.
+if AC_TRY_EVAL(ac_compile); then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}"
+	   else
+	     _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$_LT_TAGVAR(postdeps, $1)"; then
+	   _LT_TAGVAR(postdeps, $1)="${prev}${p}"
+	 else
+	   _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$_LT_TAGVAR(predep_objects, $1)"; then
+	   _LT_TAGVAR(predep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p"
+	 fi
+       else
+	 if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then
+	   _LT_TAGVAR(postdep_objects, $1)="$p"
+	 else
+	   _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling $1 test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+m4_if([$1], [CXX],
+[case $host_os in
+interix[[3-9]]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  _LT_TAGVAR(predep_objects,$1)=
+  _LT_TAGVAR(postdep_objects,$1)=
+  _LT_TAGVAR(postdeps,$1)=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+])
+
+case " $_LT_TAGVAR(postdeps, $1) " in
+*" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;;
+esac
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=
+if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then
+ _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+_LT_TAGDECL([], [compiler_lib_search_dirs], [1],
+    [The directories searched by this compiler when creating a shared library])
+_LT_TAGDECL([], [predep_objects], [1],
+    [Dependencies to place before and after the objects being linked to
+    create a shared library])
+_LT_TAGDECL([], [postdep_objects], [1])
+_LT_TAGDECL([], [predeps], [1])
+_LT_TAGDECL([], [postdeps], [1])
+_LT_TAGDECL([], [compiler_lib_search_path], [1],
+    [The library search path used internally by the compiler when linking
+    a shared library])
+])# _LT_SYS_HIDDEN_LIBDEPS
+
+
+# _LT_PROG_F77
+# ------------
+# Since AC_PROG_F77 is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_F77],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
+AC_PROG_F77
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_F77
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_F77], [])
+
+
+# _LT_LANG_F77_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for a Fortran 77 compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_F77_CONFIG],
+[AC_REQUIRE([_LT_PROG_F77])dnl
+AC_LANG_PUSH(Fortran 77)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for f77 test sources.
+ac_ext=f
+
+# Object file extension for compiled f77 test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the F77 compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_F77" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${F77-"f77"}
+  compiler=$CC
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+  GCC=$G77
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$G77"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_F77" != yes
+
+AC_LANG_POP
+])# _LT_LANG_F77_CONFIG
+
+
+# _LT_PROG_FC
+# -----------
+# Since AC_PROG_FC is broken, in that it returns the empty string
+# if there is no fortran compiler, we have our own version here.
+m4_defun([_LT_PROG_FC],
+[
+pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
+AC_PROG_FC
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
+popdef([AC_MSG_ERROR])
+])# _LT_PROG_FC
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([_LT_PROG_FC], [])
+
+
+# _LT_LANG_FC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for a Fortran compiler are
+# suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_FC_CONFIG],
+[AC_REQUIRE([_LT_PROG_FC])dnl
+AC_LANG_PUSH(Fortran)
+
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+_LT_TAGVAR(allow_undefined_flag, $1)=
+_LT_TAGVAR(always_export_symbols, $1)=no
+_LT_TAGVAR(archive_expsym_cmds, $1)=
+_LT_TAGVAR(export_dynamic_flag_spec, $1)=
+_LT_TAGVAR(hardcode_direct, $1)=no
+_LT_TAGVAR(hardcode_direct_absolute, $1)=no
+_LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
+_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
+_LT_TAGVAR(hardcode_libdir_separator, $1)=
+_LT_TAGVAR(hardcode_minus_L, $1)=no
+_LT_TAGVAR(hardcode_automatic, $1)=no
+_LT_TAGVAR(inherit_rpath, $1)=no
+_LT_TAGVAR(module_cmds, $1)=
+_LT_TAGVAR(module_expsym_cmds, $1)=
+_LT_TAGVAR(link_all_deplibs, $1)=unknown
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(no_undefined_flag, $1)=
+_LT_TAGVAR(whole_archive_flag_spec, $1)=
+_LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
+
+# Source file extension for fc test sources.
+ac_ext=${ac_fc_srcext-f}
+
+# Object file extension for compiled fc test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# No sense in running all these tests if we already determined that
+# the FC compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_disable_FC" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="\
+      subroutine t
+      return
+      end
+"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code="\
+      program t
+      end
+"
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+  _LT_TAG_COMPILER
+
+  # save warnings/boilerplate of simple test code
+  _LT_COMPILER_BOILERPLATE
+  _LT_LINKER_BOILERPLATE
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC="$CC"
+  lt_save_GCC=$GCC
+  CC=${FC-"f95"}
+  compiler=$CC
+  GCC=$ac_cv_fc_compiler_gnu
+
+  _LT_TAGVAR(compiler, $1)=$CC
+  _LT_CC_BASENAME([$compiler])
+
+  if test -n "$compiler"; then
+    AC_MSG_CHECKING([if libtool supports shared libraries])
+    AC_MSG_RESULT([$can_build_shared])
+
+    AC_MSG_CHECKING([whether to build shared libraries])
+    test "$can_build_shared" = "no" && enable_shared=no
+
+    # On AIX, shared libraries and static libraries use the same namespace, and
+    # are all built from PIC.
+    case $host_os in
+      aix3*)
+        test "$enable_shared" = yes && enable_static=no
+        if test -n "$RANLIB"; then
+          archive_cmds="$archive_cmds~\$RANLIB \$lib"
+          postinstall_cmds='$RANLIB $lib'
+        fi
+        ;;
+      aix[[4-9]]*)
+	if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+	  test "$enable_shared" = yes && enable_static=no
+	fi
+        ;;
+    esac
+    AC_MSG_RESULT([$enable_shared])
+
+    AC_MSG_CHECKING([whether to build static libraries])
+    # Make sure either enable_shared or enable_static is yes.
+    test "$enable_shared" = yes || enable_static=yes
+    AC_MSG_RESULT([$enable_static])
+
+    _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu"
+    _LT_TAGVAR(LD, $1)="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    _LT_SYS_HIDDEN_LIBDEPS($1)
+    _LT_COMPILER_PIC($1)
+    _LT_COMPILER_C_O($1)
+    _LT_COMPILER_FILE_LOCKS($1)
+    _LT_LINKER_SHLIBS($1)
+    _LT_SYS_DYNAMIC_LINKER($1)
+    _LT_LINKER_HARDCODE_LIBPATH($1)
+
+    _LT_CONFIG($1)
+  fi # test -n "$compiler"
+
+  GCC=$lt_save_GCC
+  CC="$lt_save_CC"
+fi # test "$_lt_disable_FC" != yes
+
+AC_LANG_POP
+])# _LT_LANG_FC_CONFIG
+
+
+# _LT_LANG_GCJ_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Java Compiler compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GCJ_CONFIG],
+[AC_REQUIRE([LT_PROG_GCJ])dnl
+AC_LANG_SAVE
+
+# Source file extension for Java test sources.
+ac_ext=java
+
+# Object file extension for compiled Java test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="class foo {}"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GCJ-"gcj"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# GCJ did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC="$lt_save_CC"
+])# _LT_LANG_GCJ_CONFIG
+
+
+# _LT_LANG_RC_CONFIG([TAG])
+# -------------------------
+# Ensure that the configuration variables for the Windows resource compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_RC_CONFIG],
+[AC_REQUIRE([LT_PROG_RC])dnl
+AC_LANG_SAVE
+
+# Source file extension for RC test sources.
+ac_ext=rc
+
+# Object file extension for compiled RC test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }'
+
+# Code to be used in simple link tests
+lt_simple_link_test_code="$lt_simple_compile_test_code"
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC="$CC"
+lt_save_GCC=$GCC
+GCC=
+CC=${RC-"windres"}
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_CC_BASENAME([$compiler])
+_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
+
+if test -n "$compiler"; then
+  :
+  _LT_CONFIG($1)
+fi
+
+GCC=$lt_save_GCC
+AC_LANG_RESTORE
+CC="$lt_save_CC"
+])# _LT_LANG_RC_CONFIG
+
+
+# LT_PROG_GCJ
+# -----------
+AC_DEFUN([LT_PROG_GCJ],
+[m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ],
+  [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ],
+    [AC_CHECK_TOOL(GCJ, gcj,)
+      test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2"
+      AC_SUBST(GCJFLAGS)])])[]dnl
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
+
+
+# LT_PROG_RC
+# ----------
+AC_DEFUN([LT_PROG_RC],
+[AC_CHECK_TOOL(RC, windres,)
+])
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_RC], [])
+
+
+# _LT_DECL_EGREP
+# --------------
+# If we don't have a new enough Autoconf to choose the best grep
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_EGREP],
+[AC_REQUIRE([AC_PROG_EGREP])dnl
+AC_REQUIRE([AC_PROG_FGREP])dnl
+test -z "$GREP" && GREP=grep
+_LT_DECL([], [GREP], [1], [A grep program that handles long lines])
+_LT_DECL([], [EGREP], [1], [An ERE matcher])
+_LT_DECL([], [FGREP], [1], [A literal string matcher])
+dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too
+AC_SUBST([GREP])
+])
+
+
+# _LT_DECL_OBJDUMP
+# --------------
+# If we don't have a new enough Autoconf to choose the best objdump
+# available, choose the one first in the user's PATH.
+m4_defun([_LT_DECL_OBJDUMP],
+[AC_CHECK_TOOL(OBJDUMP, objdump, false)
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
+AC_SUBST([OBJDUMP])
+])
+
+
+# _LT_DECL_SED
+# ------------
+# Check for a fully-functional sed program, that truncates
+# as few characters as possible.  Prefer GNU sed if found.
+m4_defun([_LT_DECL_SED],
+[AC_PROG_SED
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+_LT_DECL([], [SED], [1], [A sed program that does not truncate output])
+_LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"],
+    [Sed that helps us avoid accidentally triggering echo(1) options like -n])
+])# _LT_DECL_SED
+
+m4_ifndef([AC_PROG_SED], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_SED.  When it is available in   #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+
+m4_defun([AC_PROG_SED],
+[AC_MSG_CHECKING([for a sed that does not truncate output])
+AC_CACHE_VAL(lt_cv_path_SED,
+[# Loop through the user's path and test for sed and gsed.
+# Then use that list of sed's as ones to test for truncation.
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for lt_ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then
+        lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext"
+      fi
+    done
+  done
+done
+IFS=$as_save_IFS
+lt_ac_max=0
+lt_ac_count=0
+# Add /usr/xpg4/bin/sed as it is typically found on Solaris
+# along with /bin/sed that truncates output.
+for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
+  test ! -f $lt_ac_sed && continue
+  cat /dev/null > conftest.in
+  lt_ac_count=0
+  echo $ECHO_N "0123456789$ECHO_C" >conftest.in
+  # Check for GNU sed and select it if it is found.
+  if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then
+    lt_cv_path_SED=$lt_ac_sed
+    break
+  fi
+  while true; do
+    cat conftest.in conftest.in >conftest.tmp
+    mv conftest.tmp conftest.in
+    cp conftest.in conftest.nl
+    echo >>conftest.nl
+    $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break
+    cmp -s conftest.out conftest.nl || break
+    # 10000 chars as input seems more than enough
+    test $lt_ac_count -gt 10 && break
+    lt_ac_count=`expr $lt_ac_count + 1`
+    if test $lt_ac_count -gt $lt_ac_max; then
+      lt_ac_max=$lt_ac_count
+      lt_cv_path_SED=$lt_ac_sed
+    fi
+  done
+done
+])
+SED=$lt_cv_path_SED
+AC_SUBST([SED])
+AC_MSG_RESULT([$SED])
+])#AC_PROG_SED
+])#m4_ifndef
+
+# Old name:
+AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED])
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([LT_AC_PROG_SED], [])
+
+
+# _LT_CHECK_SHELL_FEATURES
+# ------------------------
+# Find out whether the shell is Bourne or XSI compatible,
+# or has some other useful features.
+m4_defun([_LT_CHECK_SHELL_FEATURES],
+[AC_MSG_CHECKING([whether the shell understands some XSI constructs])
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+AC_MSG_RESULT([$xsi_shell])
+_LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell'])
+
+AC_MSG_CHECKING([whether the shell understands "+="])
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+AC_MSG_RESULT([$lt_shell_append])
+_LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append'])
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+_LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+_LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl
+_LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
+])# _LT_CHECK_SHELL_FEATURES
+
+
+# _LT_PROG_XSI_SHELLFNS
+# ---------------------
+# Bourne and XSI compatible variants of some useful shell functions.
+m4_defun([_LT_PROG_XSI_SHELLFNS],
+[case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $[*] ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+dnl func_dirname_and_basename
+dnl A portable version of this function is already defined in general.m4sh
+dnl so there is no need for it here.
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[[^=]]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$[@]"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]+=\$[2]"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$[1]=\$$[1]\$[2]"
+}
+
+_LT_EOF
+    ;;
+  esac
+])
diff --git a/conf/ltmain.sh b/conf/ltmain.sh
new file mode 100755
index 0000000..a72f2fd
--- /dev/null
+++ b/conf/ltmain.sh
@@ -0,0 +1,8406 @@
+# Generated from ltmain.m4sh.
+
+# ltmain.sh (GNU libtool) 2.2.6b
+# Written by Gordon Matzigkeit <gord at gnu.ai.mit.edu>, 1996
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# This is free software; see the source for copying conditions.  There is NO
+# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html,
+# or obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Usage: $progname [OPTION]... [MODE-ARG]...
+#
+# Provide generalized library-building support services.
+#
+#     --config             show all configuration variables
+#     --debug              enable verbose shell tracing
+# -n, --dry-run            display commands without modifying any files
+#     --features           display basic configuration information and exit
+#     --mode=MODE          use operation mode MODE
+#     --preserve-dup-deps  don't remove duplicate dependency libraries
+#     --quiet, --silent    don't print informational messages
+#     --tag=TAG            use configuration variables from tag TAG
+# -v, --verbose            print informational messages (default)
+#     --version            print version information
+# -h, --help               print short or long help message
+#
+# MODE must be one of the following:
+#
+#       clean              remove files from the build directory
+#       compile            compile a source file into a libtool object
+#       execute            automatically set library path, then run a program
+#       finish             complete the installation of libtool libraries
+#       install            install libraries or executables
+#       link               create a library or an executable
+#       uninstall          remove libraries from an installed directory
+#
+# MODE-ARGS vary depending on the MODE.
+# Try `$progname --help --mode=MODE' for a more detailed description of MODE.
+#
+# When reporting a bug, please describe a test case to reproduce it and
+# include the following information:
+#
+#       host-triplet:	$host
+#       shell:		$SHELL
+#       compiler:		$LTCC
+#       compiler flags:		$LTCFLAGS
+#       linker:		$LD (gnu? $with_gnu_ld)
+#       $progname:		(GNU libtool) 2.2.6b
+#       automake:		$automake_version
+#       autoconf:		$autoconf_version
+#
+# Report bugs to <bug-libtool at gnu.org>.
+
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=2.2.6b
+TIMESTAMP=""
+package_revision=1.3017
+
+# 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+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# NLS nuisances: We save the old values to restore during execute mode.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+lt_user_locale=
+lt_safe_locale=
+for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+do
+  eval "if test \"\${$lt_var+set}\" = set; then
+          save_$lt_var=\$$lt_var
+          $lt_var=C
+	  export $lt_var
+	  lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\"
+	  lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
+	fi"
+done
+
+$lt_unset CDPATH
+
+
+
+
+
+: ${CP="cp -f"}
+: ${ECHO="echo"}
+: ${EGREP="/bin/grep -E"}
+: ${FGREP="/bin/grep -F"}
+: ${GREP="/bin/grep"}
+: ${LN_S="ln -s"}
+: ${MAKE="make"}
+: ${MKDIR="mkdir"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+: ${SED="/bin/sed"}
+: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
+: ${Xsed="$SED -e 1s/^X//"}
+
+# Global variables:
+EXIT_SUCCESS=0
+EXIT_FAILURE=1
+EXIT_MISMATCH=63  # $? = 63 is used to indicate version mismatch to missing.
+EXIT_SKIP=77	  # $? = 77 is used to indicate a skipped test to automake.
+
+exit_status=$EXIT_SUCCESS
+
+# Make sure IFS has a sensible default
+lt_nl='
+'
+IFS=" 	$lt_nl"
+
+dirname="s,/[^/]*$,,"
+basename="s,^.*/,,"
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+# Generated shell functions inserted here.
+
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
+
+# The name of this program:
+# In the unlikely event $progname began with a '-', it would play havoc with
+# func_echo (imagine progname=-n), so we prepend ./ in that case:
+func_dirname_and_basename "$progpath"
+progname=$func_basename_result
+case $progname in
+  -*) progname=./$progname ;;
+esac
+
+# Make sure we have an absolute path for reexecution:
+case $progpath in
+  [\\/]*|[A-Za-z]:\\*) ;;
+  *[\\/]*)
+     progdir=$func_dirname_result
+     progdir=`cd "$progdir" && pwd`
+     progpath="$progdir/$progname"
+     ;;
+  *)
+     save_IFS="$IFS"
+     IFS=:
+     for progdir in $PATH; do
+       IFS="$save_IFS"
+       test -x "$progdir/$progname" && break
+     done
+     IFS="$save_IFS"
+     test -n "$progdir" || progdir=`pwd`
+     progpath="$progdir/$progname"
+     ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed="${SED}"' -e 1s/^X//'
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Re-`\' parameter expansions in output of double_quote_subst that were
+# `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
+# in input to double_quote_subst, that '$' was protected from expansion.
+# Since each input `\' is now two `\'s, look for any number of runs of
+# four `\'s followed by two `\'s and then a '$'.  `\' that '$'.
+bs='\\'
+bs2='\\\\'
+bs4='\\\\\\\\'
+dollar='\$'
+sed_double_backslash="\
+  s/$bs4/&\\
+/g
+  s/^$bs2$dollar/$bs&/
+  s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g
+  s/\n//g"
+
+# Standard options:
+opt_dry_run=false
+opt_help=false
+opt_quiet=false
+opt_verbose=false
+opt_warning=:
+
+# func_echo arg...
+# Echo program name prefixed message, along with the current mode
+# name if it has been set yet.
+func_echo ()
+{
+    $ECHO "$progname${mode+: }$mode: $*"
+}
+
+# func_verbose arg...
+# Echo program name prefixed message in verbose mode only.
+func_verbose ()
+{
+    $opt_verbose && func_echo ${1+"$@"}
+
+    # A bug in bash halts the script if the last line of a function
+    # fails when set -e is in force, so we need another command to
+    # work around that:
+    :
+}
+
+# func_error arg...
+# Echo program name prefixed message to standard error.
+func_error ()
+{
+    $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+}
+
+# func_warning arg...
+# Echo program name prefixed warning message to standard error.
+func_warning ()
+{
+    $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+
+    # bash bug again:
+    :
+}
+
+# func_fatal_error arg...
+# Echo program name prefixed message to standard error, and exit.
+func_fatal_error ()
+{
+    func_error ${1+"$@"}
+    exit $EXIT_FAILURE
+}
+
+# func_fatal_help arg...
+# Echo program name prefixed message to standard error, followed by
+# a help hint, and exit.
+func_fatal_help ()
+{
+    func_error ${1+"$@"}
+    func_fatal_error "$help"
+}
+help="Try \`$progname --help' for more information."  ## default
+
+
+# func_grep expression filename
+# Check whether EXPRESSION matches any line of FILENAME, without output.
+func_grep ()
+{
+    $GREP "$1" "$2" >/dev/null 2>&1
+}
+
+
+# func_mkdir_p directory-path
+# Make sure the entire path to DIRECTORY-PATH is available.
+func_mkdir_p ()
+{
+    my_directory_path="$1"
+    my_dir_list=
+
+    if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then
+
+      # Protect directory names starting with `-'
+      case $my_directory_path in
+        -*) my_directory_path="./$my_directory_path" ;;
+      esac
+
+      # While some portion of DIR does not yet exist...
+      while test ! -d "$my_directory_path"; do
+        # ...make a list in topmost first order.  Use a colon delimited
+	# list incase some portion of path contains whitespace.
+        my_dir_list="$my_directory_path:$my_dir_list"
+
+        # If the last portion added has no slash in it, the list is done
+        case $my_directory_path in */*) ;; *) break ;; esac
+
+        # ...otherwise throw away the child directory and loop
+        my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+      done
+      my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+
+      save_mkdir_p_IFS="$IFS"; IFS=':'
+      for my_dir in $my_dir_list; do
+	IFS="$save_mkdir_p_IFS"
+        # mkdir can fail with a `File exist' error if two processes
+        # try to create one of the directories concurrently.  Don't
+        # stop in that case!
+        $MKDIR "$my_dir" 2>/dev/null || :
+      done
+      IFS="$save_mkdir_p_IFS"
+
+      # Bail out if we (or some other process) failed to create a directory.
+      test -d "$my_directory_path" || \
+        func_fatal_error "Failed to create \`$1'"
+    fi
+}
+
+
+# func_mktempdir [string]
+# Make a temporary directory that won't clash with other running
+# libtool processes, and avoids race conditions if possible.  If
+# given, STRING is the basename for that directory.
+func_mktempdir ()
+{
+    my_template="${TMPDIR-/tmp}/${1-$progname}"
+
+    if test "$opt_dry_run" = ":"; then
+      # Return a directory name, but don't create it in dry-run mode
+      my_tmpdir="${my_template}-$$"
+    else
+
+      # If mktemp works, use that first and foremost
+      my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null`
+
+      if test ! -d "$my_tmpdir"; then
+        # Failing that, at least try and use $RANDOM to avoid a race
+        my_tmpdir="${my_template}-${RANDOM-0}$$"
+
+        save_mktempdir_umask=`umask`
+        umask 0077
+        $MKDIR "$my_tmpdir"
+        umask $save_mktempdir_umask
+      fi
+
+      # If we're not in dry-run mode, bomb out on failure
+      test -d "$my_tmpdir" || \
+        func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
+    fi
+
+    $ECHO "X$my_tmpdir" | $Xsed
+}
+
+
+# func_quote_for_eval arg
+# Aesthetically quote ARG to be evaled later.
+# This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT
+# is double-quoted, suitable for a subsequent eval, whereas
+# FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters
+# which are still active within double quotes backslashified.
+func_quote_for_eval ()
+{
+    case $1 in
+      *[\\\`\"\$]*)
+	func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+      *)
+        func_quote_for_eval_unquoted_result="$1" ;;
+    esac
+
+    case $func_quote_for_eval_unquoted_result in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting, command substitution and and variable
+      # expansion for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\""
+        ;;
+      *)
+        func_quote_for_eval_result="$func_quote_for_eval_unquoted_result"
+    esac
+}
+
+
+# func_quote_for_expand arg
+# Aesthetically quote ARG to be evaled later; same as above,
+# but do not quote variable references.
+func_quote_for_expand ()
+{
+    case $1 in
+      *[\\\`\"]*)
+	my_arg=`$ECHO "X$1" | $Xsed \
+	    -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
+      *)
+        my_arg="$1" ;;
+    esac
+
+    case $my_arg in
+      # Double-quote args containing shell metacharacters to delay
+      # word splitting and command substitution for a subsequent eval.
+      # Many Bourne shells cannot handle close brackets correctly
+      # in scan sets, so we specify it separately.
+      *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \	]*|*]*|"")
+        my_arg="\"$my_arg\""
+        ;;
+    esac
+
+    func_quote_for_expand_result="$my_arg"
+}
+
+
+# func_show_eval cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.
+func_show_eval ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$my_cmd"
+      my_status=$?
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+# func_show_eval_locale cmd [fail_exp]
+# Unless opt_silent is true, then output CMD.  Then, if opt_dryrun is
+# not true, evaluate CMD.  If the evaluation of CMD fails, and FAIL_EXP
+# is given, then evaluate it.  Use the saved locale for evaluation.
+func_show_eval_locale ()
+{
+    my_cmd="$1"
+    my_fail_exp="${2-:}"
+
+    ${opt_silent-false} || {
+      func_quote_for_expand "$my_cmd"
+      eval "func_echo $func_quote_for_expand_result"
+    }
+
+    if ${opt_dry_run-false}; then :; else
+      eval "$lt_user_locale
+	    $my_cmd"
+      my_status=$?
+      eval "$lt_safe_locale"
+      if test "$my_status" -eq 0; then :; else
+	eval "(exit $my_status); $my_fail_exp"
+      fi
+    fi
+}
+
+
+
+
+
+# func_version
+# Echo version message to standard output and exit.
+func_version ()
+{
+    $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+        s/^# //
+	s/^# *$//
+        s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
+        p
+     }' < "$progpath"
+     exit $?
+}
+
+# func_usage
+# Echo short help message to standard output and exit.
+func_usage ()
+{
+    $SED -n '/^# Usage:/,/# -h/ {
+        s/^# //
+	s/^# *$//
+	s/\$progname/'$progname'/
+	p
+    }' < "$progpath"
+    $ECHO
+    $ECHO "run \`$progname --help | more' for full usage"
+    exit $?
+}
+
+# func_help
+# Echo long help message to standard output and exit.
+func_help ()
+{
+    $SED -n '/^# Usage:/,/# Report bugs to/ {
+        s/^# //
+	s/^# *$//
+	s*\$progname*'$progname'*
+	s*\$host*'"$host"'*
+	s*\$SHELL*'"$SHELL"'*
+	s*\$LTCC*'"$LTCC"'*
+	s*\$LTCFLAGS*'"$LTCFLAGS"'*
+	s*\$LD*'"$LD"'*
+	s/\$with_gnu_ld/'"$with_gnu_ld"'/
+	s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
+	s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+	p
+     }' < "$progpath"
+    exit $?
+}
+
+# func_missing_arg argname
+# Echo program name prefixed message to standard error and set global
+# exit_cmd.
+func_missing_arg ()
+{
+    func_error "missing argument for $1"
+    exit_cmd=exit
+}
+
+exit_cmd=:
+
+
+
+
+
+# Check that we have a working $ECHO.
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell, and then maybe $ECHO will work.
+  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<EOF
+$*
+EOF
+  exit $EXIT_SUCCESS
+fi
+
+magic="%%%MAGIC variable%%%"
+magic_exe="%%%MAGIC EXE variable%%%"
+
+# Global variables.
+# $mode is unset
+nonopt=
+execute_dlfiles=
+preserve_args=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+extracted_archives=
+extracted_serial=0
+
+opt_dry_run=false
+opt_duplicate_deps=false
+opt_silent=false
+opt_debug=:
+
+# If this variable is set in any of the actions, the command in it
+# will be execed at the end.  This prevents here-documents from being
+# left over by shells.
+exec_cmd=
+
+# func_fatal_configuration arg...
+# Echo program name prefixed message to standard error, followed by
+# a configuration failure hint, and exit.
+func_fatal_configuration ()
+{
+    func_error ${1+"$@"}
+    func_error "See the $PACKAGE documentation for more information."
+    func_fatal_error "Fatal configuration error."
+}
+
+
+# func_config
+# Display the configuration for all the tags in this script.
+func_config ()
+{
+    re_begincf='^# ### BEGIN LIBTOOL'
+    re_endcf='^# ### END LIBTOOL'
+
+    # Default configuration.
+    $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath"
+
+    # Now print the configurations for the tags.
+    for tagname in $taglist; do
+      $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath"
+    done
+
+    exit $?
+}
+
+# func_features
+# Display the features supported by this script.
+func_features ()
+{
+    $ECHO "host: $host"
+    if test "$build_libtool_libs" = yes; then
+      $ECHO "enable shared libraries"
+    else
+      $ECHO "disable shared libraries"
+    fi
+    if test "$build_old_libs" = yes; then
+      $ECHO "enable static libraries"
+    else
+      $ECHO "disable static libraries"
+    fi
+
+    exit $?
+}
+
+# func_enable_tag tagname
+# Verify that TAGNAME is valid, and either flag an error and exit, or
+# enable the TAGNAME tag.  We also add TAGNAME to the global $taglist
+# variable here.
+func_enable_tag ()
+{
+  # Global variable:
+  tagname="$1"
+
+  re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$"
+  re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$"
+  sed_extractcf="/$re_begincf/,/$re_endcf/p"
+
+  # Validate tagname.
+  case $tagname in
+    *[!-_A-Za-z0-9,/]*)
+      func_fatal_error "invalid tag name: $tagname"
+      ;;
+  esac
+
+  # Don't test for the "default" C tag, as we know it's
+  # there but not specially marked.
+  case $tagname in
+    CC) ;;
+    *)
+      if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then
+	taglist="$taglist $tagname"
+
+	# Evaluate the configuration.  Be careful to quote the path
+	# and the sed script, to avoid splitting on whitespace, but
+	# also don't use non-portable quotes within backquotes within
+	# quotes we have to do it in 2 steps:
+	extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"`
+	eval "$extractedcf"
+      else
+	func_error "ignoring unknown tag $tagname"
+      fi
+      ;;
+  esac
+}
+
+# Parse options once, thoroughly.  This comes as soon as possible in
+# the script to make things like `libtool --version' happen quickly.
+{
+
+  # Shorthand for --mode=foo, only valid as the first argument
+  case $1 in
+  clean|clea|cle|cl)
+    shift; set dummy --mode clean ${1+"$@"}; shift
+    ;;
+  compile|compil|compi|comp|com|co|c)
+    shift; set dummy --mode compile ${1+"$@"}; shift
+    ;;
+  execute|execut|execu|exec|exe|ex|e)
+    shift; set dummy --mode execute ${1+"$@"}; shift
+    ;;
+  finish|finis|fini|fin|fi|f)
+    shift; set dummy --mode finish ${1+"$@"}; shift
+    ;;
+  install|instal|insta|inst|ins|in|i)
+    shift; set dummy --mode install ${1+"$@"}; shift
+    ;;
+  link|lin|li|l)
+    shift; set dummy --mode link ${1+"$@"}; shift
+    ;;
+  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+    shift; set dummy --mode uninstall ${1+"$@"}; shift
+    ;;
+  esac
+
+  # Parse non-mode specific arguments:
+  while test "$#" -gt 0; do
+    opt="$1"
+    shift
+
+    case $opt in
+      --config)		func_config					;;
+
+      --debug)		preserve_args="$preserve_args $opt"
+			func_echo "enabling shell trace mode"
+			opt_debug='set -x'
+			$opt_debug
+			;;
+
+      -dlopen)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+			execute_dlfiles="$execute_dlfiles $1"
+			shift
+			;;
+
+      --dry-run | -n)	opt_dry_run=:					;;
+      --features)       func_features					;;
+      --finish)		mode="finish"					;;
+
+      --mode)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+			case $1 in
+			  # Valid mode arguments:
+			  clean)	;;
+			  compile)	;;
+			  execute)	;;
+			  finish)	;;
+			  install)	;;
+			  link)		;;
+			  relink)	;;
+			  uninstall)	;;
+
+			  # Catch anything else as an error
+			  *) func_error "invalid argument for $opt"
+			     exit_cmd=exit
+			     break
+			     ;;
+		        esac
+
+			mode="$1"
+			shift
+			;;
+
+      --preserve-dup-deps)
+			opt_duplicate_deps=:				;;
+
+      --quiet|--silent)	preserve_args="$preserve_args $opt"
+			opt_silent=:
+			;;
+
+      --verbose| -v)	preserve_args="$preserve_args $opt"
+			opt_silent=false
+			;;
+
+      --tag)		test "$#" -eq 0 && func_missing_arg "$opt" && break
+			preserve_args="$preserve_args $opt $1"
+			func_enable_tag "$1"	# tagname is set here
+			shift
+			;;
+
+      # Separate optargs to long options:
+      -dlopen=*|--mode=*|--tag=*)
+			func_opt_split "$opt"
+			set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+			shift
+			;;
+
+      -\?|-h)		func_usage					;;
+      --help)		opt_help=:					;;
+      --version)	func_version					;;
+
+      -*)		func_fatal_help "unrecognized option \`$opt'"	;;
+
+      *)		nonopt="$opt"
+			break
+			;;
+    esac
+  done
+
+
+  case $host in
+    *cygwin* | *mingw* | *pw32* | *cegcc*)
+      # don't eliminate duplications in $postdeps and $predeps
+      opt_duplicate_compiler_generated_deps=:
+      ;;
+    *)
+      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+      ;;
+  esac
+
+  # Having warned about all mis-specified options, bail out if
+  # anything was wrong.
+  $exit_cmd $EXIT_FAILURE
+}
+
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
+{
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+## ----------- ##
+##    Main.    ##
+## ----------- ##
+
+$opt_help || {
+  # Sanity checks first:
+  func_check_version_match
+
+  if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+    func_fatal_configuration "not configured to build any kind of library"
+  fi
+
+  test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+
+
+  # Darwin sucks
+  eval std_shrext=\"$shrext_cmds\"
+
+
+  # Only execute mode is allowed to have -dlopen flags.
+  if test -n "$execute_dlfiles" && test "$mode" != execute; then
+    func_error "unrecognized option \`-dlopen'"
+    $ECHO "$help" 1>&2
+    exit $EXIT_FAILURE
+  fi
+
+  # Change the help message to a mode-specific one.
+  generic_help="$help"
+  help="Try \`$progname --help --mode=$mode' for more information."
+}
+
+
+# func_lalib_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_lalib_p ()
+{
+    test -f "$1" &&
+      $SED -e 4q "$1" 2>/dev/null \
+        | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1
+}
+
+# func_lalib_unsafe_p file
+# True iff FILE is a libtool `.la' library or `.lo' object file.
+# This function implements the same check as func_lalib_p without
+# resorting to external programs.  To this end, it redirects stdin and
+# closes it afterwards, without saving the original file descriptor.
+# As a safety measure, use it only where a negative result would be
+# fatal anyway.  Works if `file' does not exist.
+func_lalib_unsafe_p ()
+{
+    lalib_p=no
+    if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then
+	for lalib_p_l in 1 2 3 4
+	do
+	    read lalib_p_line
+	    case "$lalib_p_line" in
+		\#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;;
+	    esac
+	done
+	exec 0<&5 5<&-
+    fi
+    test "$lalib_p" = yes
+}
+
+# func_ltwrapper_script_p file
+# True iff FILE is a libtool wrapper script
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_script_p ()
+{
+    func_lalib_p "$1"
+}
+
+# func_ltwrapper_executable_p file
+# True iff FILE is a libtool wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_executable_p ()
+{
+    func_ltwrapper_exec_suffix=
+    case $1 in
+    *.exe) ;;
+    *) func_ltwrapper_exec_suffix=.exe ;;
+    esac
+    $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1
+}
+
+# func_ltwrapper_scriptname file
+# Assumes file is an ltwrapper_executable
+# uses $file to determine the appropriate filename for a
+# temporary ltwrapper_script.
+func_ltwrapper_scriptname ()
+{
+    func_ltwrapper_scriptname_result=""
+    if func_ltwrapper_executable_p "$1"; then
+	func_dirname_and_basename "$1" "" "."
+	func_stripname '' '.exe' "$func_basename_result"
+	func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
+    fi
+}
+
+# func_ltwrapper_p file
+# True iff FILE is a libtool wrapper script or wrapper executable
+# This function is only a basic sanity check; it will hardly flush out
+# determined imposters.
+func_ltwrapper_p ()
+{
+    func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1"
+}
+
+
+# func_execute_cmds commands fail_cmd
+# Execute tilde-delimited COMMANDS.
+# If FAIL_CMD is given, eval that upon failure.
+# FAIL_CMD may read-access the current command in variable CMD!
+func_execute_cmds ()
+{
+    $opt_debug
+    save_ifs=$IFS; IFS='~'
+    for cmd in $1; do
+      IFS=$save_ifs
+      eval cmd=\"$cmd\"
+      func_show_eval "$cmd" "${2-:}"
+    done
+    IFS=$save_ifs
+}
+
+
+# func_source file
+# Source FILE, adding directory component if necessary.
+# Note that it is not necessary on cygwin/mingw to append a dot to
+# FILE even if both FILE and FILE.exe exist: automatic-append-.exe
+# behavior happens only for exec(3), not for open(2)!  Also, sourcing
+# `FILE.' does not work on cygwin managed mounts.
+func_source ()
+{
+    $opt_debug
+    case $1 in
+    */* | *\\*)	. "$1" ;;
+    *)		. "./$1" ;;
+    esac
+}
+
+
+# func_infer_tag arg
+# Infer tagged configuration to use if any are available and
+# if one wasn't chosen via the "--tag" command line option.
+# Only attempt this if the compiler in the base compile
+# command doesn't match the default compiler.
+# arg is usually of the form 'gcc ...'
+func_infer_tag ()
+{
+    $opt_debug
+    if test -n "$available_tags" && test -z "$tagname"; then
+      CC_quoted=
+      for arg in $CC; do
+        func_quote_for_eval "$arg"
+	CC_quoted="$CC_quoted $func_quote_for_eval_result"
+      done
+      case $@ in
+      # Blanks in the command may have been stripped by the calling shell,
+      # but not from the CC environment variable when configure was run.
+      " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+      # Blanks at the start of $base_compile will cause this to fail
+      # if we don't check for them as well.
+      *)
+	for z in $available_tags; do
+	  if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then
+	    # Evaluate the configuration.
+	    eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`"
+	    CC_quoted=
+	    for arg in $CC; do
+	      # Double-quote args containing other shell metacharacters.
+	      func_quote_for_eval "$arg"
+	      CC_quoted="$CC_quoted $func_quote_for_eval_result"
+	    done
+	    case "$@ " in
+	      " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+	      # The compiler in the base compile command matches
+	      # the one in the tagged configuration.
+	      # Assume this is the tagged configuration we want.
+	      tagname=$z
+	      break
+	      ;;
+	    esac
+	  fi
+	done
+	# If $tagname still isn't set, then no tagged configuration
+	# was found and let the user know that the "--tag" command
+	# line option must be used.
+	if test -z "$tagname"; then
+	  func_echo "unable to infer tagged configuration"
+	  func_fatal_error "specify a tag with \`--tag'"
+#	else
+#	  func_verbose "using $tagname tagged configuration"
+	fi
+	;;
+      esac
+    fi
+}
+
+
+
+# func_write_libtool_object output_name pic_name nonpic_name
+# Create a libtool object file (analogous to a ".la" file),
+# but don't create it if we're doing a dry run.
+func_write_libtool_object ()
+{
+    write_libobj=${1}
+    if test "$build_libtool_libs" = yes; then
+      write_lobj=\'${2}\'
+    else
+      write_lobj=none
+    fi
+
+    if test "$build_old_libs" = yes; then
+      write_oldobj=\'${3}\'
+    else
+      write_oldobj=none
+    fi
+
+    $opt_dry_run || {
+      cat >${write_libobj}T <<EOF
+# $write_libobj - a libtool object file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# Name of the PIC object.
+pic_object=$write_lobj
+
+# Name of the non-PIC object
+non_pic_object=$write_oldobj
+
+EOF
+      $MV "${write_libobj}T" "${write_libobj}"
+    }
+}
+
+# func_mode_compile arg...
+func_mode_compile ()
+{
+    $opt_debug
+    # Get the compilation command and the source file.
+    base_compile=
+    srcfile="$nonopt"  #  always keep a non-empty value in "srcfile"
+    suppress_opt=yes
+    suppress_output=
+    arg_mode=normal
+    libobj=
+    later=
+    pie_flag=
+
+    for arg
+    do
+      case $arg_mode in
+      arg  )
+	# do not "continue".  Instead, add this to base_compile
+	lastarg="$arg"
+	arg_mode=normal
+	;;
+
+      target )
+	libobj="$arg"
+	arg_mode=normal
+	continue
+	;;
+
+      normal )
+	# Accept any command-line options.
+	case $arg in
+	-o)
+	  test -n "$libobj" && \
+	    func_fatal_error "you cannot specify \`-o' more than once"
+	  arg_mode=target
+	  continue
+	  ;;
+
+	-pie | -fpie | -fPIE)
+          pie_flag="$pie_flag $arg"
+	  continue
+	  ;;
+
+	-shared | -static | -prefer-pic | -prefer-non-pic)
+	  later="$later $arg"
+	  continue
+	  ;;
+
+	-no-suppress)
+	  suppress_opt=no
+	  continue
+	  ;;
+
+	-Xcompiler)
+	  arg_mode=arg  #  the next one goes into the "base_compile" arg list
+	  continue      #  The current "srcfile" will either be retained or
+	  ;;            #  replaced later.  I would guess that would be a bug.
+
+	-Wc,*)
+	  func_stripname '-Wc,' '' "$arg"
+	  args=$func_stripname_result
+	  lastarg=
+	  save_ifs="$IFS"; IFS=','
+	  for arg in $args; do
+	    IFS="$save_ifs"
+	    func_quote_for_eval "$arg"
+	    lastarg="$lastarg $func_quote_for_eval_result"
+	  done
+	  IFS="$save_ifs"
+	  func_stripname ' ' '' "$lastarg"
+	  lastarg=$func_stripname_result
+
+	  # Add the arguments to base_compile.
+	  base_compile="$base_compile $lastarg"
+	  continue
+	  ;;
+
+	*)
+	  # Accept the current argument as the source file.
+	  # The previous "srcfile" becomes the current argument.
+	  #
+	  lastarg="$srcfile"
+	  srcfile="$arg"
+	  ;;
+	esac  #  case $arg
+	;;
+      esac    #  case $arg_mode
+
+      # Aesthetically quote the previous argument.
+      func_quote_for_eval "$lastarg"
+      base_compile="$base_compile $func_quote_for_eval_result"
+    done # for arg
+
+    case $arg_mode in
+    arg)
+      func_fatal_error "you must specify an argument for -Xcompile"
+      ;;
+    target)
+      func_fatal_error "you must specify a target with \`-o'"
+      ;;
+    *)
+      # Get the name of the library object.
+      test -z "$libobj" && {
+	func_basename "$srcfile"
+	libobj="$func_basename_result"
+      }
+      ;;
+    esac
+
+    # Recognize several different file suffixes.
+    # If the user specifies -o file.o, it is replaced with file.lo
+    case $libobj in
+    *.[cCFSifmso] | \
+    *.ada | *.adb | *.ads | *.asm | \
+    *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
+    *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+      func_xform "$libobj"
+      libobj=$func_xform_result
+      ;;
+    esac
+
+    case $libobj in
+    *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;;
+    *)
+      func_fatal_error "cannot determine name of library object from \`$libobj'"
+      ;;
+    esac
+
+    func_infer_tag $base_compile
+
+    for arg in $later; do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	continue
+	;;
+
+      -static)
+	build_libtool_libs=no
+	build_old_libs=yes
+	continue
+	;;
+
+      -prefer-pic)
+	pic_mode=yes
+	continue
+	;;
+
+      -prefer-non-pic)
+	pic_mode=no
+	continue
+	;;
+      esac
+    done
+
+    func_quote_for_eval "$libobj"
+    test "X$libobj" != "X$func_quote_for_eval_result" \
+      && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"'	 &()|`$[]' \
+      && func_warning "libobj name \`$libobj' may not contain shell special characters."
+    func_dirname_and_basename "$obj" "/" ""
+    objname="$func_basename_result"
+    xdir="$func_dirname_result"
+    lobj=${xdir}$objdir/$objname
+
+    test -z "$base_compile" && \
+      func_fatal_help "you must specify a compilation command"
+
+    # Delete any leftover library objects.
+    if test "$build_old_libs" = yes; then
+      removelist="$obj $lobj $libobj ${libobj}T"
+    else
+      removelist="$lobj $libobj ${libobj}T"
+    fi
+
+    # On Cygwin there's no "real" PIC flag so we must build both object types
+    case $host_os in
+    cygwin* | mingw* | pw32* | os2* | cegcc*)
+      pic_mode=default
+      ;;
+    esac
+    if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then
+      # non-PIC code in shared libraries is not supported
+      pic_mode=default
+    fi
+
+    # Calculate the filename of the output object if compiler does
+    # not support -o with -c
+    if test "$compiler_c_o" = no; then
+      output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      lockfile="$output_obj.lock"
+    else
+      output_obj=
+      need_locks=no
+      lockfile=
+    fi
+
+    # Lock this critical section if it is needed
+    # We use this script file to make the link, it avoids creating a new file
+    if test "$need_locks" = yes; then
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+	func_echo "Waiting for $lockfile to be removed"
+	sleep 2
+      done
+    elif test "$need_locks" = warn; then
+      if test -f "$lockfile"; then
+	$ECHO "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+      removelist="$removelist $output_obj"
+      $ECHO "$srcfile" > "$lockfile"
+    fi
+
+    $opt_dry_run || $RM $removelist
+    removelist="$removelist $lockfile"
+    trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
+
+    if test -n "$fix_srcfile_path"; then
+      eval srcfile=\"$fix_srcfile_path\"
+    fi
+    func_quote_for_eval "$srcfile"
+    qsrcfile=$func_quote_for_eval_result
+
+    # Only build a PIC object if we are building libtool libraries.
+    if test "$build_libtool_libs" = yes; then
+      # Without this assignment, base_compile gets emptied.
+      fbsd_hideous_sh_bug=$base_compile
+
+      if test "$pic_mode" != no; then
+	command="$base_compile $qsrcfile $pic_flag"
+      else
+	# Don't build PIC code
+	command="$base_compile $qsrcfile"
+      fi
+
+      func_mkdir_p "$xdir$objdir"
+
+      if test -z "$output_obj"; then
+	# Place PIC objects in $objdir
+	command="$command -o $lobj"
+      fi
+
+      func_show_eval_locale "$command"	\
+          'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed, then go on to compile the next one
+      if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then
+	func_show_eval '$MV "$output_obj" "$lobj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+
+      # Allow error messages only from the first compilation.
+      if test "$suppress_opt" = yes; then
+	suppress_output=' >/dev/null 2>&1'
+      fi
+    fi
+
+    # Only build a position-dependent object if we build old libraries.
+    if test "$build_old_libs" = yes; then
+      if test "$pic_mode" != yes; then
+	# Don't build PIC code
+	command="$base_compile $qsrcfile$pie_flag"
+      else
+	command="$base_compile $qsrcfile $pic_flag"
+      fi
+      if test "$compiler_c_o" = yes; then
+	command="$command -o $obj"
+      fi
+
+      # Suppress compiler output if we already did a PIC compilation.
+      command="$command$suppress_output"
+      func_show_eval_locale "$command" \
+        '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
+
+      if test "$need_locks" = warn &&
+	 test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then
+	$ECHO "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together.  If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+	$opt_dry_run || $RM $removelist
+	exit $EXIT_FAILURE
+      fi
+
+      # Just move the object if needed
+      if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then
+	func_show_eval '$MV "$output_obj" "$obj"' \
+	  'error=$?; $opt_dry_run || $RM $removelist; exit $error'
+      fi
+    fi
+
+    $opt_dry_run || {
+      func_write_libtool_object "$libobj" "$objdir/$objname" "$objname"
+
+      # Unlock the critical section if it was locked
+      if test "$need_locks" != no; then
+	removelist=$lockfile
+        $RM "$lockfile"
+      fi
+    }
+
+    exit $EXIT_SUCCESS
+}
+
+$opt_help || {
+test "$mode" = compile && func_mode_compile ${1+"$@"}
+}
+
+func_mode_help ()
+{
+    # We need to display help for each of the modes.
+    case $mode in
+      "")
+        # Generic help is extracted from the usage comments
+        # at the start of this file.
+        func_help
+        ;;
+
+      clean)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE...
+
+Remove files from the build directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, object or program, all the files associated
+with it are deleted. Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      compile)
+      $ECHO \
+"Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+  -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
+  -no-suppress      do not suppress compiler output for multiple passes
+  -prefer-pic       try to building PIC objects only
+  -prefer-non-pic   try to building non-PIC objects only
+  -shared           do not build a \`.o' file suitable for static linking
+  -static           only build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+        ;;
+
+      execute)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+  -dlopen FILE      add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+        ;;
+
+      finish)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges.  Use
+the \`--dry-run' option if you just want to see what would be executed."
+        ;;
+
+      install)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command.  The first component should be
+either the \`install' or \`cp' program.
+
+The following components of INSTALL-COMMAND are treated specially:
+
+  -inst-prefix PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+        ;;
+
+      link)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+  -all-static       do not do any dynamic linking at all
+  -avoid-version    do not add a version suffix if possible
+  -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
+  -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
+  -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+  -export-symbols SYMFILE
+                    try to export only the symbols listed in SYMFILE
+  -export-symbols-regex REGEX
+                    try to export only the symbols matching REGEX
+  -LLIBDIR          search LIBDIR for required installed libraries
+  -lNAME            OUTPUT-FILE requires the installed library libNAME
+  -module           build a library that can dlopened
+  -no-fast-install  disable the fast-install mode
+  -no-install       link a not-installable executable
+  -no-undefined     declare that a library does not refer to external symbols
+  -o OUTPUT-FILE    create OUTPUT-FILE from the specified objects
+  -objectlist FILE  Use a list of object files found in FILE to specify objects
+  -precious-files-regex REGEX
+                    don't remove output files matching REGEX
+  -release RELEASE  specify package release information
+  -rpath LIBDIR     the created library will eventually be installed in LIBDIR
+  -R[ ]LIBDIR       add LIBDIR to the runtime path of programs and libraries
+  -shared           only do dynamic linking of libtool libraries
+  -shrext SUFFIX    override the standard shared library file extension
+  -static           do not do any dynamic linking of uninstalled libtool libraries
+  -static-libtool-libs
+                    do not do any dynamic linking of libtool libraries
+  -version-info CURRENT[:REVISION[:AGE]]
+                    specify library version info [each variable defaults to 0]
+  -weak LIBNAME     declare that the target provides the LIBNAME interface
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename.  Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+        ;;
+
+      uninstall)
+        $ECHO \
+"Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm').  RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+        ;;
+
+      *)
+        func_fatal_help "invalid operation mode \`$mode'"
+        ;;
+    esac
+
+    $ECHO
+    $ECHO "Try \`$progname --help' for more information about other modes."
+
+    exit $?
+}
+
+  # Now that we've collected a possible --mode arg, show help if necessary
+  $opt_help && func_mode_help
+
+
+# func_mode_execute arg...
+func_mode_execute ()
+{
+    $opt_debug
+    # The first argument is the command name.
+    cmd="$nonopt"
+    test -z "$cmd" && \
+      func_fatal_help "you must specify a COMMAND"
+
+    # Handle -dlopen flags immediately.
+    for file in $execute_dlfiles; do
+      test -f "$file" \
+	|| func_fatal_help "\`$file' is not a file"
+
+      dir=
+      case $file in
+      *.la)
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$lib' is not a valid libtool archive"
+
+	# Read the libtool library.
+	dlname=
+	library_names=
+	func_source "$file"
+
+	# Skip this library if it cannot be dlopened.
+	if test -z "$dlname"; then
+	  # Warn if it was a shared library.
+	  test -n "$library_names" && \
+	    func_warning "\`$file' was not linked with \`-export-dynamic'"
+	  continue
+	fi
+
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+
+	if test -f "$dir/$objdir/$dlname"; then
+	  dir="$dir/$objdir"
+	else
+	  if test ! -f "$dir/$dlname"; then
+	    func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
+	  fi
+	fi
+	;;
+
+      *.lo)
+	# Just add the directory containing the .lo file.
+	func_dirname "$file" "" "."
+	dir="$func_dirname_result"
+	;;
+
+      *)
+	func_warning "\`-dlopen' is ignored for non-libtool libraries and objects"
+	continue
+	;;
+      esac
+
+      # Get the absolute pathname.
+      absdir=`cd "$dir" && pwd`
+      test -n "$absdir" && dir="$absdir"
+
+      # Now add the directory to shlibpath_var.
+      if eval "test -z \"\$$shlibpath_var\""; then
+	eval "$shlibpath_var=\"\$dir\""
+      else
+	eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+      fi
+    done
+
+    # This variable tells wrapper scripts just to set shlibpath_var
+    # rather than running their programs.
+    libtool_execute_magic="$magic"
+
+    # Check if any of the arguments is a wrapper script.
+    args=
+    for file
+    do
+      case $file in
+      -*) ;;
+      *)
+	# Do a test to see if this is really a libtool program.
+	if func_ltwrapper_script_p "$file"; then
+	  func_source "$file"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	elif func_ltwrapper_executable_p "$file"; then
+	  func_ltwrapper_scriptname "$file"
+	  func_source "$func_ltwrapper_scriptname_result"
+	  # Transform arg to wrapped name.
+	  file="$progdir/$program"
+	fi
+	;;
+      esac
+      # Quote arguments (to preserve shell metacharacters).
+      func_quote_for_eval "$file"
+      args="$args $func_quote_for_eval_result"
+    done
+
+    if test "X$opt_dry_run" = Xfalse; then
+      if test -n "$shlibpath_var"; then
+	# Export the shlibpath_var.
+	eval "export $shlibpath_var"
+      fi
+
+      # Restore saved environment variables
+      for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
+      do
+	eval "if test \"\${save_$lt_var+set}\" = set; then
+                $lt_var=\$save_$lt_var; export $lt_var
+	      else
+		$lt_unset $lt_var
+	      fi"
+      done
+
+      # Now prepare to actually exec the command.
+      exec_cmd="\$cmd$args"
+    else
+      # Display what would be done.
+      if test -n "$shlibpath_var"; then
+	eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
+	$ECHO "export $shlibpath_var"
+      fi
+      $ECHO "$cmd$args"
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$mode" = execute && func_mode_execute ${1+"$@"}
+
+
+# func_mode_finish arg...
+func_mode_finish ()
+{
+    $opt_debug
+    libdirs="$nonopt"
+    admincmds=
+
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      for dir
+      do
+	libdirs="$libdirs $dir"
+      done
+
+      for libdir in $libdirs; do
+	if test -n "$finish_cmds"; then
+	  # Do each command in the finish commands.
+	  func_execute_cmds "$finish_cmds" 'admincmds="$admincmds
+'"$cmd"'"'
+	fi
+	if test -n "$finish_eval"; then
+	  # Do the single finish_eval.
+	  eval cmds=\"$finish_eval\"
+	  $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+       $cmds"
+	fi
+      done
+    fi
+
+    # Exit here if they wanted silent mode.
+    $opt_silent && exit $EXIT_SUCCESS
+
+    $ECHO "X----------------------------------------------------------------------" | $Xsed
+    $ECHO "Libraries have been installed in:"
+    for libdir in $libdirs; do
+      $ECHO "   $libdir"
+    done
+    $ECHO
+    $ECHO "If you ever happen to want to link against installed libraries"
+    $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
+    $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
+    $ECHO "flag during linking and do at least one of the following:"
+    if test -n "$shlibpath_var"; then
+      $ECHO "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+      $ECHO "     during execution"
+    fi
+    if test -n "$runpath_var"; then
+      $ECHO "   - add LIBDIR to the \`$runpath_var' environment variable"
+      $ECHO "     during linking"
+    fi
+    if test -n "$hardcode_libdir_flag_spec"; then
+      libdir=LIBDIR
+      eval flag=\"$hardcode_libdir_flag_spec\"
+
+      $ECHO "   - use the \`$flag' linker flag"
+    fi
+    if test -n "$admincmds"; then
+      $ECHO "   - have your system administrator run these commands:$admincmds"
+    fi
+    if test -f /etc/ld.so.conf; then
+      $ECHO "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+    fi
+    $ECHO
+
+    $ECHO "See any operating system documentation about shared libraries for"
+    case $host in
+      solaris2.[6789]|solaris2.1[0-9])
+        $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+	$ECHO "pages."
+	;;
+      *)
+        $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
+        ;;
+    esac
+    $ECHO "X----------------------------------------------------------------------" | $Xsed
+    exit $EXIT_SUCCESS
+}
+
+test "$mode" = finish && func_mode_finish ${1+"$@"}
+
+
+# func_mode_install arg...
+func_mode_install ()
+{
+    $opt_debug
+    # There may be an optional sh(1) argument at the beginning of
+    # install_prog (especially on Windows NT).
+    if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
+       # Allow the use of GNU shtool's install command.
+       $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+      # Aesthetically quote it.
+      func_quote_for_eval "$nonopt"
+      install_prog="$func_quote_for_eval_result "
+      arg=$1
+      shift
+    else
+      install_prog=
+      arg=$nonopt
+    fi
+
+    # The real first argument should be the name of the installation program.
+    # Aesthetically quote it.
+    func_quote_for_eval "$arg"
+    install_prog="$install_prog$func_quote_for_eval_result"
+
+    # We need to accept at least all the BSD install flags.
+    dest=
+    files=
+    opts=
+    prev=
+    install_type=
+    isdir=no
+    stripme=
+    for arg
+    do
+      if test -n "$dest"; then
+	files="$files $dest"
+	dest=$arg
+	continue
+      fi
+
+      case $arg in
+      -d) isdir=yes ;;
+      -f)
+	case " $install_prog " in
+	*[\\\ /]cp\ *) ;;
+	*) prev=$arg ;;
+	esac
+	;;
+      -g | -m | -o)
+	prev=$arg
+	;;
+      -s)
+	stripme=" -s"
+	continue
+	;;
+      -*)
+	;;
+      *)
+	# If the previous option needed an argument, then skip it.
+	if test -n "$prev"; then
+	  prev=
+	else
+	  dest=$arg
+	  continue
+	fi
+	;;
+      esac
+
+      # Aesthetically quote the argument.
+      func_quote_for_eval "$arg"
+      install_prog="$install_prog $func_quote_for_eval_result"
+    done
+
+    test -z "$install_prog" && \
+      func_fatal_help "you must specify an install program"
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prev' option requires an argument"
+
+    if test -z "$files"; then
+      if test -z "$dest"; then
+	func_fatal_help "no file or destination specified"
+      else
+	func_fatal_help "you must specify a destination"
+      fi
+    fi
+
+    # Strip any trailing slash from the destination.
+    func_stripname '' '/' "$dest"
+    dest=$func_stripname_result
+
+    # Check to see that the destination is a directory.
+    test -d "$dest" && isdir=yes
+    if test "$isdir" = yes; then
+      destdir="$dest"
+      destname=
+    else
+      func_dirname_and_basename "$dest" "" "."
+      destdir="$func_dirname_result"
+      destname="$func_basename_result"
+
+      # Not a directory, so check to see that there is only one file specified.
+      set dummy $files; shift
+      test "$#" -gt 1 && \
+	func_fatal_help "\`$dest' is not a directory"
+    fi
+    case $destdir in
+    [\\/]* | [A-Za-z]:[\\/]*) ;;
+    *)
+      for file in $files; do
+	case $file in
+	*.lo) ;;
+	*)
+	  func_fatal_help "\`$destdir' must be an absolute directory name"
+	  ;;
+	esac
+      done
+      ;;
+    esac
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    staticlibs=
+    future_libdirs=
+    current_libdirs=
+    for file in $files; do
+
+      # Do each installation.
+      case $file in
+      *.$libext)
+	# Do the static libraries later.
+	staticlibs="$staticlibs $file"
+	;;
+
+      *.la)
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$file" \
+	  || func_fatal_help "\`$file' is not a valid libtool archive"
+
+	library_names=
+	old_library=
+	relink_command=
+	func_source "$file"
+
+	# Add the libdir to current_libdirs if it is the destination.
+	if test "X$destdir" = "X$libdir"; then
+	  case "$current_libdirs " in
+	  *" $libdir "*) ;;
+	  *) current_libdirs="$current_libdirs $libdir" ;;
+	  esac
+	else
+	  # Note the libdir as a future libdir.
+	  case "$future_libdirs " in
+	  *" $libdir "*) ;;
+	  *) future_libdirs="$future_libdirs $libdir" ;;
+	  esac
+	fi
+
+	func_dirname "$file" "/" ""
+	dir="$func_dirname_result"
+	dir="$dir$objdir"
+
+	if test -n "$relink_command"; then
+	  # Determine the prefix the user has applied to our future dir.
+	  inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+
+	  # Don't allow the user to place us outside of our expected
+	  # location b/c this prevents finding dependent libraries that
+	  # are installed to the same prefix.
+	  # At present, this check doesn't affect windows .dll's that
+	  # are installed into $libdir/../bin (currently, that works fine)
+	  # but it's something to keep an eye on.
+	  test "$inst_prefix_dir" = "$destdir" && \
+	    func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir"
+
+	  if test -n "$inst_prefix_dir"; then
+	    # Stick the inst_prefix_dir data into the link command.
+	    relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+	  else
+	    relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+	  fi
+
+	  func_warning "relinking \`$file'"
+	  func_show_eval "$relink_command" \
+	    'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"'
+	fi
+
+	# See the names of the shared library.
+	set dummy $library_names; shift
+	if test -n "$1"; then
+	  realname="$1"
+	  shift
+
+	  srcname="$realname"
+	  test -n "$relink_command" && srcname="$realname"T
+
+	  # Install the shared library and build the symlinks.
+	  func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+	      'exit $?'
+	  tstripme="$stripme"
+	  case $host_os in
+	  cygwin* | mingw* | pw32* | cegcc*)
+	    case $realname in
+	    *.dll.a)
+	      tstripme=""
+	      ;;
+	    esac
+	    ;;
+	  esac
+	  if test -n "$tstripme" && test -n "$striplib"; then
+	    func_show_eval "$striplib $destdir/$realname" 'exit $?'
+	  fi
+
+	  if test "$#" -gt 0; then
+	    # Delete the old symlinks, and create new ones.
+	    # Try `ln -sf' first, because the `ln' binary might depend on
+	    # the symlink we replace!  Solaris /bin/ln does not understand -f,
+	    # so we also need to try rm && ln -s.
+	    for linkname
+	    do
+	      test "$linkname" != "$realname" \
+		&& func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })"
+	    done
+	  fi
+
+	  # Do each command in the postinstall commands.
+	  lib="$destdir/$realname"
+	  func_execute_cmds "$postinstall_cmds" 'exit $?'
+	fi
+
+	# Install the pseudo-library for information purposes.
+	func_basename "$file"
+	name="$func_basename_result"
+	instname="$dir/$name"i
+	func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
+
+	# Maybe install the static library, too.
+	test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+	;;
+
+      *.lo)
+	# Install (i.e. copy) a libtool object.
+
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# Deduce the name of the destination old-style object file.
+	case $destfile in
+	*.lo)
+	  func_lo2o "$destfile"
+	  staticdest=$func_lo2o_result
+	  ;;
+	*.$objext)
+	  staticdest="$destfile"
+	  destfile=
+	  ;;
+	*)
+	  func_fatal_help "cannot copy a libtool object to \`$destfile'"
+	  ;;
+	esac
+
+	# Install the libtool object if requested.
+	test -n "$destfile" && \
+	  func_show_eval "$install_prog $file $destfile" 'exit $?'
+
+	# Install the old object if enabled.
+	if test "$build_old_libs" = yes; then
+	  # Deduce the name of the old-style object file.
+	  func_lo2o "$file"
+	  staticobj=$func_lo2o_result
+	  func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?'
+	fi
+	exit $EXIT_SUCCESS
+	;;
+
+      *)
+	# Figure out destination file name, if it wasn't already specified.
+	if test -n "$destname"; then
+	  destfile="$destdir/$destname"
+	else
+	  func_basename "$file"
+	  destfile="$func_basename_result"
+	  destfile="$destdir/$destfile"
+	fi
+
+	# If the file is missing, and there is a .exe on the end, strip it
+	# because it is most likely a libtool script we actually want to
+	# install
+	stripped_ext=""
+	case $file in
+	  *.exe)
+	    if test ! -f "$file"; then
+	      func_stripname '' '.exe' "$file"
+	      file=$func_stripname_result
+	      stripped_ext=".exe"
+	    fi
+	    ;;
+	esac
+
+	# Do a test to see if this is really a libtool program.
+	case $host in
+	*cygwin* | *mingw*)
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      wrapper=$func_ltwrapper_scriptname_result
+	    else
+	      func_stripname '' '.exe' "$file"
+	      wrapper=$func_stripname_result
+	    fi
+	    ;;
+	*)
+	    wrapper=$file
+	    ;;
+	esac
+	if func_ltwrapper_script_p "$wrapper"; then
+	  notinst_deplibs=
+	  relink_command=
+
+	  func_source "$wrapper"
+
+	  # Check the variables that should have been set.
+	  test -z "$generated_by_libtool_version" && \
+	    func_fatal_error "invalid libtool wrapper script \`$wrapper'"
+
+	  finalize=yes
+	  for lib in $notinst_deplibs; do
+	    # Check to see that each library is installed.
+	    libdir=
+	    if test -f "$lib"; then
+	      func_source "$lib"
+	    fi
+	    libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+	    if test -n "$libdir" && test ! -f "$libfile"; then
+	      func_warning "\`$lib' has not been installed in \`$libdir'"
+	      finalize=no
+	    fi
+	  done
+
+	  relink_command=
+	  func_source "$wrapper"
+
+	  outputname=
+	  if test "$fast_install" = no && test -n "$relink_command"; then
+	    $opt_dry_run || {
+	      if test "$finalize" = yes; then
+	        tmpdir=`func_mktempdir`
+		func_basename "$file$stripped_ext"
+		file="$func_basename_result"
+	        outputname="$tmpdir/$file"
+	        # Replace the output file specification.
+	        relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+	        $opt_silent || {
+	          func_quote_for_expand "$relink_command"
+		  eval "func_echo $func_quote_for_expand_result"
+	        }
+	        if eval "$relink_command"; then :
+	          else
+		  func_error "error: relink \`$file' with the above command before installing it"
+		  $opt_dry_run || ${RM}r "$tmpdir"
+		  continue
+	        fi
+	        file="$outputname"
+	      else
+	        func_warning "cannot relink \`$file'"
+	      fi
+	    }
+	  else
+	    # Install the binary that we compiled earlier.
+	    file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+	  fi
+	fi
+
+	# remove .exe since cygwin /usr/bin/install will append another
+	# one anyway
+	case $install_prog,$host in
+	*/usr/bin/install*,*cygwin*)
+	  case $file:$destfile in
+	  *.exe:*.exe)
+	    # this is ok
+	    ;;
+	  *.exe:*)
+	    destfile=$destfile.exe
+	    ;;
+	  *:*.exe)
+	    func_stripname '' '.exe' "$destfile"
+	    destfile=$func_stripname_result
+	    ;;
+	  esac
+	  ;;
+	esac
+	func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?'
+	$opt_dry_run || if test -n "$outputname"; then
+	  ${RM}r "$tmpdir"
+	fi
+	;;
+      esac
+    done
+
+    for file in $staticlibs; do
+      func_basename "$file"
+      name="$func_basename_result"
+
+      # Set up the ranlib parameters.
+      oldlib="$destdir/$name"
+
+      func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
+
+      if test -n "$stripme" && test -n "$old_striplib"; then
+	func_show_eval "$old_striplib $oldlib" 'exit $?'
+      fi
+
+      # Do each command in the postinstall commands.
+      func_execute_cmds "$old_postinstall_cmds" 'exit $?'
+    done
+
+    test -n "$future_libdirs" && \
+      func_warning "remember to run \`$progname --finish$future_libdirs'"
+
+    if test -n "$current_libdirs"; then
+      # Maybe just do a dry run.
+      $opt_dry_run && current_libdirs=" -n$current_libdirs"
+      exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs'
+    else
+      exit $EXIT_SUCCESS
+    fi
+}
+
+test "$mode" = install && func_mode_install ${1+"$@"}
+
+
+# func_generate_dlsyms outputname originator pic_p
+# Extract symbols from dlprefiles and create ${outputname}S.o with
+# a dlpreopen symbol table.
+func_generate_dlsyms ()
+{
+    $opt_debug
+    my_outputname="$1"
+    my_originator="$2"
+    my_pic_p="${3-no}"
+    my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'`
+    my_dlsyms=
+
+    if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+      if test -n "$NM" && test -n "$global_symbol_pipe"; then
+	my_dlsyms="${my_outputname}S.c"
+      else
+	func_error "not configured to extract global symbols from dlpreopened files"
+      fi
+    fi
+
+    if test -n "$my_dlsyms"; then
+      case $my_dlsyms in
+      "") ;;
+      *.c)
+	# Discover the nlist of each of the dlfiles.
+	nlist="$output_objdir/${my_outputname}.nm"
+
+	func_show_eval "$RM $nlist ${nlist}S ${nlist}T"
+
+	# Parse the name list into a source file.
+	func_verbose "creating $output_objdir/$my_dlsyms"
+
+	$opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\
+/* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */
+/* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* External symbol declarations for the compiler. */\
+"
+
+	if test "$dlself" = yes; then
+	  func_verbose "generating symbol list for \`$output'"
+
+	  $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
+
+	  # Add our own program objects to the symbol list.
+	  progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	  for progfile in $progfiles; do
+	    func_verbose "extracting global C symbols from \`$progfile'"
+	    $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+	  done
+
+	  if test -n "$exclude_expsyms"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  if test -n "$export_symbols_regex"; then
+	    $opt_dry_run || {
+	      eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	    }
+	  fi
+
+	  # Prepare the list of exported symbols
+	  if test -z "$export_symbols"; then
+	    export_symbols="$output_objdir/$outputname.exp"
+	    $opt_dry_run || {
+	      $RM $export_symbols
+	      eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+	      case $host in
+	      *cygwin* | *mingw* | *cegcc* )
+                eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+                eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"'
+	        ;;
+	      esac
+	    }
+	  else
+	    $opt_dry_run || {
+	      eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"'
+	      eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
+	      eval '$MV "$nlist"T "$nlist"'
+	      case $host in
+	        *cygwin | *mingw* | *cegcc* )
+	          eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
+	          eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
+	          ;;
+	      esac
+	    }
+	  fi
+	fi
+
+	for dlprefile in $dlprefiles; do
+	  func_verbose "extracting global C symbols from \`$dlprefile'"
+	  func_basename "$dlprefile"
+	  name="$func_basename_result"
+	  $opt_dry_run || {
+	    eval '$ECHO ": $name " >> "$nlist"'
+	    eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+	  }
+	done
+
+	$opt_dry_run || {
+	  # Make sure we have at least an empty file.
+	  test -f "$nlist" || : > "$nlist"
+
+	  if test -n "$exclude_expsyms"; then
+	    $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+	    $MV "$nlist"T "$nlist"
+	  fi
+
+	  # Try sorting and uniquifying the output.
+	  if $GREP -v "^: " < "$nlist" |
+	      if sort -k 3 </dev/null >/dev/null 2>&1; then
+		sort -k 3
+	      else
+		sort +2
+	      fi |
+	      uniq > "$nlist"S; then
+	    :
+	  else
+	    $GREP -v "^: " < "$nlist" > "$nlist"S
+	  fi
+
+	  if test -f "$nlist"S; then
+	    eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
+	  else
+	    $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+	  fi
+
+	  $ECHO >> "$output_objdir/$my_dlsyms" "\
+
+/* The mapping between symbol names and symbols.  */
+typedef struct {
+  const char *name;
+  void *address;
+} lt_dlsymlist;
+"
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc* )
+	    $ECHO >> "$output_objdir/$my_dlsyms" "\
+/* DATA imports from DLLs on WIN32 con't be const, because
+   runtime relocations are performed -- see ld's documentation
+   on pseudo-relocs.  */"
+	    lt_dlsym_const= ;;
+	  *osf5*)
+	    echo >> "$output_objdir/$my_dlsyms" "\
+/* This system does not cope well with relocations in const data */"
+	    lt_dlsym_const= ;;
+	  *)
+	    lt_dlsym_const=const ;;
+	  esac
+
+	  $ECHO >> "$output_objdir/$my_dlsyms" "\
+extern $lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[];
+$lt_dlsym_const lt_dlsymlist
+lt_${my_prefix}_LTX_preloaded_symbols[] =
+{\
+  { \"$my_originator\", (void *) 0 },"
+
+	  case $need_lib_prefix in
+	  no)
+	    eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  *)
+	    eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
+	    ;;
+	  esac
+	  $ECHO >> "$output_objdir/$my_dlsyms" "\
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt_${my_prefix}_LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+	} # !$opt_dry_run
+
+	pic_flag_for_symtable=
+	case "$compile_command " in
+	*" -static "*) ;;
+	*)
+	  case $host in
+	  # compiling the symbol table file with pic_flag works around
+	  # a FreeBSD bug that causes programs to crash when -lm is
+	  # linked before any other PIC object.  But we must not use
+	  # pic_flag when linking with -static.  The problem exists in
+	  # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+	  *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+	    pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
+	  *-*-hpux*)
+	    pic_flag_for_symtable=" $pic_flag"  ;;
+	  *)
+	    if test "X$my_pic_p" != Xno; then
+	      pic_flag_for_symtable=" $pic_flag"
+	    fi
+	    ;;
+	  esac
+	  ;;
+	esac
+	symtab_cflags=
+	for arg in $LTCFLAGS; do
+	  case $arg in
+	  -pie | -fpie | -fPIE) ;;
+	  *) symtab_cflags="$symtab_cflags $arg" ;;
+	  esac
+	done
+
+	# Now compile the dynamic symbol file.
+	func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?'
+
+	# Clean up the generated files.
+	func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"'
+
+	# Transform the symbol file into the correct name.
+	symfileobj="$output_objdir/${my_outputname}S.$objext"
+	case $host in
+	*cygwin* | *mingw* | *cegcc* )
+	  if test -f "$output_objdir/$my_outputname.def"; then
+	    compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	    finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+	  else
+	    compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	    finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	  fi
+	  ;;
+	*)
+	  compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	  finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+	  ;;
+	esac
+	;;
+      *)
+	func_fatal_error "unknown suffix for \`$my_dlsyms'"
+	;;
+      esac
+    else
+      # We keep going just in case the user didn't refer to
+      # lt_preloaded_symbols.  The linker will fail if global_symbol_pipe
+      # really was required.
+
+      # Nullify the symbol file.
+      compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+    fi
+}
+
+# func_win32_libid arg
+# return the library type of file 'arg'
+#
+# Need a lot of goo to handle *both* DLLs and import libs
+# Has to be a shell function in order to 'eat' the argument
+# that is supplied when $file_magic_command is called.
+func_win32_libid ()
+{
+  $opt_debug
+  win32_libid_type="unknown"
+  win32_fileres=`file -L $1 2>/dev/null`
+  case $win32_fileres in
+  *ar\ archive\ import\ library*) # definitely import
+    win32_libid_type="x86 archive import"
+    ;;
+  *ar\ archive*) # could be an import, or static
+    if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
+       $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
+      win32_nmres=`eval $NM -f posix -A $1 |
+	$SED -n -e '
+	    1,100{
+		/ I /{
+		    s,.*,import,
+		    p
+		    q
+		}
+	    }'`
+      case $win32_nmres in
+      import*)  win32_libid_type="x86 archive import";;
+      *)        win32_libid_type="x86 archive static";;
+      esac
+    fi
+    ;;
+  *DLL*)
+    win32_libid_type="x86 DLL"
+    ;;
+  *executable*) # but shell scripts are "executable" too...
+    case $win32_fileres in
+    *MS\ Windows\ PE\ Intel*)
+      win32_libid_type="x86 DLL"
+      ;;
+    esac
+    ;;
+  esac
+  $ECHO "$win32_libid_type"
+}
+
+
+
+# func_extract_an_archive dir oldlib
+func_extract_an_archive ()
+{
+    $opt_debug
+    f_ex_an_ar_dir="$1"; shift
+    f_ex_an_ar_oldlib="$1"
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+    if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
+     :
+    else
+      func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib"
+    fi
+}
+
+
+# func_extract_archives gentop oldlib ...
+func_extract_archives ()
+{
+    $opt_debug
+    my_gentop="$1"; shift
+    my_oldlibs=${1+"$@"}
+    my_oldobjs=""
+    my_xlib=""
+    my_xabs=""
+    my_xdir=""
+
+    for my_xlib in $my_oldlibs; do
+      # Extract the objects.
+      case $my_xlib in
+	[\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;;
+	*) my_xabs=`pwd`"/$my_xlib" ;;
+      esac
+      func_basename "$my_xlib"
+      my_xlib="$func_basename_result"
+      my_xlib_u=$my_xlib
+      while :; do
+        case " $extracted_archives " in
+	*" $my_xlib_u "*)
+	  func_arith $extracted_serial + 1
+	  extracted_serial=$func_arith_result
+	  my_xlib_u=lt$extracted_serial-$my_xlib ;;
+	*) break ;;
+	esac
+      done
+      extracted_archives="$extracted_archives $my_xlib_u"
+      my_xdir="$my_gentop/$my_xlib_u"
+
+      func_mkdir_p "$my_xdir"
+
+      case $host in
+      *-darwin*)
+	func_verbose "Extracting $my_xabs"
+	# Do not bother doing anything if just a dry run
+	$opt_dry_run || {
+	  darwin_orig_dir=`pwd`
+	  cd $my_xdir || exit $?
+	  darwin_archive=$my_xabs
+	  darwin_curdir=`pwd`
+	  darwin_base_archive=`basename "$darwin_archive"`
+	  darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true`
+	  if test -n "$darwin_arches"; then
+	    darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'`
+	    darwin_arch=
+	    func_verbose "$darwin_base_archive has multiple architectures $darwin_arches"
+	    for darwin_arch in  $darwin_arches ; do
+	      func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}"
+	      cd "unfat-$$/${darwin_base_archive}-${darwin_arch}"
+	      func_extract_an_archive "`pwd`" "${darwin_base_archive}"
+	      cd "$darwin_curdir"
+	      $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}"
+	    done # $darwin_arches
+            ## Okay now we've a bunch of thin objects, gotta fatten them up :)
+	    darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u`
+	    darwin_file=
+	    darwin_files=
+	    for darwin_file in $darwin_filelist; do
+	      darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+	      $LIPO -create -output "$darwin_file" $darwin_files
+	    done # $darwin_filelist
+	    $RM -rf unfat-$$
+	    cd "$darwin_orig_dir"
+	  else
+	    cd $darwin_orig_dir
+	    func_extract_an_archive "$my_xdir" "$my_xabs"
+	  fi # $darwin_arches
+	} # !$opt_dry_run
+	;;
+      *)
+        func_extract_an_archive "$my_xdir" "$my_xabs"
+	;;
+      esac
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+    done
+
+    func_extract_archives_result="$my_oldobjs"
+}
+
+
+
+# func_emit_wrapper_part1 [arg=no]
+#
+# Emit the first part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part1 ()
+{
+	func_emit_wrapper_part1_arg1=no
+	if test -n "$1" ; then
+	  func_emit_wrapper_part1_arg1=$1
+	fi
+
+	$ECHO "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='${SED} -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# 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+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='$macro_version'
+  notinst_deplibs='$notinst_deplibs'
+else
+  # When we are sourced in execute mode, \$file and \$ECHO are already set.
+  if test \"\$libtool_execute_magic\" != \"$magic\"; then
+    ECHO=\"$qecho\"
+    file=\"\$0\"
+    # Make sure echo works.
+    if test \"X\$1\" = X--no-reexec; then
+      # Discard the --no-reexec flag, and continue.
+      shift
+    elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
+      # Yippee, \$ECHO works!
+      :
+    else
+      # Restart under the correct shell, and then maybe \$ECHO will work.
+      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+    fi
+  fi\
+"
+	$ECHO "\
+
+  # Find the directory that this script lives in.
+  thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  while test -n \"\$file\"; do
+    destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+    # If there was a directory component, then change thisdir.
+    if test \"x\$destdir\" != \"x\$file\"; then
+      case \"\$destdir\" in
+      [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;;
+      *) thisdir=\"\$thisdir/\$destdir\" ;;
+      esac
+    fi
+
+    file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+  done
+"
+}
+# end: func_emit_wrapper_part1
+
+# func_emit_wrapper_part2 [arg=no]
+#
+# Emit the second part of a libtool wrapper script on stdout.
+# For more information, see the description associated with
+# func_emit_wrapper(), below.
+func_emit_wrapper_part2 ()
+{
+	func_emit_wrapper_part2_arg1=no
+	if test -n "$1" ; then
+	  func_emit_wrapper_part2_arg1=$1
+	fi
+
+	$ECHO "\
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+  if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
+    # special case for '.'
+    if test \"\$thisdir\" = \".\"; then
+      thisdir=\`pwd\`
+    fi
+    # remove .libs from thisdir
+    case \"\$thisdir\" in
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    $objdir )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=\`cd \"\$thisdir\" && pwd\`
+  test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+	if test "$fast_install" = yes; then
+	  $ECHO "\
+  program=lt-'$outputname'$exeext
+  progdir=\"\$thisdir/$objdir\"
+
+  if test ! -f \"\$progdir/\$program\" ||
+     { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\
+       test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+    file=\"\$\$-\$program\"
+
+    if test ! -d \"\$progdir\"; then
+      $MKDIR \"\$progdir\"
+    else
+      $RM \"\$progdir/\$file\"
+    fi"
+
+	  $ECHO "\
+
+    # relink executable if necessary
+    if test -n \"\$relink_command\"; then
+      if relink_command_output=\`eval \$relink_command 2>&1\`; then :
+      else
+	$ECHO \"\$relink_command_output\" >&2
+	$RM \"\$progdir/\$file\"
+	exit 1
+      fi
+    fi
+
+    $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+    { $RM \"\$progdir/\$program\";
+      $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+    $RM \"\$progdir/\$file\"
+  fi"
+	else
+	  $ECHO "\
+  program='$outputname'
+  progdir=\"\$thisdir/$objdir\"
+"
+	fi
+
+	$ECHO "\
+
+  if test -f \"\$progdir/\$program\"; then"
+
+	# Export our shlibpath_var if we have one.
+	if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+	  $ECHO "\
+    # Add our own library path to $shlibpath_var
+    $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+    # Some systems cannot cope with colon-terminated $shlibpath_var
+    # The second colon is a workaround for a bug in BeOS R4 sed
+    $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+    export $shlibpath_var
+"
+	fi
+
+	# fixup the dll searchpath if we need to.
+	if test -n "$dllsearchpath"; then
+	  $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+	fi
+
+	$ECHO "\
+    if test \"\$libtool_execute_magic\" != \"$magic\"; then
+      # Run the actual program with our arguments.
+"
+	case $host in
+	# Backslashes separate directories on plain windows
+	*-*-mingw | *-*-os2* | *-cegcc*)
+	  $ECHO "\
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+	  ;;
+
+	*)
+	  $ECHO "\
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+	  ;;
+	esac
+	$ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+    fi
+  else
+    # The program doesn't exist.
+    \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
+    \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
+    $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    exit 1
+  fi
+fi\
+"
+}
+# end: func_emit_wrapper_part2
+
+
+# func_emit_wrapper [arg=no]
+#
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
+{
+	func_emit_wrapper_arg1=no
+	if test -n "$1" ; then
+	  func_emit_wrapper_arg1=$1
+	fi
+
+	# split this up so that func_emit_cwrapperexe_src
+	# can call each part independently.
+	func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
+	func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
+}
+
+
+# func_to_host_path arg
+#
+# Convert paths to host format when used with build tools.
+# Intended for use with "native" mingw (where libtool itself
+# is running under the msys shell), or in the following cross-
+# build environments:
+#    $build          $host
+#    mingw (msys)    mingw  [e.g. native]
+#    cygwin          mingw
+#    *nix + wine     mingw
+# where wine is equipped with the `winepath' executable.
+# In the native mingw case, the (msys) shell automatically
+# converts paths for any non-msys applications it launches,
+# but that facility isn't available from inside the cwrapper.
+# Similar accommodations are necessary for $host mingw and
+# $build cygwin.  Calling this function does no harm for other
+# $host/$build combinations not listed above.
+#
+# ARG is the path (on $build) that should be converted to
+# the proper representation for $host. The result is stored
+# in $func_to_host_path_result.
+func_to_host_path ()
+{
+  func_to_host_path_result="$1"
+  if test -n "$1" ; then
+    case $host in
+      *mingw* )
+        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+        case $build in
+          *mingw* ) # actually, msys
+            # awkward: cmd appends spaces to result
+            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+            func_to_host_path_tmp1=`( cmd //c echo "$1" |\
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          *cygwin* )
+            func_to_host_path_tmp1=`cygpath -w "$1"`
+            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          * )
+            # Unfortunately, winepath does not exit with a non-zero
+            # error code, so we are forced to check the contents of
+            # stdout. On the other hand, if the command is not
+            # found, the shell will set an exit code of 127 and print
+            # *an error message* to stdout. So we must check for both
+            # error code of zero AND non-empty stdout, which explains
+            # the odd construction:
+            func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
+            if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
+              func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
+                $SED -e "$lt_sed_naive_backslashify"`
+            else
+              # Allow warning below.
+              func_to_host_path_result=""
+            fi
+            ;;
+        esac
+        if test -z "$func_to_host_path_result" ; then
+          func_error "Could not determine host path corresponding to"
+          func_error "  '$1'"
+          func_error "Continuing, but uninstalled executables may not work."
+          # Fallback:
+          func_to_host_path_result="$1"
+        fi
+        ;;
+    esac
+  fi
+}
+# end: func_to_host_path
+
+# func_to_host_pathlist arg
+#
+# Convert pathlists to host format when used with build tools.
+# See func_to_host_path(), above. This function supports the
+# following $build/$host combinations (but does no harm for
+# combinations not listed here):
+#    $build          $host
+#    mingw (msys)    mingw  [e.g. native]
+#    cygwin          mingw
+#    *nix + wine     mingw
+#
+# Path separators are also converted from $build format to
+# $host format. If ARG begins or ends with a path separator
+# character, it is preserved (but converted to $host format)
+# on output.
+#
+# ARG is a pathlist (on $build) that should be converted to
+# the proper representation on $host. The result is stored
+# in $func_to_host_pathlist_result.
+func_to_host_pathlist ()
+{
+  func_to_host_pathlist_result="$1"
+  if test -n "$1" ; then
+    case $host in
+      *mingw* )
+        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+        # Remove leading and trailing path separator characters from
+        # ARG. msys behavior is inconsistent here, cygpath turns them
+        # into '.;' and ';.', and winepath ignores them completely.
+        func_to_host_pathlist_tmp2="$1"
+        # Once set for this call, this variable should not be
+        # reassigned. It is used in tha fallback case.
+        func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
+          $SED -e 's|^:*||' -e 's|:*$||'`
+        case $build in
+          *mingw* ) # Actually, msys.
+            # Awkward: cmd appends spaces to result.
+            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
+            func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
+              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          *cygwin* )
+            func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
+            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
+              $SED -e "$lt_sed_naive_backslashify"`
+            ;;
+          * )
+            # unfortunately, winepath doesn't convert pathlists
+            func_to_host_pathlist_result=""
+            func_to_host_pathlist_oldIFS=$IFS
+            IFS=:
+            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
+              IFS=$func_to_host_pathlist_oldIFS
+              if test -n "$func_to_host_pathlist_f" ; then
+                func_to_host_path "$func_to_host_pathlist_f"
+                if test -n "$func_to_host_path_result" ; then
+                  if test -z "$func_to_host_pathlist_result" ; then
+                    func_to_host_pathlist_result="$func_to_host_path_result"
+                  else
+                    func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
+                  fi
+                fi
+              fi
+              IFS=:
+            done
+            IFS=$func_to_host_pathlist_oldIFS
+            ;;
+        esac
+        if test -z "$func_to_host_pathlist_result" ; then
+          func_error "Could not determine the host path(s) corresponding to"
+          func_error "  '$1'"
+          func_error "Continuing, but uninstalled executables may not work."
+          # Fallback. This may break if $1 contains DOS-style drive
+          # specifications. The fix is not to complicate the expression
+          # below, but for the user to provide a working wine installation
+          # with winepath so that path translation in the cross-to-mingw
+          # case works properly.
+          lt_replace_pathsep_nix_to_dos="s|:|;|g"
+          func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
+            $SED -e "$lt_replace_pathsep_nix_to_dos"`
+        fi
+        # Now, add the leading and trailing path separators back
+        case "$1" in
+          :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
+            ;;
+        esac
+        case "$1" in
+          *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
+            ;;
+        esac
+        ;;
+    esac
+  fi
+}
+# end: func_to_host_pathlist
+
+# func_emit_cwrapperexe_src
+# emit the source code for a wrapper executable on stdout
+# Must ONLY be called from within func_mode_link because
+# it depends on a number of variable set therein.
+func_emit_cwrapperexe_src ()
+{
+	cat <<EOF
+
+/* $cwrappersource - temporary wrapper executable for $objdir/$outputname
+   Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+
+   The $output program cannot be directly executed until all the libtool
+   libraries that it depends on are installed.
+
+   This wrapper executable should never be moved out of the build directory.
+   If it is, it will not operate correctly.
+
+   Currently, it simply execs the wrapper *script* "$SHELL $output",
+   but could eventually absorb all of the scripts functionality and
+   exec $objdir/$outputname directly.
+*/
+EOF
+	    cat <<"EOF"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _MSC_VER
+# include <direct.h>
+# include <process.h>
+# include <io.h>
+# define setmode _setmode
+#else
+# include <unistd.h>
+# include <stdint.h>
+# ifdef __CYGWIN__
+#  include <io.h>
+#  define HAVE_SETENV
+#  ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+#  endif
+# endif
+#endif
+#include <malloc.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+#if defined(PATH_MAX)
+# define LT_PATHMAX PATH_MAX
+#elif defined(MAXPATHLEN)
+# define LT_PATHMAX MAXPATHLEN
+#else
+# define LT_PATHMAX 1024
+#endif
+
+#ifndef S_IXOTH
+# define S_IXOTH 0
+#endif
+#ifndef S_IXGRP
+# define S_IXGRP 0
+#endif
+
+#ifdef _MSC_VER
+# define S_IXUSR _S_IEXEC
+# define stat _stat
+# ifndef _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR
+# define DIR_SEPARATOR '/'
+# define PATH_SEPARATOR ':'
+#endif
+
+#if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \
+  defined (__OS2__)
+# define HAVE_DOS_BASED_FILE_SYSTEM
+# define FOPEN_WB "wb"
+# ifndef DIR_SEPARATOR_2
+#  define DIR_SEPARATOR_2 '\\'
+# endif
+# ifndef PATH_SEPARATOR_2
+#  define PATH_SEPARATOR_2 ';'
+# endif
+#endif
+
+#ifndef DIR_SEPARATOR_2
+# define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR)
+#else /* DIR_SEPARATOR_2 */
+# define IS_DIR_SEPARATOR(ch) \
+	(((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2))
+#endif /* DIR_SEPARATOR_2 */
+
+#ifndef PATH_SEPARATOR_2
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR)
+#else /* PATH_SEPARATOR_2 */
+# define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
+#endif /* PATH_SEPARATOR_2 */
+
+#ifdef __CYGWIN__
+# define FOPEN_WB "wb"
+#endif
+
+#ifndef FOPEN_WB
+# define FOPEN_WB "w"
+#endif
+#ifndef _O_BINARY
+# define _O_BINARY 0
+#endif
+
+#define XMALLOC(type, num)      ((type *) xmalloc ((num) * sizeof(type)))
+#define XFREE(stale) do { \
+  if (stale) { free ((void *) stale); stale = 0; } \
+} while (0)
+
+#undef LTWRAPPER_DEBUGPRINTF
+#if defined DEBUGWRAPPER
+# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
+static void
+ltwrapper_debugprintf (const char *fmt, ...)
+{
+    va_list args;
+    va_start (args, fmt);
+    (void) vfprintf (stderr, fmt, args);
+    va_end (args);
+}
+#else
+# define LTWRAPPER_DEBUGPRINTF(args)
+#endif
+
+const char *program_name = NULL;
+
+void *xmalloc (size_t num);
+char *xstrdup (const char *string);
+const char *base_name (const char *name);
+char *find_executable (const char *wrapper);
+char *chase_symlinks (const char *pathspec);
+int make_executable (const char *path);
+int check_executable (const char *path);
+char *strendzap (char *str, const char *pat);
+void lt_fatal (const char *message, ...);
+void lt_setenv (const char *name, const char *value);
+char *lt_extend_str (const char *orig_value, const char *add, int to_end);
+void lt_opt_process_env_set (const char *arg);
+void lt_opt_process_env_prepend (const char *arg);
+void lt_opt_process_env_append (const char *arg);
+int lt_split_name_value (const char *arg, char** name, char** value);
+void lt_update_exe_path (const char *name, const char *value);
+void lt_update_lib_path (const char *name, const char *value);
+
+static const char *script_text_part1 =
+EOF
+
+	    func_emit_wrapper_part1 yes |
+	        $SED -e 's/\([\\"]\)/\\\1/g' \
+	             -e 's/^/  "/' -e 's/$/\\n"/'
+	    echo ";"
+	    cat <<EOF
+
+static const char *script_text_part2 =
+EOF
+	    func_emit_wrapper_part2 yes |
+	        $SED -e 's/\([\\"]\)/\\\1/g' \
+	             -e 's/^/  "/' -e 's/$/\\n"/'
+	    echo ";"
+
+	    cat <<EOF
+const char * MAGIC_EXE = "$magic_exe";
+const char * LIB_PATH_VARNAME = "$shlibpath_var";
+EOF
+
+	    if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+              func_to_host_pathlist "$temp_rpath"
+	      cat <<EOF
+const char * LIB_PATH_VALUE   = "$func_to_host_pathlist_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * LIB_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test -n "$dllsearchpath"; then
+              func_to_host_pathlist "$dllsearchpath:"
+	      cat <<EOF
+const char * EXE_PATH_VARNAME = "PATH";
+const char * EXE_PATH_VALUE   = "$func_to_host_pathlist_result";
+EOF
+	    else
+	      cat <<"EOF"
+const char * EXE_PATH_VARNAME = "";
+const char * EXE_PATH_VALUE   = "";
+EOF
+	    fi
+
+	    if test "$fast_install" = yes; then
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "lt-$outputname"; /* hopefully, no .exe */
+EOF
+	    else
+	      cat <<EOF
+const char * TARGET_PROGRAM_NAME = "$outputname"; /* hopefully, no .exe */
+EOF
+	    fi
+
+
+	    cat <<"EOF"
+
+#define LTWRAPPER_OPTION_PREFIX         "--lt-"
+#define LTWRAPPER_OPTION_PREFIX_LENGTH  5
+
+static const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;
+static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
+
+static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
+
+static const size_t env_set_opt_len     = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
+static const char *env_set_opt          = LTWRAPPER_OPTION_PREFIX "env-set";
+  /* argument is putenv-style "foo=bar", value of foo is set to bar */
+
+static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
+static const char *env_prepend_opt      = LTWRAPPER_OPTION_PREFIX "env-prepend";
+  /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
+
+static const size_t env_append_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
+static const char *env_append_opt       = LTWRAPPER_OPTION_PREFIX "env-append";
+  /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+
+int
+main (int argc, char *argv[])
+{
+  char **newargz;
+  int  newargc;
+  char *tmp_pathspec;
+  char *actual_cwrapper_path;
+  char *actual_cwrapper_name;
+  char *target_name;
+  char *lt_argv_zero;
+  intptr_t rval = 127;
+
+  int i;
+
+  program_name = (char *) xstrdup (base_name (argv[0]));
+  LTWRAPPER_DEBUGPRINTF (("(main) argv[0]      : %s\n", argv[0]));
+  LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+
+  /* very simple arg parsing; don't want to rely on getopt */
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], dumpscript_opt) == 0)
+	{
+EOF
+	    case "$host" in
+	      *mingw* | *cygwin* )
+		# make stdout use "unix" line endings
+		echo "          setmode(1,_O_BINARY);"
+		;;
+	      esac
+
+	    cat <<"EOF"
+	  printf ("%s", script_text_part1);
+	  printf ("%s", script_text_part2);
+	  return 0;
+	}
+    }
+
+  newargz = XMALLOC (char *, argc + 1);
+  tmp_pathspec = find_executable (argv[0]);
+  if (tmp_pathspec == NULL)
+    lt_fatal ("Couldn't find %s", argv[0]);
+  LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
+			  tmp_pathspec));
+
+  actual_cwrapper_path = chase_symlinks (tmp_pathspec);
+  LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
+			  actual_cwrapper_path));
+  XFREE (tmp_pathspec);
+
+  actual_cwrapper_name = xstrdup( base_name (actual_cwrapper_path));
+  strendzap (actual_cwrapper_path, actual_cwrapper_name);
+
+  /* wrapper name transforms */
+  strendzap (actual_cwrapper_name, ".exe");
+  tmp_pathspec = lt_extend_str (actual_cwrapper_name, ".exe", 1);
+  XFREE (actual_cwrapper_name);
+  actual_cwrapper_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  /* target_name transforms -- use actual target program name; might have lt- prefix */
+  target_name = xstrdup (base_name (TARGET_PROGRAM_NAME));
+  strendzap (target_name, ".exe");
+  tmp_pathspec = lt_extend_str (target_name, ".exe", 1);
+  XFREE (target_name);
+  target_name = tmp_pathspec;
+  tmp_pathspec = 0;
+
+  LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
+			  target_name));
+EOF
+
+	    cat <<EOF
+  newargz[0] =
+    XMALLOC (char, (strlen (actual_cwrapper_path) +
+		    strlen ("$objdir") + 1 + strlen (actual_cwrapper_name) + 1));
+  strcpy (newargz[0], actual_cwrapper_path);
+  strcat (newargz[0], "$objdir");
+  strcat (newargz[0], "/");
+EOF
+
+	    cat <<"EOF"
+  /* stop here, and copy so we don't have to do this twice */
+  tmp_pathspec = xstrdup (newargz[0]);
+
+  /* do NOT want the lt- prefix here, so use actual_cwrapper_name */
+  strcat (newargz[0], actual_cwrapper_name);
+
+  /* DO want the lt- prefix here if it exists, so use target_name */
+  lt_argv_zero = lt_extend_str (tmp_pathspec, target_name, 1);
+  XFREE (tmp_pathspec);
+  tmp_pathspec = NULL;
+EOF
+
+	    case $host_os in
+	      mingw*)
+	    cat <<"EOF"
+  {
+    char* p;
+    while ((p = strchr (newargz[0], '\\')) != NULL)
+      {
+	*p = '/';
+      }
+    while ((p = strchr (lt_argv_zero, '\\')) != NULL)
+      {
+	*p = '/';
+      }
+  }
+EOF
+	    ;;
+	    esac
+
+	    cat <<"EOF"
+  XFREE (target_name);
+  XFREE (actual_cwrapper_path);
+  XFREE (actual_cwrapper_name);
+
+  lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
+  lt_setenv ("DUALCASE", "1");  /* for MSK sh */
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+  lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+
+  newargc=0;
+  for (i = 1; i < argc; i++)
+    {
+      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
+        {
+          if (argv[i][env_set_opt_len] == '=')
+            {
+              const char *p = argv[i] + env_set_opt_len + 1;
+              lt_opt_process_env_set (p);
+            }
+          else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
+            {
+              lt_opt_process_env_set (argv[++i]); /* don't copy */
+            }
+          else
+            lt_fatal ("%s missing required argument", env_set_opt);
+          continue;
+        }
+      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
+        {
+          if (argv[i][env_prepend_opt_len] == '=')
+            {
+              const char *p = argv[i] + env_prepend_opt_len + 1;
+              lt_opt_process_env_prepend (p);
+            }
+          else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
+            {
+              lt_opt_process_env_prepend (argv[++i]); /* don't copy */
+            }
+          else
+            lt_fatal ("%s missing required argument", env_prepend_opt);
+          continue;
+        }
+      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
+        {
+          if (argv[i][env_append_opt_len] == '=')
+            {
+              const char *p = argv[i] + env_append_opt_len + 1;
+              lt_opt_process_env_append (p);
+            }
+          else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
+            {
+              lt_opt_process_env_append (argv[++i]); /* don't copy */
+            }
+          else
+            lt_fatal ("%s missing required argument", env_append_opt);
+          continue;
+        }
+      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal ("Unrecognized option in %s namespace: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
+    }
+  newargz[++newargc] = NULL;
+
+  LTWRAPPER_DEBUGPRINTF     (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+  for (i = 0; i < newargc; i++)
+    {
+      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+    }
+
+EOF
+
+	    case $host_os in
+	      mingw*)
+		cat <<"EOF"
+  /* execv doesn't actually work on mingw as expected on unix */
+  rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
+  if (rval == -1)
+    {
+      /* failed to start process */
+      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+      return 127;
+    }
+  return rval;
+EOF
+		;;
+	      *)
+		cat <<"EOF"
+  execv (lt_argv_zero, newargz);
+  return rval; /* =127, but avoids unused variable warning */
+EOF
+		;;
+	    esac
+
+	    cat <<"EOF"
+}
+
+void *
+xmalloc (size_t num)
+{
+  void *p = (void *) malloc (num);
+  if (!p)
+    lt_fatal ("Memory exhausted");
+
+  return p;
+}
+
+char *
+xstrdup (const char *string)
+{
+  return string ? strcpy ((char *) xmalloc (strlen (string) + 1),
+			  string) : NULL;
+}
+
+const char *
+base_name (const char *name)
+{
+  const char *base;
+
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  /* Skip over the disk name in MSDOS pathnames. */
+  if (isalpha ((unsigned char) name[0]) && name[1] == ':')
+    name += 2;
+#endif
+
+  for (base = name; *name; name++)
+    if (IS_DIR_SEPARATOR (*name))
+      base = name + 1;
+  return base;
+}
+
+int
+check_executable (const char *path)
+{
+  struct stat st;
+
+  LTWRAPPER_DEBUGPRINTF (("(check_executable)  : %s\n",
+			  path ? (*path ? path : "EMPTY!") : "NULL!"));
+  if ((!path) || (!*path))
+    return 0;
+
+  if ((stat (path, &st) >= 0)
+      && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
+    return 1;
+  else
+    return 0;
+}
+
+int
+make_executable (const char *path)
+{
+  int rval = 0;
+  struct stat st;
+
+  LTWRAPPER_DEBUGPRINTF (("(make_executable)   : %s\n",
+			  path ? (*path ? path : "EMPTY!") : "NULL!"));
+  if ((!path) || (!*path))
+    return 0;
+
+  if (stat (path, &st) >= 0)
+    {
+      rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR);
+    }
+  return rval;
+}
+
+/* Searches for the full path of the wrapper.  Returns
+   newly allocated full path name if found, NULL otherwise
+   Does not chase symlinks, even on platforms that support them.
+*/
+char *
+find_executable (const char *wrapper)
+{
+  int has_slash = 0;
+  const char *p;
+  const char *p_next;
+  /* static buffer for getcwd */
+  char tmp[LT_PATHMAX + 1];
+  int tmp_len;
+  char *concat_name;
+
+  LTWRAPPER_DEBUGPRINTF (("(find_executable)   : %s\n",
+			  wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+
+  if ((wrapper == NULL) || (*wrapper == '\0'))
+    return NULL;
+
+  /* Absolute path? */
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+  if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':')
+    {
+      concat_name = xstrdup (wrapper);
+      if (check_executable (concat_name))
+	return concat_name;
+      XFREE (concat_name);
+    }
+  else
+    {
+#endif
+      if (IS_DIR_SEPARATOR (wrapper[0]))
+	{
+	  concat_name = xstrdup (wrapper);
+	  if (check_executable (concat_name))
+	    return concat_name;
+	  XFREE (concat_name);
+	}
+#if defined (HAVE_DOS_BASED_FILE_SYSTEM)
+    }
+#endif
+
+  for (p = wrapper; *p; p++)
+    if (*p == '/')
+      {
+	has_slash = 1;
+	break;
+      }
+  if (!has_slash)
+    {
+      /* no slashes; search PATH */
+      const char *path = getenv ("PATH");
+      if (path != NULL)
+	{
+	  for (p = path; *p; p = p_next)
+	    {
+	      const char *q;
+	      size_t p_len;
+	      for (q = p; *q; q++)
+		if (IS_PATH_SEPARATOR (*q))
+		  break;
+	      p_len = q - p;
+	      p_next = (*q == '\0' ? q : q + 1);
+	      if (p_len == 0)
+		{
+		  /* empty path: current directory */
+		  if (getcwd (tmp, LT_PATHMAX) == NULL)
+		    lt_fatal ("getcwd failed");
+		  tmp_len = strlen (tmp);
+		  concat_name =
+		    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, tmp, tmp_len);
+		  concat_name[tmp_len] = '/';
+		  strcpy (concat_name + tmp_len + 1, wrapper);
+		}
+	      else
+		{
+		  concat_name =
+		    XMALLOC (char, p_len + 1 + strlen (wrapper) + 1);
+		  memcpy (concat_name, p, p_len);
+		  concat_name[p_len] = '/';
+		  strcpy (concat_name + p_len + 1, wrapper);
+		}
+	      if (check_executable (concat_name))
+		return concat_name;
+	      XFREE (concat_name);
+	    }
+	}
+      /* not found in PATH; assume curdir */
+    }
+  /* Relative path | not found in path: prepend cwd */
+  if (getcwd (tmp, LT_PATHMAX) == NULL)
+    lt_fatal ("getcwd failed");
+  tmp_len = strlen (tmp);
+  concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
+  memcpy (concat_name, tmp, tmp_len);
+  concat_name[tmp_len] = '/';
+  strcpy (concat_name + tmp_len + 1, wrapper);
+
+  if (check_executable (concat_name))
+    return concat_name;
+  XFREE (concat_name);
+  return NULL;
+}
+
+char *
+chase_symlinks (const char *pathspec)
+{
+#ifndef S_ISLNK
+  return xstrdup (pathspec);
+#else
+  char buf[LT_PATHMAX];
+  struct stat s;
+  char *tmp_pathspec = xstrdup (pathspec);
+  char *p;
+  int has_symlinks = 0;
+  while (strlen (tmp_pathspec) && !has_symlinks)
+    {
+      LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
+			      tmp_pathspec));
+      if (lstat (tmp_pathspec, &s) == 0)
+	{
+	  if (S_ISLNK (s.st_mode) != 0)
+	    {
+	      has_symlinks = 1;
+	      break;
+	    }
+
+	  /* search backwards for last DIR_SEPARATOR */
+	  p = tmp_pathspec + strlen (tmp_pathspec) - 1;
+	  while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    p--;
+	  if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p)))
+	    {
+	      /* no more DIR_SEPARATORS left */
+	      break;
+	    }
+	  *p = '\0';
+	}
+      else
+	{
+	  char *errstr = strerror (errno);
+	  lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+	}
+    }
+  XFREE (tmp_pathspec);
+
+  if (!has_symlinks)
+    {
+      return xstrdup (pathspec);
+    }
+
+  tmp_pathspec = realpath (pathspec, buf);
+  if (tmp_pathspec == 0)
+    {
+      lt_fatal ("Could not follow symlinks for %s", pathspec);
+    }
+  return xstrdup (tmp_pathspec);
+#endif
+}
+
+char *
+strendzap (char *str, const char *pat)
+{
+  size_t len, patlen;
+
+  assert (str != NULL);
+  assert (pat != NULL);
+
+  len = strlen (str);
+  patlen = strlen (pat);
+
+  if (patlen <= len)
+    {
+      str += len - patlen;
+      if (strcmp (str, pat) == 0)
+	*str = '\0';
+    }
+  return str;
+}
+
+static void
+lt_error_core (int exit_status, const char *mode,
+	       const char *message, va_list ap)
+{
+  fprintf (stderr, "%s: %s: ", program_name, mode);
+  vfprintf (stderr, message, ap);
+  fprintf (stderr, ".\n");
+
+  if (exit_status >= 0)
+    exit (exit_status);
+}
+
+void
+lt_fatal (const char *message, ...)
+{
+  va_list ap;
+  va_start (ap, message);
+  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  va_end (ap);
+}
+
+void
+lt_setenv (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+  {
+#ifdef HAVE_SETENV
+    /* always make a copy, for consistency with !HAVE_SETENV */
+    char *str = xstrdup (value);
+    setenv (name, str, 1);
+#else
+    int len = strlen (name) + 1 + strlen (value) + 1;
+    char *str = XMALLOC (char, len);
+    sprintf (str, "%s=%s", name, value);
+    if (putenv (str) != EXIT_SUCCESS)
+      {
+        XFREE (str);
+      }
+#endif
+  }
+}
+
+char *
+lt_extend_str (const char *orig_value, const char *add, int to_end)
+{
+  char *new_value;
+  if (orig_value && *orig_value)
+    {
+      int orig_value_len = strlen (orig_value);
+      int add_len = strlen (add);
+      new_value = XMALLOC (char, add_len + orig_value_len + 1);
+      if (to_end)
+        {
+          strcpy (new_value, orig_value);
+          strcpy (new_value + orig_value_len, add);
+        }
+      else
+        {
+          strcpy (new_value, add);
+          strcpy (new_value + add_len, orig_value);
+        }
+    }
+  else
+    {
+      new_value = xstrdup (add);
+    }
+  return new_value;
+}
+
+int
+lt_split_name_value (const char *arg, char** name, char** value)
+{
+  const char *p;
+  int len;
+  if (!arg || !*arg)
+    return 1;
+
+  p = strchr (arg, (int)'=');
+
+  if (!p)
+    return 1;
+
+  *value = xstrdup (++p);
+
+  len = strlen (arg) - strlen (*value);
+  *name = XMALLOC (char, len);
+  strncpy (*name, arg, len-1);
+  (*name)[len - 1] = '\0';
+
+  return 0;
+}
+
+void
+lt_opt_process_env_set (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
+    }
+
+  lt_setenv (name, value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_opt_process_env_prepend (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+  char *new_value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
+    }
+
+  new_value = lt_extend_str (getenv (name), value, 0);
+  lt_setenv (name, new_value);
+  XFREE (new_value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_opt_process_env_append (const char *arg)
+{
+  char *name = NULL;
+  char *value = NULL;
+  char *new_value = NULL;
+
+  if (lt_split_name_value (arg, &name, &value) != 0)
+    {
+      XFREE (name);
+      XFREE (value);
+      lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
+    }
+
+  new_value = lt_extend_str (getenv (name), value, 1);
+  lt_setenv (name, new_value);
+  XFREE (new_value);
+  XFREE (name);
+  XFREE (value);
+}
+
+void
+lt_update_exe_path (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      /* some systems can't cope with a ':'-terminated path #' */
+      int len = strlen (new_value);
+      while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1]))
+        {
+          new_value[len-1] = '\0';
+        }
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+void
+lt_update_lib_path (const char *name, const char *value)
+{
+  LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                          (name ? name : "<NULL>"),
+                          (value ? value : "<NULL>")));
+
+  if (name && *name && value && *value)
+    {
+      char *new_value = lt_extend_str (getenv (name), value, 0);
+      lt_setenv (name, new_value);
+      XFREE (new_value);
+    }
+}
+
+
+EOF
+}
+# end: func_emit_cwrapperexe_src
+
+# func_mode_link arg...
+func_mode_link ()
+{
+    $opt_debug
+    case $host in
+    *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+      # It is impossible to link a dll without this setting, and
+      # we shouldn't force the makefile maintainer to figure out
+      # which system we are compiling for in order to pass an extra
+      # flag for every libtool invocation.
+      # allow_undefined=no
+
+      # FIXME: Unfortunately, there are problems with the above when trying
+      # to make a dll which has undefined symbols, in which case not
+      # even a static library is built.  For now, we need to specify
+      # -no-undefined on the libtool link line when we can be certain
+      # that all symbols are satisfied, otherwise we get a static library.
+      allow_undefined=yes
+      ;;
+    *)
+      allow_undefined=yes
+      ;;
+    esac
+    libtool_args=$nonopt
+    base_compile="$nonopt $@"
+    compile_command=$nonopt
+    finalize_command=$nonopt
+
+    compile_rpath=
+    finalize_rpath=
+    compile_shlibpath=
+    finalize_shlibpath=
+    convenience=
+    old_convenience=
+    deplibs=
+    old_deplibs=
+    compiler_flags=
+    linker_flags=
+    dllsearchpath=
+    lib_search_path=`pwd`
+    inst_prefix_dir=
+    new_inherited_linker_flags=
+
+    avoid_version=no
+    dlfiles=
+    dlprefiles=
+    dlself=no
+    export_dynamic=no
+    export_symbols=
+    export_symbols_regex=
+    generated=
+    libobjs=
+    ltlibs=
+    module=no
+    no_install=no
+    objs=
+    non_pic_objects=
+    precious_files_regex=
+    prefer_static_libs=no
+    preload=no
+    prev=
+    prevarg=
+    release=
+    rpath=
+    xrpath=
+    perm_rpath=
+    temp_rpath=
+    thread_safe=no
+    vinfo=
+    vinfo_number=no
+    weak_libs=
+    single_module="${wl}-single_module"
+    func_infer_tag $base_compile
+
+    # We need to know -static, to get the right output filenames.
+    for arg
+    do
+      case $arg in
+      -shared)
+	test "$build_libtool_libs" != yes && \
+	  func_fatal_configuration "can not build a shared library"
+	build_old_libs=no
+	break
+	;;
+      -all-static | -static | -static-libtool-libs)
+	case $arg in
+	-all-static)
+	  if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+	    func_warning "complete static linking is impossible in this configuration"
+	  fi
+	  if test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	-static)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=built
+	  ;;
+	-static-libtool-libs)
+	  if test -z "$pic_flag" && test -n "$link_static_flag"; then
+	    dlopen_self=$dlopen_self_static
+	  fi
+	  prefer_static_libs=yes
+	  ;;
+	esac
+	build_libtool_libs=no
+	build_old_libs=yes
+	break
+	;;
+      esac
+    done
+
+    # See if our shared archives depend on static archives.
+    test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+    # Go through the arguments, transforming them on the way.
+    while test "$#" -gt 0; do
+      arg="$1"
+      shift
+      func_quote_for_eval "$arg"
+      qarg=$func_quote_for_eval_unquoted_result
+      func_append libtool_args " $func_quote_for_eval_result"
+
+      # If the previous option needs an argument, assign it.
+      if test -n "$prev"; then
+	case $prev in
+	output)
+	  func_append compile_command " @OUTPUT@"
+	  func_append finalize_command " @OUTPUT@"
+	  ;;
+	esac
+
+	case $prev in
+	dlfiles|dlprefiles)
+	  if test "$preload" = no; then
+	    # Add the symbol object into the linking commands.
+	    func_append compile_command " @SYMFILE@"
+	    func_append finalize_command " @SYMFILE@"
+	    preload=yes
+	  fi
+	  case $arg in
+	  *.la | *.lo) ;;  # We handle these cases below.
+	  force)
+	    if test "$dlself" = no; then
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  self)
+	    if test "$prev" = dlprefiles; then
+	      dlself=yes
+	    elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+	      dlself=yes
+	    else
+	      dlself=needless
+	      export_dynamic=yes
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  *)
+	    if test "$prev" = dlfiles; then
+	      dlfiles="$dlfiles $arg"
+	    else
+	      dlprefiles="$dlprefiles $arg"
+	    fi
+	    prev=
+	    continue
+	    ;;
+	  esac
+	  ;;
+	expsyms)
+	  export_symbols="$arg"
+	  test -f "$arg" \
+	    || func_fatal_error "symbol file \`$arg' does not exist"
+	  prev=
+	  continue
+	  ;;
+	expsyms_regex)
+	  export_symbols_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	framework)
+	  case $host in
+	    *-*-darwin*)
+	      case "$deplibs " in
+		*" $qarg.ltframework "*) ;;
+		*) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+		   ;;
+	      esac
+	      ;;
+	  esac
+	  prev=
+	  continue
+	  ;;
+	inst_prefix)
+	  inst_prefix_dir="$arg"
+	  prev=
+	  continue
+	  ;;
+	objectlist)
+	  if test -f "$arg"; then
+	    save_arg=$arg
+	    moreargs=
+	    for fil in `cat "$save_arg"`
+	    do
+#	      moreargs="$moreargs $fil"
+	      arg=$fil
+	      # A libtool-controlled object.
+
+	      # Check to see that this really is a libtool object.
+	      if func_lalib_unsafe_p "$arg"; then
+		pic_object=
+		non_pic_object=
+
+		# Read the .lo file
+		func_source "$arg"
+
+		if test -z "$pic_object" ||
+		   test -z "$non_pic_object" ||
+		   test "$pic_object" = none &&
+		   test "$non_pic_object" = none; then
+		  func_fatal_error "cannot find name of object for \`$arg'"
+		fi
+
+		# Extract subdirectory from the argument.
+		func_dirname "$arg" "/" ""
+		xdir="$func_dirname_result"
+
+		if test "$pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  pic_object="$xdir$pic_object"
+
+		  if test "$prev" = dlfiles; then
+		    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		      dlfiles="$dlfiles $pic_object"
+		      prev=
+		      continue
+		    else
+		      # If libtool objects are unsupported, then we need to preload.
+		      prev=dlprefiles
+		    fi
+		  fi
+
+		  # CHECK ME:  I think I busted this.  -Ossama
+		  if test "$prev" = dlprefiles; then
+		    # Preload the old-style object.
+		    dlprefiles="$dlprefiles $pic_object"
+		    prev=
+		  fi
+
+		  # A PIC object.
+		  func_append libobjs " $pic_object"
+		  arg="$pic_object"
+		fi
+
+		# Non-PIC object.
+		if test "$non_pic_object" != none; then
+		  # Prepend the subdirectory the object is found in.
+		  non_pic_object="$xdir$non_pic_object"
+
+		  # A standard non-PIC object
+		  func_append non_pic_objects " $non_pic_object"
+		  if test -z "$pic_object" || test "$pic_object" = none ; then
+		    arg="$non_pic_object"
+		  fi
+		else
+		  # If the PIC object exists, use it instead.
+		  # $xdir was prepended to $pic_object above.
+		  non_pic_object="$pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+		fi
+	      else
+		# Only an error if not doing a dry-run.
+		if $opt_dry_run; then
+		  # Extract subdirectory from the argument.
+		  func_dirname "$arg" "/" ""
+		  xdir="$func_dirname_result"
+
+		  func_lo2o "$arg"
+		  pic_object=$xdir$objdir/$func_lo2o_result
+		  non_pic_object=$xdir$func_lo2o_result
+		  func_append libobjs " $pic_object"
+		  func_append non_pic_objects " $non_pic_object"
+	        else
+		  func_fatal_error "\`$arg' is not a valid libtool object"
+		fi
+	      fi
+	    done
+	  else
+	    func_fatal_error "link input file \`$arg' does not exist"
+	  fi
+	  arg=$save_arg
+	  prev=
+	  continue
+	  ;;
+	precious_regex)
+	  precious_files_regex="$arg"
+	  prev=
+	  continue
+	  ;;
+	release)
+	  release="-$arg"
+	  prev=
+	  continue
+	  ;;
+	rpath | xrpath)
+	  # We need an absolute path.
+	  case $arg in
+	  [\\/]* | [A-Za-z]:[\\/]*) ;;
+	  *)
+	    func_fatal_error "only absolute run-paths are allowed"
+	    ;;
+	  esac
+	  if test "$prev" = rpath; then
+	    case "$rpath " in
+	    *" $arg "*) ;;
+	    *) rpath="$rpath $arg" ;;
+	    esac
+	  else
+	    case "$xrpath " in
+	    *" $arg "*) ;;
+	    *) xrpath="$xrpath $arg" ;;
+	    esac
+	  fi
+	  prev=
+	  continue
+	  ;;
+	shrext)
+	  shrext_cmds="$arg"
+	  prev=
+	  continue
+	  ;;
+	weak)
+	  weak_libs="$weak_libs $arg"
+	  prev=
+	  continue
+	  ;;
+	xcclinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xcompiler)
+	  compiler_flags="$compiler_flags $qarg"
+	  prev=
+	  func_append compile_command " $qarg"
+	  func_append finalize_command " $qarg"
+	  continue
+	  ;;
+	xlinker)
+	  linker_flags="$linker_flags $qarg"
+	  compiler_flags="$compiler_flags $wl$qarg"
+	  prev=
+	  func_append compile_command " $wl$qarg"
+	  func_append finalize_command " $wl$qarg"
+	  continue
+	  ;;
+	*)
+	  eval "$prev=\"\$arg\""
+	  prev=
+	  continue
+	  ;;
+	esac
+      fi # test -n "$prev"
+
+      prevarg="$arg"
+
+      case $arg in
+      -all-static)
+	if test -n "$link_static_flag"; then
+	  # See comment for -static flag below, for more details.
+	  func_append compile_command " $link_static_flag"
+	  func_append finalize_command " $link_static_flag"
+	fi
+	continue
+	;;
+
+      -allow-undefined)
+	# FIXME: remove this flag sometime in the future.
+	func_fatal_error "\`-allow-undefined' must not be used because it is the default"
+	;;
+
+      -avoid-version)
+	avoid_version=yes
+	continue
+	;;
+
+      -dlopen)
+	prev=dlfiles
+	continue
+	;;
+
+      -dlpreopen)
+	prev=dlprefiles
+	continue
+	;;
+
+      -export-dynamic)
+	export_dynamic=yes
+	continue
+	;;
+
+      -export-symbols | -export-symbols-regex)
+	if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+	  func_fatal_error "more than one -exported-symbols argument is not allowed"
+	fi
+	if test "X$arg" = "X-export-symbols"; then
+	  prev=expsyms
+	else
+	  prev=expsyms_regex
+	fi
+	continue
+	;;
+
+      -framework)
+	prev=framework
+	continue
+	;;
+
+      -inst-prefix-dir)
+	prev=inst_prefix
+	continue
+	;;
+
+      # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:*
+      # so, if we see these flags be careful not to treat them like -L
+      -L[A-Z][A-Z]*:*)
+	case $with_gcc/$host in
+	no/*-*-irix* | /*-*-irix*)
+	  func_append compile_command " $arg"
+	  func_append finalize_command " $arg"
+	  ;;
+	esac
+	continue
+	;;
+
+      -L*)
+	func_stripname '-L' '' "$arg"
+	dir=$func_stripname_result
+	if test -z "$dir"; then
+	  if test "$#" -gt 0; then
+	    func_fatal_error "require no space between \`-L' and \`$1'"
+	  else
+	    func_fatal_error "need path for \`-L' option"
+	  fi
+	fi
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  absdir=`cd "$dir" && pwd`
+	  test -z "$absdir" && \
+	    func_fatal_error "cannot determine absolute directory name of \`$dir'"
+	  dir="$absdir"
+	  ;;
+	esac
+	case "$deplibs " in
+	*" -L$dir "*) ;;
+	*)
+	  deplibs="$deplibs -L$dir"
+	  lib_search_path="$lib_search_path $dir"
+	  ;;
+	esac
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$dir:"*) ;;
+	  ::) dllsearchpath=$dir;;
+	  *) dllsearchpath="$dllsearchpath:$dir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+	continue
+	;;
+
+      -l*)
+	if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+	    # These systems don't actually have a C or math library (as such)
+	    continue
+	    ;;
+	  *-*-os2*)
+	    # These systems don't actually have a C library (as such)
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C and math libraries are in the System framework
+	    deplibs="$deplibs System.ltframework"
+	    continue
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    test "X$arg" = "X-lc" && continue
+	    ;;
+	  esac
+	elif test "X$arg" = "X-lc_r"; then
+	 case $host in
+	 *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	   # Do not include libc_r directly, use -pthread flag.
+	   continue
+	   ;;
+	 esac
+	fi
+	deplibs="$deplibs $arg"
+	continue
+	;;
+
+      -module)
+	module=yes
+	continue
+	;;
+
+      # Tru64 UNIX uses -model [arg] to determine the layout of C++
+      # classes, name mangling, and exception handling.
+      # Darwin uses the -arch flag to determine output architecture.
+      -model|-arch|-isysroot)
+	compiler_flags="$compiler_flags $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	prev=xcompiler
+	continue
+	;;
+
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	compiler_flags="$compiler_flags $arg"
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+	case "$new_inherited_linker_flags " in
+	    *" $arg "*) ;;
+	    * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+	esac
+	continue
+	;;
+
+      -multi_module)
+	single_module="${wl}-multi_module"
+	continue
+	;;
+
+      -no-fast-install)
+	fast_install=no
+	continue
+	;;
+
+      -no-install)
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*)
+	  # The PATH hackery in wrapper scripts is required on Windows
+	  # and Darwin in order for the loader to find any dlls it needs.
+	  func_warning "\`-no-install' is ignored for $host"
+	  func_warning "assuming \`-no-fast-install' instead"
+	  fast_install=no
+	  ;;
+	*) no_install=yes ;;
+	esac
+	continue
+	;;
+
+      -no-undefined)
+	allow_undefined=no
+	continue
+	;;
+
+      -objectlist)
+	prev=objectlist
+	continue
+	;;
+
+      -o) prev=output ;;
+
+      -precious-files-regex)
+	prev=precious_regex
+	continue
+	;;
+
+      -release)
+	prev=release
+	continue
+	;;
+
+      -rpath)
+	prev=rpath
+	continue
+	;;
+
+      -R)
+	prev=xrpath
+	continue
+	;;
+
+      -R*)
+	func_stripname '-R' '' "$arg"
+	dir=$func_stripname_result
+	# We need an absolute path.
+	case $dir in
+	[\\/]* | [A-Za-z]:[\\/]*) ;;
+	*)
+	  func_fatal_error "only absolute run-paths are allowed"
+	  ;;
+	esac
+	case "$xrpath " in
+	*" $dir "*) ;;
+	*) xrpath="$xrpath $dir" ;;
+	esac
+	continue
+	;;
+
+      -shared)
+	# The effects of -shared are defined in a previous loop.
+	continue
+	;;
+
+      -shrext)
+	prev=shrext
+	continue
+	;;
+
+      -static | -static-libtool-libs)
+	# The effects of -static are defined in a previous loop.
+	# We used to do the same as -all-static on platforms that
+	# didn't have a PIC flag, but the assumption that the effects
+	# would be equivalent was wrong.  It would break on at least
+	# Digital Unix and AIX.
+	continue
+	;;
+
+      -thread-safe)
+	thread_safe=yes
+	continue
+	;;
+
+      -version-info)
+	prev=vinfo
+	continue
+	;;
+
+      -version-number)
+	prev=vinfo
+	vinfo_number=yes
+	continue
+	;;
+
+      -weak)
+        prev=weak
+	continue
+	;;
+
+      -Wc,*)
+	func_stripname '-Wc,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  arg="$arg $wl$func_quote_for_eval_result"
+	  compiler_flags="$compiler_flags $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Wl,*)
+	func_stripname '-Wl,' '' "$arg"
+	args=$func_stripname_result
+	arg=
+	save_ifs="$IFS"; IFS=','
+	for flag in $args; do
+	  IFS="$save_ifs"
+          func_quote_for_eval "$flag"
+	  arg="$arg $wl$func_quote_for_eval_result"
+	  compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
+	  linker_flags="$linker_flags $func_quote_for_eval_result"
+	done
+	IFS="$save_ifs"
+	func_stripname ' ' '' "$arg"
+	arg=$func_stripname_result
+	;;
+
+      -Xcompiler)
+	prev=xcompiler
+	continue
+	;;
+
+      -Xlinker)
+	prev=xlinker
+	continue
+	;;
+
+      -XCClinker)
+	prev=xcclinker
+	continue
+	;;
+
+      # -msg_* for osf cc
+      -msg_*)
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
+      # -r[0-9][0-9]* specifies the processor on the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
+      # +DA*, +DD* enable 64-bit mode on the HP compiler
+      # -q* pass through compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* pass through architecture-specific
+      # compiler args for GCC
+      # -F/path gives path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
+      # @file GCC response files
+      -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+        func_append compile_command " $arg"
+        func_append finalize_command " $arg"
+        compiler_flags="$compiler_flags $arg"
+        continue
+        ;;
+
+      # Some other compiler flag.
+      -* | +*)
+        func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+
+      *.$objext)
+	# A standard object.
+	objs="$objs $arg"
+	;;
+
+      *.lo)
+	# A libtool-controlled object.
+
+	# Check to see that this really is a libtool object.
+	if func_lalib_unsafe_p "$arg"; then
+	  pic_object=
+	  non_pic_object=
+
+	  # Read the .lo file
+	  func_source "$arg"
+
+	  if test -z "$pic_object" ||
+	     test -z "$non_pic_object" ||
+	     test "$pic_object" = none &&
+	     test "$non_pic_object" = none; then
+	    func_fatal_error "cannot find name of object for \`$arg'"
+	  fi
+
+	  # Extract subdirectory from the argument.
+	  func_dirname "$arg" "/" ""
+	  xdir="$func_dirname_result"
+
+	  if test "$pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    pic_object="$xdir$pic_object"
+
+	    if test "$prev" = dlfiles; then
+	      if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
+		dlfiles="$dlfiles $pic_object"
+		prev=
+		continue
+	      else
+		# If libtool objects are unsupported, then we need to preload.
+		prev=dlprefiles
+	      fi
+	    fi
+
+	    # CHECK ME:  I think I busted this.  -Ossama
+	    if test "$prev" = dlprefiles; then
+	      # Preload the old-style object.
+	      dlprefiles="$dlprefiles $pic_object"
+	      prev=
+	    fi
+
+	    # A PIC object.
+	    func_append libobjs " $pic_object"
+	    arg="$pic_object"
+	  fi
+
+	  # Non-PIC object.
+	  if test "$non_pic_object" != none; then
+	    # Prepend the subdirectory the object is found in.
+	    non_pic_object="$xdir$non_pic_object"
+
+	    # A standard non-PIC object
+	    func_append non_pic_objects " $non_pic_object"
+	    if test -z "$pic_object" || test "$pic_object" = none ; then
+	      arg="$non_pic_object"
+	    fi
+	  else
+	    # If the PIC object exists, use it instead.
+	    # $xdir was prepended to $pic_object above.
+	    non_pic_object="$pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  fi
+	else
+	  # Only an error if not doing a dry-run.
+	  if $opt_dry_run; then
+	    # Extract subdirectory from the argument.
+	    func_dirname "$arg" "/" ""
+	    xdir="$func_dirname_result"
+
+	    func_lo2o "$arg"
+	    pic_object=$xdir$objdir/$func_lo2o_result
+	    non_pic_object=$xdir$func_lo2o_result
+	    func_append libobjs " $pic_object"
+	    func_append non_pic_objects " $non_pic_object"
+	  else
+	    func_fatal_error "\`$arg' is not a valid libtool object"
+	  fi
+	fi
+	;;
+
+      *.$libext)
+	# An archive.
+	deplibs="$deplibs $arg"
+	old_deplibs="$old_deplibs $arg"
+	continue
+	;;
+
+      *.la)
+	# A libtool-controlled library.
+
+	if test "$prev" = dlfiles; then
+	  # This library was specified with -dlopen.
+	  dlfiles="$dlfiles $arg"
+	  prev=
+	elif test "$prev" = dlprefiles; then
+	  # The library was specified with -dlpreopen.
+	  dlprefiles="$dlprefiles $arg"
+	  prev=
+	else
+	  deplibs="$deplibs $arg"
+	fi
+	continue
+	;;
+
+      # Some other compiler argument.
+      *)
+	# Unknown arguments in both finalize_command and compile_command need
+	# to be aesthetically quoted because they are evaled later.
+	func_quote_for_eval "$arg"
+	arg="$func_quote_for_eval_result"
+	;;
+      esac # arg
+
+      # Now actually substitute the argument into the commands.
+      if test -n "$arg"; then
+	func_append compile_command " $arg"
+	func_append finalize_command " $arg"
+      fi
+    done # argument parsing loop
+
+    test -n "$prev" && \
+      func_fatal_help "the \`$prevarg' option requires an argument"
+
+    if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+      eval arg=\"$export_dynamic_flag_spec\"
+      func_append compile_command " $arg"
+      func_append finalize_command " $arg"
+    fi
+
+    oldlibs=
+    # calculate the name of the file, without its directory
+    func_basename "$output"
+    outputname="$func_basename_result"
+    libobjs_save="$libobjs"
+
+    if test -n "$shlibpath_var"; then
+      # get the directories listed in $shlibpath_var
+      eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+    else
+      shlib_search_path=
+    fi
+    eval sys_lib_search_path=\"$sys_lib_search_path_spec\"
+    eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+    func_dirname "$output" "/" ""
+    output_objdir="$func_dirname_result$objdir"
+    # Create the object directory.
+    func_mkdir_p "$output_objdir"
+
+    # Determine the type of output
+    case $output in
+    "")
+      func_fatal_help "you must specify an output file"
+      ;;
+    *.$libext) linkmode=oldlib ;;
+    *.lo | *.$objext) linkmode=obj ;;
+    *.la) linkmode=lib ;;
+    *) linkmode=prog ;; # Anything else should be a program.
+    esac
+
+    specialdeplibs=
+
+    libs=
+    # Find all interdependent deplibs by searching for libraries
+    # that are linked more than once (e.g. -la -lb -la)
+    for deplib in $deplibs; do
+      if $opt_duplicate_deps ; then
+	case "$libs " in
+	*" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	esac
+      fi
+      libs="$libs $deplib"
+    done
+
+    if test "$linkmode" = lib; then
+      libs="$predeps $libs $compiler_lib_search_path $postdeps"
+
+      # Compute libraries that are listed more than once in $predeps
+      # $postdeps and mark them as special (i.e., whose duplicates are
+      # not to be eliminated).
+      pre_post_deps=
+      if $opt_duplicate_compiler_generated_deps; then
+	for pre_post_dep in $predeps $postdeps; do
+	  case "$pre_post_deps " in
+	  *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+	  esac
+	  pre_post_deps="$pre_post_deps $pre_post_dep"
+	done
+      fi
+      pre_post_deps=
+    fi
+
+    deplibs=
+    newdependency_libs=
+    newlib_search_path=
+    need_relink=no # whether we're linking any uninstalled libtool libraries
+    notinst_deplibs= # not-installed libtool libraries
+    notinst_path= # paths that contain not-installed libtool libraries
+
+    case $linkmode in
+    lib)
+	passes="conv dlpreopen link"
+	for file in $dlfiles $dlprefiles; do
+	  case $file in
+	  *.la) ;;
+	  *)
+	    func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file"
+	    ;;
+	  esac
+	done
+	;;
+    prog)
+	compile_deplibs=
+	finalize_deplibs=
+	alldeplibs=no
+	newdlfiles=
+	newdlprefiles=
+	passes="conv scan dlopen dlpreopen link"
+	;;
+    *)  passes="conv"
+	;;
+    esac
+
+    for pass in $passes; do
+      # The preopen pass in lib mode reverses $deplibs; put it back here
+      # so that -L comes before libs that need it for instance...
+      if test "$linkmode,$pass" = "lib,link"; then
+	## FIXME: Find the place where the list is rebuilt in the wrong
+	##        order, and fix it there properly
+        tmp_deplibs=
+	for deplib in $deplibs; do
+	  tmp_deplibs="$deplib $tmp_deplibs"
+	done
+	deplibs="$tmp_deplibs"
+      fi
+
+      if test "$linkmode,$pass" = "lib,link" ||
+	 test "$linkmode,$pass" = "prog,scan"; then
+	libs="$deplibs"
+	deplibs=
+      fi
+      if test "$linkmode" = prog; then
+	case $pass in
+	dlopen) libs="$dlfiles" ;;
+	dlpreopen) libs="$dlprefiles" ;;
+	link) libs="$deplibs %DEPLIBS% $dependency_libs" ;;
+	esac
+      fi
+      if test "$linkmode,$pass" = "lib,dlpreopen"; then
+	# Collect and forward deplibs of preopened libtool libs
+	for lib in $dlprefiles; do
+	  # Ignore non-libtool-libs
+	  dependency_libs=
+	  case $lib in
+	  *.la)	func_source "$lib" ;;
+	  esac
+
+	  # Collect preopened libtool deplibs, except any this library
+	  # has declared as weak libs
+	  for deplib in $dependency_libs; do
+            deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+	    case " $weak_libs " in
+	    *" $deplib_base "*) ;;
+	    *) deplibs="$deplibs $deplib" ;;
+	    esac
+	  done
+	done
+	libs="$dlprefiles"
+      fi
+      if test "$pass" = dlopen; then
+	# Collect dlpreopened libraries
+	save_deplibs="$deplibs"
+	deplibs=
+      fi
+
+      for deplib in $libs; do
+	lib=
+	found=no
+	case $deplib in
+	-mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    compiler_flags="$compiler_flags $deplib"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-l*)
+	  if test "$linkmode" != lib && test "$linkmode" != prog; then
+	    func_warning "\`-l' is ignored for archives/objects"
+	    continue
+	  fi
+	  func_stripname '-l' '' "$deplib"
+	  name=$func_stripname_result
+	  if test "$linkmode" = lib; then
+	    searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path"
+	  else
+	    searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path"
+	  fi
+	  for searchdir in $searchdirs; do
+	    for search_ext in .la $std_shrext .so .a; do
+	      # Search the libtool library
+	      lib="$searchdir/lib${name}${search_ext}"
+	      if test -f "$lib"; then
+		if test "$search_ext" = ".la"; then
+		  found=yes
+		else
+		  found=no
+		fi
+		break 2
+	      fi
+	    done
+	  done
+	  if test "$found" != yes; then
+	    # deplib doesn't seem to be a libtool library
+	    if test "$linkmode,$pass" = "prog,link"; then
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      deplibs="$deplib $deplibs"
+	      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    continue
+	  else # deplib is a libtool library
+	    # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib,
+	    # We need to do some special things here, and not later.
+	    if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	      case " $predeps $postdeps " in
+	      *" $deplib "*)
+		if func_lalib_p "$lib"; then
+		  library_names=
+		  old_library=
+		  func_source "$lib"
+		  for l in $old_library $library_names; do
+		    ll="$l"
+		  done
+		  if test "X$ll" = "X$old_library" ; then # only static version available
+		    found=no
+		    func_dirname "$lib" "" "."
+		    ladir="$func_dirname_result"
+		    lib=$ladir/$old_library
+		    if test "$linkmode,$pass" = "prog,link"; then
+		      compile_deplibs="$deplib $compile_deplibs"
+		      finalize_deplibs="$deplib $finalize_deplibs"
+		    else
+		      deplibs="$deplib $deplibs"
+		      test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs"
+		    fi
+		    continue
+		  fi
+		fi
+		;;
+	      *) ;;
+	      esac
+	    fi
+	  fi
+	  ;; # -l
+	*.ltframework)
+	  if test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$deplib $compile_deplibs"
+	    finalize_deplibs="$deplib $finalize_deplibs"
+	  else
+	    deplibs="$deplib $deplibs"
+	    if test "$linkmode" = lib ; then
+		case "$new_inherited_linker_flags " in
+		    *" $deplib "*) ;;
+		    * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+		esac
+	    fi
+	  fi
+	  continue
+	  ;;
+	-L*)
+	  case $linkmode in
+	  lib)
+	    deplibs="$deplib $deplibs"
+	    test "$pass" = conv && continue
+	    newdependency_libs="$deplib $newdependency_libs"
+	    func_stripname '-L' '' "$deplib"
+	    newlib_search_path="$newlib_search_path $func_stripname_result"
+	    ;;
+	  prog)
+	    if test "$pass" = conv; then
+	      deplibs="$deplib $deplibs"
+	      continue
+	    fi
+	    if test "$pass" = scan; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    func_stripname '-L' '' "$deplib"
+	    newlib_search_path="$newlib_search_path $func_stripname_result"
+	    ;;
+	  *)
+	    func_warning "\`-L' is ignored for archives/objects"
+	    ;;
+	  esac # linkmode
+	  continue
+	  ;; # -L
+	-R*)
+	  if test "$pass" = link; then
+	    func_stripname '-R' '' "$deplib"
+	    dir=$func_stripname_result
+	    # Make sure the xrpath contains only unique directories.
+	    case "$xrpath " in
+	    *" $dir "*) ;;
+	    *) xrpath="$xrpath $dir" ;;
+	    esac
+	  fi
+	  deplibs="$deplib $deplibs"
+	  continue
+	  ;;
+	*.la) lib="$deplib" ;;
+	*.$libext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	    continue
+	  fi
+	  case $linkmode in
+	  lib)
+	    # Linking convenience modules into shared libraries is allowed,
+	    # but linking other static libraries is non-portable.
+	    case " $dlpreconveniencelibs " in
+	    *" $deplib "*) ;;
+	    *)
+	      valid_a_lib=no
+	      case $deplibs_check_method in
+		match_pattern*)
+		  set dummy $deplibs_check_method; shift
+		  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+		  if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+		    | $EGREP "$match_pattern_regex" > /dev/null; then
+		    valid_a_lib=yes
+		  fi
+		;;
+		pass_all)
+		  valid_a_lib=yes
+		;;
+	      esac
+	      if test "$valid_a_lib" != yes; then
+		$ECHO
+		$ECHO "*** Warning: Trying to link with static lib archive $deplib."
+		$ECHO "*** I have the capability to make that library automatically link in when"
+		$ECHO "*** you link to this library.  But I can only do this if you have a"
+		$ECHO "*** shared version of the library, which you do not appear to have"
+		$ECHO "*** because the file extensions .$libext of this argument makes me believe"
+		$ECHO "*** that it is just a static archive that I should not use here."
+	      else
+		$ECHO
+		$ECHO "*** Warning: Linking the shared library $output against the"
+		$ECHO "*** static library $deplib is not portable!"
+		deplibs="$deplib $deplibs"
+	      fi
+	      ;;
+	    esac
+	    continue
+	    ;;
+	  prog)
+	    if test "$pass" != link; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    fi
+	    continue
+	    ;;
+	  esac # linkmode
+	  ;; # *.$libext
+	*.lo | *.$objext)
+	  if test "$pass" = conv; then
+	    deplibs="$deplib $deplibs"
+	  elif test "$linkmode" = prog; then
+	    if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
+	      # If there is no dlopen support or we're linking statically,
+	      # we need to preload.
+	      newdlprefiles="$newdlprefiles $deplib"
+	      compile_deplibs="$deplib $compile_deplibs"
+	      finalize_deplibs="$deplib $finalize_deplibs"
+	    else
+	      newdlfiles="$newdlfiles $deplib"
+	    fi
+	  fi
+	  continue
+	  ;;
+	%DEPLIBS%)
+	  alldeplibs=yes
+	  continue
+	  ;;
+	esac # case $deplib
+
+	if test "$found" = yes || test -f "$lib"; then :
+	else
+	  func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'"
+	fi
+
+	# Check to see that this really is a libtool archive.
+	func_lalib_unsafe_p "$lib" \
+	  || func_fatal_error "\`$lib' is not a valid libtool archive"
+
+	func_dirname "$lib" "" "."
+	ladir="$func_dirname_result"
+
+	dlname=
+	dlopen=
+	dlpreopen=
+	libdir=
+	library_names=
+	old_library=
+	inherited_linker_flags=
+	# If the library was installed with an old release of libtool,
+	# it will not redefine variables installed, or shouldnotlink
+	installed=yes
+	shouldnotlink=no
+	avoidtemprpath=
+
+
+	# Read the .la file
+	func_source "$lib"
+
+	# Convert "-framework foo" to "foo.ltframework"
+	if test -n "$inherited_linker_flags"; then
+	  tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+	  for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
+	    case " $new_inherited_linker_flags " in
+	      *" $tmp_inherited_linker_flag "*) ;;
+	      *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+	    esac
+	  done
+	fi
+	dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	if test "$linkmode,$pass" = "lib,link" ||
+	   test "$linkmode,$pass" = "prog,scan" ||
+	   { test "$linkmode" != prog && test "$linkmode" != lib; }; then
+	  test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
+	  test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+	fi
+
+	if test "$pass" = conv; then
+	  # Only check for convenience libraries
+	  deplibs="$lib $deplibs"
+	  if test -z "$libdir"; then
+	    if test -z "$old_library"; then
+	      func_fatal_error "cannot find name of link library for \`$lib'"
+	    fi
+	    # It is a libtool convenience library, so add in its objects.
+	    convenience="$convenience $ladir/$objdir/$old_library"
+	    old_convenience="$old_convenience $ladir/$objdir/$old_library"
+	  elif test "$linkmode" != prog && test "$linkmode" != lib; then
+	    func_fatal_error "\`$lib' is not a convenience library"
+	  fi
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    deplibs="$deplib $deplibs"
+	    if $opt_duplicate_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+	  continue
+	fi # $pass = conv
+
+
+	# Get the name of the library we link against.
+	linklib=
+	for l in $old_library $library_names; do
+	  linklib="$l"
+	done
+	if test -z "$linklib"; then
+	  func_fatal_error "cannot find name of link library for \`$lib'"
+	fi
+
+	# This library was specified with -dlopen.
+	if test "$pass" = dlopen; then
+	  if test -z "$libdir"; then
+	    func_fatal_error "cannot -dlopen a convenience library: \`$lib'"
+	  fi
+	  if test -z "$dlname" ||
+	     test "$dlopen_support" != yes ||
+	     test "$build_libtool_libs" = no; then
+	    # If there is no dlname, no dlopen support or we're linking
+	    # statically, we need to preload.  We also need to preload any
+	    # dependent libraries so libltdl's deplib preloader doesn't
+	    # bomb out in the load deplibs phase.
+	    dlprefiles="$dlprefiles $lib $dependency_libs"
+	  else
+	    newdlfiles="$newdlfiles $lib"
+	  fi
+	  continue
+	fi # $pass = dlopen
+
+	# We need an absolute path.
+	case $ladir in
+	[\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;;
+	*)
+	  abs_ladir=`cd "$ladir" && pwd`
+	  if test -z "$abs_ladir"; then
+	    func_warning "cannot determine absolute directory name of \`$ladir'"
+	    func_warning "passing it literally to the linker, although it might fail"
+	    abs_ladir="$ladir"
+	  fi
+	  ;;
+	esac
+	func_basename "$lib"
+	laname="$func_basename_result"
+
+	# Find the relevant object directory and library name.
+	if test "X$installed" = Xyes; then
+	  if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    func_warning "library \`$lib' was moved."
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    libdir="$abs_ladir"
+	  else
+	    dir="$libdir"
+	    absdir="$libdir"
+	  fi
+	  test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
+	else
+	  if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+	    dir="$ladir"
+	    absdir="$abs_ladir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  else
+	    dir="$ladir/$objdir"
+	    absdir="$abs_ladir/$objdir"
+	    # Remove this search path later
+	    notinst_path="$notinst_path $abs_ladir"
+	  fi
+	fi # $installed = yes
+	func_stripname 'lib' '.la' "$laname"
+	name=$func_stripname_result
+
+	# This library was specified with -dlpreopen.
+	if test "$pass" = dlpreopen; then
+	  if test -z "$libdir" && test "$linkmode" = prog; then
+	    func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
+	  fi
+	  # Prefer using a static library (so that no silly _DYNAMIC symbols
+	  # are required to link).
+	  if test -n "$old_library"; then
+	    newdlprefiles="$newdlprefiles $dir/$old_library"
+	    # Keep a list of preopened convenience libraries to check
+	    # that they are being used correctly in the link pass.
+	    test -z "$libdir" && \
+		dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
+	  # Otherwise, use the dlname, so that lt_dlopen finds it.
+	  elif test -n "$dlname"; then
+	    newdlprefiles="$newdlprefiles $dir/$dlname"
+	  else
+	    newdlprefiles="$newdlprefiles $dir/$linklib"
+	  fi
+	fi # $pass = dlpreopen
+
+	if test -z "$libdir"; then
+	  # Link the convenience library
+	  if test "$linkmode" = lib; then
+	    deplibs="$dir/$old_library $deplibs"
+	  elif test "$linkmode,$pass" = "prog,link"; then
+	    compile_deplibs="$dir/$old_library $compile_deplibs"
+	    finalize_deplibs="$dir/$old_library $finalize_deplibs"
+	  else
+	    deplibs="$lib $deplibs" # used for prog,scan pass
+	  fi
+	  continue
+	fi
+
+
+	if test "$linkmode" = prog && test "$pass" != link; then
+	  newlib_search_path="$newlib_search_path $ladir"
+	  deplibs="$lib $deplibs"
+
+	  linkalldeplibs=no
+	  if test "$link_all_deplibs" != no || test -z "$library_names" ||
+	     test "$build_libtool_libs" = no; then
+	    linkalldeplibs=yes
+	  fi
+
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    case $deplib in
+	    -L*) func_stripname '-L' '' "$deplib"
+	         newlib_search_path="$newlib_search_path $func_stripname_result"
+		 ;;
+	    esac
+	    # Need to link against all dependency_libs?
+	    if test "$linkalldeplibs" = yes; then
+	      deplibs="$deplib $deplibs"
+	    else
+	      # Need to hardcode shared library paths
+	      # or/and link against static libraries
+	      newdependency_libs="$deplib $newdependency_libs"
+	    fi
+	    if $opt_duplicate_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done # for deplib
+	  continue
+	fi # $linkmode = prog...
+
+	if test "$linkmode,$pass" = "prog,link"; then
+	  if test -n "$library_names" &&
+	     { { test "$prefer_static_libs" = no ||
+	         test "$prefer_static_libs,$installed" = "built,yes"; } ||
+	       test -z "$old_library"; }; then
+	    # We need to hardcode the library path
+	    if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then
+	      # Make sure the rpath contains only unique directories.
+	      case "$temp_rpath:" in
+	      *"$absdir:"*) ;;
+	      *) temp_rpath="$temp_rpath$absdir:" ;;
+	      esac
+	    fi
+
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi # $linkmode,$pass = prog,link...
+
+	  if test "$alldeplibs" = yes &&
+	     { test "$deplibs_check_method" = pass_all ||
+	       { test "$build_libtool_libs" = yes &&
+		 test -n "$library_names"; }; }; then
+	    # We only need to search for static libraries
+	    continue
+	  fi
+	fi
+
+	link_static=no # Whether the deplib will be linked statically
+	use_static_libs=$prefer_static_libs
+	if test "$use_static_libs" = built && test "$installed" = yes; then
+	  use_static_libs=no
+	fi
+	if test -n "$library_names" &&
+	   { test "$use_static_libs" = no || test -z "$old_library"; }; then
+	  case $host in
+	  *cygwin* | *mingw* | *cegcc*)
+	      # No point in relinking DLLs because paths are not encoded
+	      notinst_deplibs="$notinst_deplibs $lib"
+	      need_relink=no
+	    ;;
+	  *)
+	    if test "$installed" = no; then
+	      notinst_deplibs="$notinst_deplibs $lib"
+	      need_relink=yes
+	    fi
+	    ;;
+	  esac
+	  # This is a shared library
+
+	  # Warn about portability, can't link against -module's on some
+	  # systems (darwin).  Don't bleat about dlopened modules though!
+	  dlopenmodule=""
+	  for dlpremoduletest in $dlprefiles; do
+	    if test "X$dlpremoduletest" = "X$lib"; then
+	      dlopenmodule="$dlpremoduletest"
+	      break
+	    fi
+	  done
+	  if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
+	    $ECHO
+	    if test "$linkmode" = prog; then
+	      $ECHO "*** Warning: Linking the executable $output against the loadable module"
+	    else
+	      $ECHO "*** Warning: Linking the shared library $output against the loadable module"
+	    fi
+	    $ECHO "*** $linklib is not portable!"
+	  fi
+	  if test "$linkmode" = lib &&
+	     test "$hardcode_into_libs" = yes; then
+	    # Hardcode the library path.
+	    # Skip directories that are in the system default run-time
+	    # search path.
+	    case " $sys_lib_dlsearch_path " in
+	    *" $absdir "*) ;;
+	    *)
+	      case "$compile_rpath " in
+	      *" $absdir "*) ;;
+	      *) compile_rpath="$compile_rpath $absdir"
+	      esac
+	      ;;
+	    esac
+	    case " $sys_lib_dlsearch_path " in
+	    *" $libdir "*) ;;
+	    *)
+	      case "$finalize_rpath " in
+	      *" $libdir "*) ;;
+	      *) finalize_rpath="$finalize_rpath $libdir"
+	      esac
+	      ;;
+	    esac
+	  fi
+
+	  if test -n "$old_archive_from_expsyms_cmds"; then
+	    # figure out the soname
+	    set dummy $library_names
+	    shift
+	    realname="$1"
+	    shift
+	    libname=`eval "\\$ECHO \"$libname_spec\""`
+	    # use dlname if we got it. it's perfectly good, no?
+	    if test -n "$dlname"; then
+	      soname="$dlname"
+	    elif test -n "$soname_spec"; then
+	      # bleh windows
+	      case $host in
+	      *cygwin* | mingw* | *cegcc*)
+	        func_arith $current - $age
+		major=$func_arith_result
+		versuffix="-$major"
+		;;
+	      esac
+	      eval soname=\"$soname_spec\"
+	    else
+	      soname="$realname"
+	    fi
+
+	    # Make a new name for the extract_expsyms_cmds to use
+	    soroot="$soname"
+	    func_basename "$soroot"
+	    soname="$func_basename_result"
+	    func_stripname 'lib' '.dll' "$soname"
+	    newlib=libimp-$func_stripname_result.a
+
+	    # If the library has no export list, then create one now
+	    if test -f "$output_objdir/$soname-def"; then :
+	    else
+	      func_verbose "extracting exported symbol list from \`$soname'"
+	      func_execute_cmds "$extract_expsyms_cmds" 'exit $?'
+	    fi
+
+	    # Create $newlib
+	    if test -f "$output_objdir/$newlib"; then :; else
+	      func_verbose "generating import library for \`$soname'"
+	      func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?'
+	    fi
+	    # make sure the library variables are pointing to the new library
+	    dir=$output_objdir
+	    linklib=$newlib
+	  fi # test -n "$old_archive_from_expsyms_cmds"
+
+	  if test "$linkmode" = prog || test "$mode" != relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    lib_linked=yes
+	    case $hardcode_action in
+	    immediate | unsupported)
+	      if test "$hardcode_direct" = no; then
+		add="$dir/$linklib"
+		case $host in
+		  *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;;
+		  *-*-sysv4*uw2*) add_dir="-L$dir" ;;
+		  *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \
+		    *-*-unixware7*) add_dir="-L$dir" ;;
+		  *-*-darwin* )
+		    # if the lib is a (non-dlopened) module then we can not
+		    # link against it, someone is ignoring the earlier warnings
+		    if /usr/bin/file -L $add 2> /dev/null |
+			 $GREP ": [^:]* bundle" >/dev/null ; then
+		      if test "X$dlopenmodule" != "X$lib"; then
+			$ECHO "*** Warning: lib $linklib is a module, not a shared library"
+			if test -z "$old_library" ; then
+			  $ECHO
+			  $ECHO "*** And there doesn't seem to be a static archive available"
+			  $ECHO "*** The link will probably fail, sorry"
+			else
+			  add="$dir/$old_library"
+			fi
+		      elif test -n "$old_library"; then
+			add="$dir/$old_library"
+		      fi
+		    fi
+		esac
+	      elif test "$hardcode_minus_L" = no; then
+		case $host in
+		*-*-sunos*) add_shlibpath="$dir" ;;
+		esac
+		add_dir="-L$dir"
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = no; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    relink)
+	      if test "$hardcode_direct" = yes &&
+	         test "$hardcode_direct_absolute" = no; then
+		add="$dir/$linklib"
+	      elif test "$hardcode_minus_L" = yes; then
+		add_dir="-L$dir"
+		# Try looking first in the location we're being installed to.
+		if test -n "$inst_prefix_dir"; then
+		  case $libdir in
+		    [\\/]*)
+		      add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		      ;;
+		  esac
+		fi
+		add="-l$name"
+	      elif test "$hardcode_shlibpath_var" = yes; then
+		add_shlibpath="$dir"
+		add="-l$name"
+	      else
+		lib_linked=no
+	      fi
+	      ;;
+	    *) lib_linked=no ;;
+	    esac
+
+	    if test "$lib_linked" != yes; then
+	      func_fatal_configuration "unsupported hardcode properties"
+	    fi
+
+	    if test -n "$add_shlibpath"; then
+	      case :$compile_shlibpath: in
+	      *":$add_shlibpath:"*) ;;
+	      *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+	      esac
+	    fi
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs"
+	      test -n "$add" && compile_deplibs="$add $compile_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	      if test "$hardcode_direct" != yes &&
+		 test "$hardcode_minus_L" != yes &&
+		 test "$hardcode_shlibpath_var" = yes; then
+		case :$finalize_shlibpath: in
+		*":$libdir:"*) ;;
+		*) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+		esac
+	      fi
+	    fi
+	  fi
+
+	  if test "$linkmode" = prog || test "$mode" = relink; then
+	    add_shlibpath=
+	    add_dir=
+	    add=
+	    # Finalize command for both is simple: just hardcode it.
+	    if test "$hardcode_direct" = yes &&
+	       test "$hardcode_direct_absolute" = no; then
+	      add="$libdir/$linklib"
+	    elif test "$hardcode_minus_L" = yes; then
+	      add_dir="-L$libdir"
+	      add="-l$name"
+	    elif test "$hardcode_shlibpath_var" = yes; then
+	      case :$finalize_shlibpath: in
+	      *":$libdir:"*) ;;
+	      *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+	      esac
+	      add="-l$name"
+	    elif test "$hardcode_automatic" = yes; then
+	      if test -n "$inst_prefix_dir" &&
+		 test -f "$inst_prefix_dir$libdir/$linklib" ; then
+		add="$inst_prefix_dir$libdir/$linklib"
+	      else
+		add="$libdir/$linklib"
+	      fi
+	    else
+	      # We cannot seem to hardcode it, guess we'll fake it.
+	      add_dir="-L$libdir"
+	      # Try looking first in the location we're being installed to.
+	      if test -n "$inst_prefix_dir"; then
+		case $libdir in
+		  [\\/]*)
+		    add_dir="$add_dir -L$inst_prefix_dir$libdir"
+		    ;;
+		esac
+	      fi
+	      add="-l$name"
+	    fi
+
+	    if test "$linkmode" = prog; then
+	      test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs"
+	      test -n "$add" && finalize_deplibs="$add $finalize_deplibs"
+	    else
+	      test -n "$add_dir" && deplibs="$add_dir $deplibs"
+	      test -n "$add" && deplibs="$add $deplibs"
+	    fi
+	  fi
+	elif test "$linkmode" = prog; then
+	  # Here we assume that one of hardcode_direct or hardcode_minus_L
+	  # is not unsupported.  This is valid on all known static and
+	  # shared platforms.
+	  if test "$hardcode_direct" != unsupported; then
+	    test -n "$old_library" && linklib="$old_library"
+	    compile_deplibs="$dir/$linklib $compile_deplibs"
+	    finalize_deplibs="$dir/$linklib $finalize_deplibs"
+	  else
+	    compile_deplibs="-l$name -L$dir $compile_deplibs"
+	    finalize_deplibs="-l$name -L$dir $finalize_deplibs"
+	  fi
+	elif test "$build_libtool_libs" = yes; then
+	  # Not a shared library
+	  if test "$deplibs_check_method" != pass_all; then
+	    # We're trying link a shared library against a static one
+	    # but the system doesn't support it.
+
+	    # Just print a warning and add the library to dependency_libs so
+	    # that the program can be linked against the static library.
+	    $ECHO
+	    $ECHO "*** Warning: This system can not link to static lib archive $lib."
+	    $ECHO "*** I have the capability to make that library automatically link in when"
+	    $ECHO "*** you link to this library.  But I can only do this if you have a"
+	    $ECHO "*** shared version of the library, which you do not appear to have."
+	    if test "$module" = yes; then
+	      $ECHO "*** But as you try to build a module library, libtool will still create "
+	      $ECHO "*** a static module, that should work as long as the dlopening application"
+	      $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+	      if test -z "$global_symbol_pipe"; then
+		$ECHO
+		$ECHO "*** However, this would only work if libtool was able to extract symbol"
+		$ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+		$ECHO "*** not find such a program.  So, this module is probably useless."
+		$ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+	      fi
+	      if test "$build_old_libs" = no; then
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  else
+	    deplibs="$dir/$old_library $deplibs"
+	    link_static=yes
+	  fi
+	fi # link shared/static library?
+
+	if test "$linkmode" = lib; then
+	  if test -n "$dependency_libs" &&
+	     { test "$hardcode_into_libs" != yes ||
+	       test "$build_old_libs" = yes ||
+	       test "$link_static" = yes; }; then
+	    # Extract -R from dependency_libs
+	    temp_deplibs=
+	    for libdir in $dependency_libs; do
+	      case $libdir in
+	      -R*) func_stripname '-R' '' "$libdir"
+	           temp_xrpath=$func_stripname_result
+		   case " $xrpath " in
+		   *" $temp_xrpath "*) ;;
+		   *) xrpath="$xrpath $temp_xrpath";;
+		   esac;;
+	      *) temp_deplibs="$temp_deplibs $libdir";;
+	      esac
+	    done
+	    dependency_libs="$temp_deplibs"
+	  fi
+
+	  newlib_search_path="$newlib_search_path $absdir"
+	  # Link against this library
+	  test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
+	  # ... and its dependency_libs
+	  tmp_libs=
+	  for deplib in $dependency_libs; do
+	    newdependency_libs="$deplib $newdependency_libs"
+	    if $opt_duplicate_deps ; then
+	      case "$tmp_libs " in
+	      *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+	      esac
+	    fi
+	    tmp_libs="$tmp_libs $deplib"
+	  done
+
+	  if test "$link_all_deplibs" != no; then
+	    # Add the search paths of all dependency libraries
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      -L*) path="$deplib" ;;
+	      *.la)
+	        func_dirname "$deplib" "" "."
+		dir="$func_dirname_result"
+		# We need an absolute path.
+		case $dir in
+		[\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+		*)
+		  absdir=`cd "$dir" && pwd`
+		  if test -z "$absdir"; then
+		    func_warning "cannot determine absolute directory name of \`$dir'"
+		    absdir="$dir"
+		  fi
+		  ;;
+		esac
+		if $GREP "^installed=no" $deplib > /dev/null; then
+		case $host in
+		*-*-darwin*)
+		  depdepl=
+		  eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib`
+		  if test -n "$deplibrary_names" ; then
+		    for tmp in $deplibrary_names ; do
+		      depdepl=$tmp
+		    done
+		    if test -f "$absdir/$objdir/$depdepl" ; then
+		      depdepl="$absdir/$objdir/$depdepl"
+		      darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'`
+                      if test -z "$darwin_install_name"; then
+                          darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
+                      fi
+		      compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+		      linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+		      path=
+		    fi
+		  fi
+		  ;;
+		*)
+		  path="-L$absdir/$objdir"
+		  ;;
+		esac
+		else
+		  eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		  test -z "$libdir" && \
+		    func_fatal_error "\`$deplib' is not a valid libtool archive"
+		  test "$absdir" != "$libdir" && \
+		    func_warning "\`$deplib' seems to be moved"
+
+		  path="-L$absdir"
+		fi
+		;;
+	      esac
+	      case " $deplibs " in
+	      *" $path "*) ;;
+	      *) deplibs="$path $deplibs" ;;
+	      esac
+	    done
+	  fi # link_all_deplibs != no
+	fi # linkmode = lib
+      done # for deplib in $libs
+      if test "$pass" = link; then
+	if test "$linkmode" = "prog"; then
+	  compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
+	  finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
+	else
+	  compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	fi
+      fi
+      dependency_libs="$newdependency_libs"
+      if test "$pass" = dlpreopen; then
+	# Link the dlpreopened libraries before other libraries
+	for deplib in $save_deplibs; do
+	  deplibs="$deplib $deplibs"
+	done
+      fi
+      if test "$pass" != dlopen; then
+	if test "$pass" != conv; then
+	  # Make sure lib_search_path contains only unique directories.
+	  lib_search_path=
+	  for dir in $newlib_search_path; do
+	    case "$lib_search_path " in
+	    *" $dir "*) ;;
+	    *) lib_search_path="$lib_search_path $dir" ;;
+	    esac
+	  done
+	  newlib_search_path=
+	fi
+
+	if test "$linkmode,$pass" != "prog,link"; then
+	  vars="deplibs"
+	else
+	  vars="compile_deplibs finalize_deplibs"
+	fi
+	for var in $vars dependency_libs; do
+	  # Add libraries to $var in reverse order
+	  eval tmp_libs=\"\$$var\"
+	  new_libs=
+	  for deplib in $tmp_libs; do
+	    # FIXME: Pedantically, this is the right thing to do, so
+	    #        that some nasty dependency loop isn't accidentally
+	    #        broken:
+	    #new_libs="$deplib $new_libs"
+	    # Pragmatically, this seems to cause very few problems in
+	    # practice:
+	    case $deplib in
+	    -L*) new_libs="$deplib $new_libs" ;;
+	    -R*) ;;
+	    *)
+	      # And here is the reason: when a library appears more
+	      # than once as an explicit dependence of a library, or
+	      # is implicitly linked in more than once by the
+	      # compiler, it is considered special, and multiple
+	      # occurrences thereof are not removed.  Compare this
+	      # with having the same library being listed as a
+	      # dependency of multiple other libraries: in this case,
+	      # we know (pedantically, we assume) the library does not
+	      # need to be listed more than once, so we keep only the
+	      # last copy.  This is not always right, but it is rare
+	      # enough that we require users that really mean to play
+	      # such unportable linking tricks to link the library
+	      # using -Wl,-lname, so that libtool does not consider it
+	      # for duplicate removal.
+	      case " $specialdeplibs " in
+	      *" $deplib "*) new_libs="$deplib $new_libs" ;;
+	      *)
+		case " $new_libs " in
+		*" $deplib "*) ;;
+		*) new_libs="$deplib $new_libs" ;;
+		esac
+		;;
+	      esac
+	      ;;
+	    esac
+	  done
+	  tmp_libs=
+	  for deplib in $new_libs; do
+	    case $deplib in
+	    -L*)
+	      case " $tmp_libs " in
+	      *" $deplib "*) ;;
+	      *) tmp_libs="$tmp_libs $deplib" ;;
+	      esac
+	      ;;
+	    *) tmp_libs="$tmp_libs $deplib" ;;
+	    esac
+	  done
+	  eval $var=\"$tmp_libs\"
+	done # for var
+      fi
+      # Last step: remove runtime libs from dependency_libs
+      # (they stay in deplibs)
+      tmp_libs=
+      for i in $dependency_libs ; do
+	case " $predeps $postdeps $compiler_lib_search_path " in
+	*" $i "*)
+	  i=""
+	  ;;
+	esac
+	if test -n "$i" ; then
+	  tmp_libs="$tmp_libs $i"
+	fi
+      done
+      dependency_libs=$tmp_libs
+    done # for pass
+    if test "$linkmode" = prog; then
+      dlfiles="$newdlfiles"
+    fi
+    if test "$linkmode" = prog || test "$linkmode" = lib; then
+      dlprefiles="$newdlprefiles"
+    fi
+
+    case $linkmode in
+    oldlib)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for archives"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for archives" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for archives"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for archives"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info/-version-number' is ignored for archives"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for archives"
+
+      test -n "$export_symbols$export_symbols_regex" && \
+	func_warning "\`-export-symbols' is ignored for archives"
+
+      # Now set the variables for building old libraries.
+      build_libtool_libs=no
+      oldlibs="$output"
+      objs="$objs$old_deplibs"
+      ;;
+
+    lib)
+      # Make sure we only generate libraries of the form `libNAME.la'.
+      case $outputname in
+      lib*)
+	func_stripname 'lib' '.la' "$outputname"
+	name=$func_stripname_result
+	eval shared_ext=\"$shrext_cmds\"
+	eval libname=\"$libname_spec\"
+	;;
+      *)
+	test "$module" = no && \
+	  func_fatal_help "libtool library \`$output' must begin with \`lib'"
+
+	if test "$need_lib_prefix" != no; then
+	  # Add the "lib" prefix for modules if required
+	  func_stripname '' '.la' "$outputname"
+	  name=$func_stripname_result
+	  eval shared_ext=\"$shrext_cmds\"
+	  eval libname=\"$libname_spec\"
+	else
+	  func_stripname '' '.la' "$outputname"
+	  libname=$func_stripname_result
+	fi
+	;;
+      esac
+
+      if test -n "$objs"; then
+	if test "$deplibs_check_method" != pass_all; then
+	  func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
+	else
+	  $ECHO
+	  $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
+	  $ECHO "*** objects $objs is not portable!"
+	  libobjs="$libobjs $objs"
+	fi
+      fi
+
+      test "$dlself" != no && \
+	func_warning "\`-dlopen self' is ignored for libtool libraries"
+
+      set dummy $rpath
+      shift
+      test "$#" -gt 1 && \
+	func_warning "ignoring multiple \`-rpath's for a libtool library"
+
+      install_libdir="$1"
+
+      oldlibs=
+      if test -z "$rpath"; then
+	if test "$build_libtool_libs" = yes; then
+	  # Building a libtool convenience library.
+	  # Some compilers have problems with a `.al' extension so
+	  # convenience libraries should have the same extension an
+	  # archive normally would.
+	  oldlibs="$output_objdir/$libname.$libext $oldlibs"
+	  build_libtool_libs=convenience
+	  build_old_libs=yes
+	fi
+
+	test -n "$vinfo" && \
+	  func_warning "\`-version-info/-version-number' is ignored for convenience libraries"
+
+	test -n "$release" && \
+	  func_warning "\`-release' is ignored for convenience libraries"
+      else
+
+	# Parse the version information argument.
+	save_ifs="$IFS"; IFS=':'
+	set dummy $vinfo 0 0 0
+	shift
+	IFS="$save_ifs"
+
+	test -n "$7" && \
+	  func_fatal_help "too many parameters to \`-version-info'"
+
+	# convert absolute version numbers to libtool ages
+	# this retains compatibility with .la files and attempts
+	# to make the code below a bit more comprehensible
+
+	case $vinfo_number in
+	yes)
+	  number_major="$1"
+	  number_minor="$2"
+	  number_revision="$3"
+	  #
+	  # There are really only two kinds -- those that
+	  # use the current revision as the major version
+	  # and those that subtract age and use age as
+	  # a minor version.  But, then there is irix
+	  # which has an extra 1 added just for fun
+	  #
+	  case $version_type in
+	  darwin|linux|osf|windows|none)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_revision"
+	    ;;
+	  freebsd-aout|freebsd-elf|sunos)
+	    current="$number_major"
+	    revision="$number_minor"
+	    age="0"
+	    ;;
+	  irix|nonstopux)
+	    func_arith $number_major + $number_minor
+	    current=$func_arith_result
+	    age="$number_minor"
+	    revision="$number_minor"
+	    lt_irix_increment=no
+	    ;;
+	  esac
+	  ;;
+	no)
+	  current="$1"
+	  revision="$2"
+	  age="$3"
+	  ;;
+	esac
+
+	# Check that each of the things are valid numbers.
+	case $current in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "CURRENT \`$current' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $revision in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "REVISION \`$revision' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	case $age in
+	0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;;
+	*)
+	  func_error "AGE \`$age' must be a nonnegative integer"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	  ;;
+	esac
+
+	if test "$age" -gt "$current"; then
+	  func_error "AGE \`$age' is greater than the current interface number \`$current'"
+	  func_fatal_error "\`$vinfo' is not valid version information"
+	fi
+
+	# Calculate the version variables.
+	major=
+	versuffix=
+	verstring=
+	case $version_type in
+	none) ;;
+
+	darwin)
+	  # Like Linux, but with the current version available in
+	  # verstring for coding it into the library header
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  # Darwin ld doesn't like 0 for these options...
+	  func_arith $current + 1
+	  minor_current=$func_arith_result
+	  xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision"
+	  verstring="-compatibility_version $minor_current -current_version $minor_current.$revision"
+	  ;;
+
+	freebsd-aout)
+	  major=".$current"
+	  versuffix=".$current.$revision";
+	  ;;
+
+	freebsd-elf)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	irix | nonstopux)
+	  if test "X$lt_irix_increment" = "Xno"; then
+	    func_arith $current - $age
+	  else
+	    func_arith $current - $age + 1
+	  fi
+	  major=$func_arith_result
+
+	  case $version_type in
+	    nonstopux) verstring_prefix=nonstopux ;;
+	    *)         verstring_prefix=sgi ;;
+	  esac
+	  verstring="$verstring_prefix$major.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$revision
+	  while test "$loop" -ne 0; do
+	    func_arith $revision - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring_prefix$major.$iface:$verstring"
+	  done
+
+	  # Before this point, $major must not contain `.'.
+	  major=.$major
+	  versuffix="$major.$revision"
+	  ;;
+
+	linux)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix="$major.$age.$revision"
+	  ;;
+
+	osf)
+	  func_arith $current - $age
+	  major=.$func_arith_result
+	  versuffix=".$current.$age.$revision"
+	  verstring="$current.$age.$revision"
+
+	  # Add in all the interfaces that we are compatible with.
+	  loop=$age
+	  while test "$loop" -ne 0; do
+	    func_arith $current - $loop
+	    iface=$func_arith_result
+	    func_arith $loop - 1
+	    loop=$func_arith_result
+	    verstring="$verstring:${iface}.0"
+	  done
+
+	  # Make executables depend on our current version.
+	  verstring="$verstring:${current}.0"
+	  ;;
+
+	qnx)
+	  major=".$current"
+	  versuffix=".$current"
+	  ;;
+
+	sunos)
+	  major=".$current"
+	  versuffix=".$current.$revision"
+	  ;;
+
+	windows)
+	  # Use '-' rather than '.', since we only want one
+	  # extension on DOS 8.3 filesystems.
+	  func_arith $current - $age
+	  major=$func_arith_result
+	  versuffix="-$major"
+	  ;;
+
+	*)
+	  func_fatal_configuration "unknown library version type \`$version_type'"
+	  ;;
+	esac
+
+	# Clear the version info if we defaulted, and they specified a release.
+	if test -z "$vinfo" && test -n "$release"; then
+	  major=
+	  case $version_type in
+	  darwin)
+	    # we can't check for "0.0" in archive_cmds due to quoting
+	    # problems, so we reset it completely
+	    verstring=
+	    ;;
+	  *)
+	    verstring="0.0"
+	    ;;
+	  esac
+	  if test "$need_version" = no; then
+	    versuffix=
+	  else
+	    versuffix=".0.0"
+	  fi
+	fi
+
+	# Remove version info from name if versioning should be avoided
+	if test "$avoid_version" = yes && test "$need_version" = no; then
+	  major=
+	  versuffix=
+	  verstring=""
+	fi
+
+	# Check to see if the archive will have undefined symbols.
+	if test "$allow_undefined" = yes; then
+	  if test "$allow_undefined_flag" = unsupported; then
+	    func_warning "undefined symbols not allowed in $host shared libraries"
+	    build_libtool_libs=no
+	    build_old_libs=yes
+	  fi
+	else
+	  # Don't allow undefined symbols.
+	  allow_undefined_flag="$no_undefined_flag"
+	fi
+
+      fi
+
+      func_generate_dlsyms "$libname" "$libname" "yes"
+      libobjs="$libobjs $symfileobj"
+      test "X$libobjs" = "X " && libobjs=
+
+      if test "$mode" != relink; then
+	# Remove our outputs, but don't remove object files since they
+	# may have been created when compiling PIC objects.
+	removelist=
+	tempremovelist=`$ECHO "$output_objdir/*"`
+	for p in $tempremovelist; do
+	  case $p in
+	    *.$objext | *.gcno)
+	       ;;
+	    $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*)
+	       if test "X$precious_files_regex" != "X"; then
+		 if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1
+		 then
+		   continue
+		 fi
+	       fi
+	       removelist="$removelist $p"
+	       ;;
+	    *) ;;
+	  esac
+	done
+	test -n "$removelist" && \
+	  func_show_eval "${RM}r \$removelist"
+      fi
+
+      # Now set the variables for building old libraries.
+      if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+	oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+	# Transform .lo files to .o files.
+	oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+      fi
+
+      # Eliminate all temporary directories.
+      #for path in $notinst_path; do
+      #	lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
+      #	deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
+      #	dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+      #done
+
+      if test -n "$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	temp_xrpath=
+	for libdir in $xrpath; do
+	  temp_xrpath="$temp_xrpath -R$libdir"
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+	if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
+	  dependency_libs="$temp_xrpath $dependency_libs"
+	fi
+      fi
+
+      # Make sure dlfiles contains only unique files that won't be dlpreopened
+      old_dlfiles="$dlfiles"
+      dlfiles=
+      for lib in $old_dlfiles; do
+	case " $dlprefiles $dlfiles " in
+	*" $lib "*) ;;
+	*) dlfiles="$dlfiles $lib" ;;
+	esac
+      done
+
+      # Make sure dlprefiles contains only unique files
+      old_dlprefiles="$dlprefiles"
+      dlprefiles=
+      for lib in $old_dlprefiles; do
+	case "$dlprefiles " in
+	*" $lib "*) ;;
+	*) dlprefiles="$dlprefiles $lib" ;;
+	esac
+      done
+
+      if test "$build_libtool_libs" = yes; then
+	if test -n "$rpath"; then
+	  case $host in
+	  *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+	    # these systems don't actually have a c library (as such)!
+	    ;;
+	  *-*-rhapsody* | *-*-darwin1.[012])
+	    # Rhapsody C library is in the System framework
+	    deplibs="$deplibs System.ltframework"
+	    ;;
+	  *-*-netbsd*)
+	    # Don't link with libc until the a.out ld.so is fixed.
+	    ;;
+	  *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*)
+	    # Do not include libc due to us having libc/libc_r.
+	    ;;
+	  *-*-sco3.2v5* | *-*-sco5v6*)
+	    # Causes problems with __ctype
+	    ;;
+	  *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*)
+	    # Compiler inserts libc in the correct place for threads to work
+	    ;;
+	  *)
+	    # Add libc to deplibs on all other systems if necessary.
+	    if test "$build_libtool_need_lc" = "yes"; then
+	      deplibs="$deplibs -lc"
+	    fi
+	    ;;
+	  esac
+	fi
+
+	# Transform deplibs into only deplibs that can be linked in shared.
+	name_save=$name
+	libname_save=$libname
+	release_save=$release
+	versuffix_save=$versuffix
+	major_save=$major
+	# I'm not sure if I'm treating the release correctly.  I think
+	# release should show up in the -l (ie -lgmp5) so we don't want to
+	# add it in twice.  Is that correct?
+	release=""
+	versuffix=""
+	major=""
+	newdeplibs=
+	droppeddeps=no
+	case $deplibs_check_method in
+	pass_all)
+	  # Don't check for shared/static.  Everything works.
+	  # This might be a little naive.  We might want to check
+	  # whether the library exists or not.  But this is on
+	  # osf3 & osf4 and I'm not really sure... Just
+	  # implementing what was already the behavior.
+	  newdeplibs=$deplibs
+	  ;;
+	test_compile)
+	  # This code stresses the "libraries are programs" paradigm to its
+	  # limits. Maybe even breaks it.  We compile a program, linking it
+	  # against the deplibs as a proxy for the library.  Then we can check
+	  # whether they linked in statically or dynamically with ldd.
+	  $opt_dry_run || $RM conftest.c
+	  cat > conftest.c <<EOF
+	  int main() { return 0; }
+EOF
+	  $opt_dry_run || $RM conftest
+	  if $LTCC $LTCFLAGS -o conftest conftest.c $deplibs; then
+	    ldd_output=`ldd conftest`
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		  case " $predeps $postdeps " in
+		  *" $i "*)
+		    newdeplibs="$newdeplibs $i"
+		    i=""
+		    ;;
+		  esac
+		fi
+		if test -n "$i" ; then
+		  libname=`eval "\\$ECHO \"$libname_spec\""`
+		  deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		  set dummy $deplib_matches; shift
+		  deplib_match=$1
+		  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		    newdeplibs="$newdeplibs $i"
+		  else
+		    droppeddeps=yes
+		    $ECHO
+		    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		    $ECHO "*** I have the capability to make that library automatically link in when"
+		    $ECHO "*** you link to this library.  But I can only do this if you have a"
+		    $ECHO "*** shared version of the library, which I believe you do not have"
+		    $ECHO "*** because a test_compile did reveal that the linker did not use it for"
+		    $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+		  fi
+		fi
+		;;
+	      *)
+		newdeplibs="$newdeplibs $i"
+		;;
+	      esac
+	    done
+	  else
+	    # Error occurred in the first compile.  Let's try to salvage
+	    # the situation: Compile a separate program for each library.
+	    for i in $deplibs; do
+	      case $i in
+	      -l*)
+		func_stripname -l '' "$i"
+		name=$func_stripname_result
+		$opt_dry_run || $RM conftest
+		if $LTCC $LTCFLAGS -o conftest conftest.c $i; then
+		  ldd_output=`ldd conftest`
+		  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		    case " $predeps $postdeps " in
+		    *" $i "*)
+		      newdeplibs="$newdeplibs $i"
+		      i=""
+		      ;;
+		    esac
+		  fi
+		  if test -n "$i" ; then
+		    libname=`eval "\\$ECHO \"$libname_spec\""`
+		    deplib_matches=`eval "\\$ECHO \"$library_names_spec\""`
+		    set dummy $deplib_matches; shift
+		    deplib_match=$1
+		    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+		      newdeplibs="$newdeplibs $i"
+		    else
+		      droppeddeps=yes
+		      $ECHO
+		      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
+		      $ECHO "*** I have the capability to make that library automatically link in when"
+		      $ECHO "*** you link to this library.  But I can only do this if you have a"
+		      $ECHO "*** shared version of the library, which you do not appear to have"
+		      $ECHO "*** because a test_compile did reveal that the linker did not use this one"
+		      $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+		    fi
+		  fi
+		else
+		  droppeddeps=yes
+		  $ECHO
+		  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
+		  $ECHO "*** make it link in!  You will probably need to install it or some"
+		  $ECHO "*** library that it depends on before this library will be fully"
+		  $ECHO "*** functional.  Installing it before continuing would be even better."
+		fi
+		;;
+	      *)
+		newdeplibs="$newdeplibs $i"
+		;;
+	      esac
+	    done
+	  fi
+	  ;;
+	file_magic*)
+	  set dummy $deplibs_check_method; shift
+	  file_magic_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		      # Follow soft links.
+		      if ls -lLd "$potent_lib" 2>/dev/null |
+			 $GREP " -> " >/dev/null; then
+			continue
+		      fi
+		      # The statement above tries to avoid entering an
+		      # endless loop below, in case of cyclic links.
+		      # We might still enter an endless loop, since a link
+		      # loop can be closed while we follow links,
+		      # but so what?
+		      potlib="$potent_lib"
+		      while test -h "$potlib" 2>/dev/null; do
+			potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
+			case $potliblink in
+			[\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+			*) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+			esac
+		      done
+		      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
+			 $SED -e 10q |
+			 $EGREP "$file_magic_regex" > /dev/null; then
+			newdeplibs="$newdeplibs $a_deplib"
+			a_deplib=""
+			break 2
+		      fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$ECHO
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		$ECHO "*** I have the capability to make that library automatically link in when"
+		$ECHO "*** you link to this library.  But I can only do this if you have a"
+		$ECHO "*** shared version of the library, which you do not appear to have"
+		$ECHO "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a file magic. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	match_pattern*)
+	  set dummy $deplibs_check_method; shift
+	  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
+	  for a_deplib in $deplibs; do
+	    case $a_deplib in
+	    -l*)
+	      func_stripname -l '' "$a_deplib"
+	      name=$func_stripname_result
+	      if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+		case " $predeps $postdeps " in
+		*" $a_deplib "*)
+		  newdeplibs="$newdeplibs $a_deplib"
+		  a_deplib=""
+		  ;;
+		esac
+	      fi
+	      if test -n "$a_deplib" ; then
+		libname=`eval "\\$ECHO \"$libname_spec\""`
+		for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
+		  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+		  for potent_lib in $potential_libs; do
+		    potlib="$potent_lib" # see symlink-check above in file_magic test
+		    if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+		       $EGREP "$match_pattern_regex" > /dev/null; then
+		      newdeplibs="$newdeplibs $a_deplib"
+		      a_deplib=""
+		      break 2
+		    fi
+		  done
+		done
+	      fi
+	      if test -n "$a_deplib" ; then
+		droppeddeps=yes
+		$ECHO
+		$ECHO "*** Warning: linker path does not have real file for library $a_deplib."
+		$ECHO "*** I have the capability to make that library automatically link in when"
+		$ECHO "*** you link to this library.  But I can only do this if you have a"
+		$ECHO "*** shared version of the library, which you do not appear to have"
+		$ECHO "*** because I did check the linker path looking for a file starting"
+		if test -z "$potlib" ; then
+		  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
+		else
+		  $ECHO "*** with $libname and none of the candidates passed a file format test"
+		  $ECHO "*** using a regex pattern. Last file checked: $potlib"
+		fi
+	      fi
+	      ;;
+	    *)
+	      # Add a -L argument.
+	      newdeplibs="$newdeplibs $a_deplib"
+	      ;;
+	    esac
+	  done # Gone through all deplibs.
+	  ;;
+	none | unknown | *)
+	  newdeplibs=""
+	  tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
+	      -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+	  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
+	    for i in $predeps $postdeps ; do
+	      # can't use Xsed below, because $i might contain '/'
+	      tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+	    done
+	  fi
+	  if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[	 ]//g' |
+	     $GREP . >/dev/null; then
+	    $ECHO
+	    if test "X$deplibs_check_method" = "Xnone"; then
+	      $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+	    else
+	      $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+	    fi
+	    $ECHO "*** All declared inter-library dependencies are being dropped."
+	    droppeddeps=yes
+	  fi
+	  ;;
+	esac
+	versuffix=$versuffix_save
+	major=$major_save
+	release=$release_save
+	libname=$libname_save
+	name=$name_save
+
+	case $host in
+	*-*-rhapsody* | *-*-darwin1.[012])
+	  # On Rhapsody replace the C library with the System framework
+	  newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+	  ;;
+	esac
+
+	if test "$droppeddeps" = yes; then
+	  if test "$module" = yes; then
+	    $ECHO
+	    $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+	    $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
+	    $ECHO "*** a static module, that should work as long as the dlopening"
+	    $ECHO "*** application is linked with the -dlopen flag."
+	    if test -z "$global_symbol_pipe"; then
+	      $ECHO
+	      $ECHO "*** However, this would only work if libtool was able to extract symbol"
+	      $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
+	      $ECHO "*** not find such a program.  So, this module is probably useless."
+	      $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+	    fi
+	    if test "$build_old_libs" = no; then
+	      oldlibs="$output_objdir/$libname.$libext"
+	      build_libtool_libs=module
+	      build_old_libs=yes
+	    else
+	      build_libtool_libs=no
+	    fi
+	  else
+	    $ECHO "*** The inter-library dependencies that have been dropped here will be"
+	    $ECHO "*** automatically added whenever a program is linked with this library"
+	    $ECHO "*** or is declared to -dlopen it."
+
+	    if test "$allow_undefined" = no; then
+	      $ECHO
+	      $ECHO "*** Since this library must not contain undefined symbols,"
+	      $ECHO "*** because either the platform does not support them or"
+	      $ECHO "*** it was explicitly requested with -no-undefined,"
+	      $ECHO "*** libtool will only create a static version of it."
+	      if test "$build_old_libs" = no; then
+		oldlibs="$output_objdir/$libname.$libext"
+		build_libtool_libs=module
+		build_old_libs=yes
+	      else
+		build_libtool_libs=no
+	      fi
+	    fi
+	  fi
+	fi
+	# Done checking deplibs!
+	deplibs=$newdeplibs
+      fi
+      # Time to change all our "foo.ltframework" stuff back to "-framework foo"
+      case $host in
+	*-*-darwin*)
+	  newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	  ;;
+      esac
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      deplibs="$new_libs"
+
+      # All the library-specific variables (install_libdir is set above).
+      library_names=
+      old_library=
+      dlname=
+
+      # Test again, we may have decided not to build it any more
+      if test "$build_libtool_libs" = yes; then
+	if test "$hardcode_into_libs" = yes; then
+	  # Hardcode the library paths
+	  hardcode_libdirs=
+	  dep_rpath=
+	  rpath="$finalize_rpath"
+	  test "$mode" != relink && rpath="$compile_rpath$rpath"
+	  for libdir in $rpath; do
+	    if test -n "$hardcode_libdir_flag_spec"; then
+	      if test -n "$hardcode_libdir_separator"; then
+		if test -z "$hardcode_libdirs"; then
+		  hardcode_libdirs="$libdir"
+		else
+		  # Just accumulate the unique libdirs.
+		  case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+		  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		    ;;
+		  *)
+		    hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		    ;;
+		  esac
+		fi
+	      else
+		eval flag=\"$hardcode_libdir_flag_spec\"
+		dep_rpath="$dep_rpath $flag"
+	      fi
+	    elif test -n "$runpath_var"; then
+	      case "$perm_rpath " in
+	      *" $libdir "*) ;;
+	      *) perm_rpath="$perm_rpath $libdir" ;;
+	      esac
+	    fi
+	  done
+	  # Substitute the hardcoded libdirs into the rpath.
+	  if test -n "$hardcode_libdir_separator" &&
+	     test -n "$hardcode_libdirs"; then
+	    libdir="$hardcode_libdirs"
+	    if test -n "$hardcode_libdir_flag_spec_ld"; then
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
+	    else
+	      eval dep_rpath=\"$hardcode_libdir_flag_spec\"
+	    fi
+	  fi
+	  if test -n "$runpath_var" && test -n "$perm_rpath"; then
+	    # We should set the runpath_var.
+	    rpath=
+	    for dir in $perm_rpath; do
+	      rpath="$rpath$dir:"
+	    done
+	    eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
+	  fi
+	  test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs"
+	fi
+
+	shlibpath="$finalize_shlibpath"
+	test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+	if test -n "$shlibpath"; then
+	  eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
+	fi
+
+	# Get the real and link names of the library.
+	eval shared_ext=\"$shrext_cmds\"
+	eval library_names=\"$library_names_spec\"
+	set dummy $library_names
+	shift
+	realname="$1"
+	shift
+
+	if test -n "$soname_spec"; then
+	  eval soname=\"$soname_spec\"
+	else
+	  soname="$realname"
+	fi
+	if test -z "$dlname"; then
+	  dlname=$soname
+	fi
+
+	lib="$output_objdir/$realname"
+	linknames=
+	for link
+	do
+	  linknames="$linknames $link"
+	done
+
+	# Use standard objects if they are pic
+	test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	test "X$libobjs" = "X " && libobjs=
+
+	delfiles=
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
+	  export_symbols="$output_objdir/$libname.uexp"
+	  delfiles="$delfiles $export_symbols"
+	fi
+
+	orig_export_symbols=
+	case $host_os in
+	cygwin* | mingw* | cegcc*)
+	  if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
+	    # exporting using user supplied symfile
+	    if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+	      # and it's NOT already a .def file. Must figure out
+	      # which of the given symbols are data symbols and tag
+	      # them as such. So, trigger use of export_symbols_cmds.
+	      # export_symbols gets reassigned inside the "prepare
+	      # the list of exported symbols" if statement, so the
+	      # include_expsyms logic still works.
+	      orig_export_symbols="$export_symbols"
+	      export_symbols=
+	      always_export_symbols=yes
+	    fi
+	  fi
+	  ;;
+	esac
+
+	# Prepare the list of exported symbols
+	if test -z "$export_symbols"; then
+	  if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+	    func_verbose "generating symbol list for \`$libname.la'"
+	    export_symbols="$output_objdir/$libname.exp"
+	    $opt_dry_run || $RM $export_symbols
+	    cmds=$export_symbols_cmds
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $cmds; do
+	      IFS="$save_ifs"
+	      eval cmd=\"$cmd\"
+	      func_len " $cmd"
+	      len=$func_len_result
+	      if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+		func_show_eval "$cmd" 'exit $?'
+		skipped_export=false
+	      else
+		# The command line is too long to execute in one step.
+		func_verbose "using reloadable object file for export list..."
+		skipped_export=:
+		# Break out early, otherwise skipped_export may be
+		# set to false by a later but shorter cmd.
+		break
+	      fi
+	    done
+	    IFS="$save_ifs"
+	    if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+	fi
+
+	if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	  tmp_export_symbols="$export_symbols"
+	  test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	  $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+	fi
+
+	if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
+	  # The given exports_symbols file has to be filtered, so filter it.
+	  func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	  # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	  # 's' commands which not all seds can handle. GNU sed should be fine
+	  # though. Also, the filter scales superlinearly with the number of
+	  # global variables. join(1) would be nice here, but unfortunately
+	  # isn't a blessed tool.
+	  $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	  delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+	  export_symbols=$output_objdir/$libname.def
+	  $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	fi
+
+	tmp_deplibs=
+	for test_deplib in $deplibs; do
+	  case " $convenience " in
+	  *" $test_deplib "*) ;;
+	  *)
+	    tmp_deplibs="$tmp_deplibs $test_deplib"
+	    ;;
+	  esac
+	done
+	deplibs="$tmp_deplibs"
+
+	if test -n "$convenience"; then
+	  if test -n "$whole_archive_flag_spec" &&
+	    test "$compiler_needs_object" = yes &&
+	    test -z "$libobjs"; then
+	    # extract the archives, so we have objects to list.
+	    # TODO: could optimize this to just extract one archive.
+	    whole_archive_flag_spec=
+	  fi
+	  if test -n "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  else
+	    gentop="$output_objdir/${outputname}x"
+	    generated="$generated $gentop"
+
+	    func_extract_archives $gentop $convenience
+	    libobjs="$libobjs $func_extract_archives_result"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	fi
+
+	if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+	  eval flag=\"$thread_safe_flag_spec\"
+	  linker_flags="$linker_flags $flag"
+	fi
+
+	# Make a backup of the uninstalled library when relinking
+	if test "$mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
+	fi
+
+	# Do each of the archive commands.
+	if test "$module" = yes && test -n "$module_cmds" ; then
+	  if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	    eval test_cmds=\"$module_expsym_cmds\"
+	    cmds=$module_expsym_cmds
+	  else
+	    eval test_cmds=\"$module_cmds\"
+	    cmds=$module_cmds
+	  fi
+	else
+	  if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	    eval test_cmds=\"$archive_expsym_cmds\"
+	    cmds=$archive_expsym_cmds
+	  else
+	    eval test_cmds=\"$archive_cmds\"
+	    cmds=$archive_cmds
+	  fi
+	fi
+
+	if test "X$skipped_export" != "X:" &&
+	   func_len " $test_cmds" &&
+	   len=$func_len_result &&
+	   test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  :
+	else
+	  # The command line is too long to link in one step, link piecewise
+	  # or, if using GNU ld and skipped_export is not :, use a linker
+	  # script.
+
+	  # Save the value of $output and $libobjs because we want to
+	  # use them later.  If we have whole_archive_flag_spec, we
+	  # want to use save_libobjs as it was before
+	  # whole_archive_flag_spec was expanded, because we can't
+	  # assume the linker understands whole_archive_flag_spec.
+	  # This may have to be revisited, in case too many
+	  # convenience libraries get linked in and end up exceeding
+	  # the spec.
+	  if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then
+	    save_libobjs=$libobjs
+	  fi
+	  save_output=$output
+	  output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+
+	  # Clear the reloadable object creation command queue and
+	  # initialize k to one.
+	  test_cmds=
+	  concat_cmds=
+	  objlist=
+	  last_robj=
+	  k=1
+
+	  if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
+	    output=${output_objdir}/${output_la}.lnkscript
+	    func_verbose "creating GNU ld script: $output"
+	    $ECHO 'INPUT (' > $output
+	    for obj in $save_libobjs
+	    do
+	      $ECHO "$obj" >> $output
+	    done
+	    $ECHO ')' >> $output
+	    delfiles="$delfiles $output"
+	  elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
+	    output=${output_objdir}/${output_la}.lnk
+	    func_verbose "creating linker input file list: $output"
+	    : > $output
+	    set x $save_libobjs
+	    shift
+	    firstobj=
+	    if test "$compiler_needs_object" = yes; then
+	      firstobj="$1 "
+	      shift
+	    fi
+	    for obj
+	    do
+	      $ECHO "$obj" >> $output
+	    done
+	    delfiles="$delfiles $output"
+	    output=$firstobj\"$file_list_spec$output\"
+	  else
+	    if test -n "$save_libobjs"; then
+	      func_verbose "creating reloadable object files..."
+	      output=$output_objdir/$output_la-${k}.$objext
+	      eval test_cmds=\"$reload_cmds\"
+	      func_len " $test_cmds"
+	      len0=$func_len_result
+	      len=$len0
+
+	      # Loop over the list of objects to be linked.
+	      for obj in $save_libobjs
+	      do
+		func_len " $obj"
+		func_arith $len + $func_len_result
+		len=$func_arith_result
+		if test "X$objlist" = X ||
+		   test "$len" -lt "$max_cmd_len"; then
+		  func_append objlist " $obj"
+		else
+		  # The command $test_cmds is almost too long, add a
+		  # command to the queue.
+		  if test "$k" -eq 1 ; then
+		    # The first file doesn't have a previous command to add.
+		    eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+		  else
+		    # All subsequent reloadable object files will link in
+		    # the last one created.
+		    eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+		  fi
+		  last_robj=$output_objdir/$output_la-${k}.$objext
+		  func_arith $k + 1
+		  k=$func_arith_result
+		  output=$output_objdir/$output_la-${k}.$objext
+		  objlist=$obj
+		  func_len " $last_robj"
+		  func_arith $len0 + $func_len_result
+		  len=$func_arith_result
+		fi
+	      done
+	      # Handle the remaining objects by creating one last
+	      # reloadable object file.  All subsequent reloadable object
+	      # files will link in the last one created.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+	      if test -n "$last_robj"; then
+	        eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
+	      fi
+	      delfiles="$delfiles $output"
+
+	    else
+	      output=
+	    fi
+
+	    if ${skipped_export-false}; then
+	      func_verbose "generating symbol list for \`$libname.la'"
+	      export_symbols="$output_objdir/$libname.exp"
+	      $opt_dry_run || $RM $export_symbols
+	      libobjs=$output
+	      # Append the command to create the export file.
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\"
+	      if test -n "$last_robj"; then
+		eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\"
+	      fi
+	    fi
+
+	    test -n "$save_libobjs" &&
+	      func_verbose "creating a temporary reloadable object file: $output"
+
+	    # Loop through the commands generated above and execute them.
+	    save_ifs="$IFS"; IFS='~'
+	    for cmd in $concat_cmds; do
+	      IFS="$save_ifs"
+	      $opt_silent || {
+		  func_quote_for_expand "$cmd"
+		  eval "func_echo $func_quote_for_expand_result"
+	      }
+	      $opt_dry_run || eval "$cmd" || {
+		lt_exit=$?
+
+		# Restore the uninstalled library and exit
+		if test "$mode" = relink; then
+		  ( cd "$output_objdir" && \
+		    $RM "${realname}T" && \
+		    $MV "${realname}U" "$realname" )
+		fi
+
+		exit $lt_exit
+	      }
+	    done
+	    IFS="$save_ifs"
+
+	    if test -n "$export_symbols_regex" && ${skipped_export-false}; then
+	      func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+	      func_show_eval '$MV "${export_symbols}T" "$export_symbols"'
+	    fi
+	  fi
+
+          if ${skipped_export-false}; then
+	    if test -n "$export_symbols" && test -n "$include_expsyms"; then
+	      tmp_export_symbols="$export_symbols"
+	      test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
+	      $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+	    fi
+
+	    if test -n "$orig_export_symbols"; then
+	      # The given exports_symbols file has to be filtered, so filter it.
+	      func_verbose "filter symbol list for \`$libname.la' to tag DATA exports"
+	      # FIXME: $output_objdir/$libname.filter potentially contains lots of
+	      # 's' commands which not all seds can handle. GNU sed should be fine
+	      # though. Also, the filter scales superlinearly with the number of
+	      # global variables. join(1) would be nice here, but unfortunately
+	      # isn't a blessed tool.
+	      $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
+	      delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+	      export_symbols=$output_objdir/$libname.def
+	      $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
+	    fi
+	  fi
+
+	  libobjs=$output
+	  # Restore the value of output.
+	  output=$save_output
+
+	  if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then
+	    eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+	    test "X$libobjs" = "X " && libobjs=
+	  fi
+	  # Expand the library linking commands again to reset the
+	  # value of $libobjs for piecewise linking.
+
+	  # Do each of the archive commands.
+	  if test "$module" = yes && test -n "$module_cmds" ; then
+	    if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then
+	      cmds=$module_expsym_cmds
+	    else
+	      cmds=$module_cmds
+	    fi
+	  else
+	    if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+	      cmds=$archive_expsym_cmds
+	    else
+	      cmds=$archive_cmds
+	    fi
+	  fi
+	fi
+
+	if test -n "$delfiles"; then
+	  # Append the command to remove temporary files to $cmds.
+	  eval cmds=\"\$cmds~\$RM $delfiles\"
+	fi
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  libobjs="$libobjs $func_extract_archives_result"
+	  test "X$libobjs" = "X " && libobjs=
+	fi
+
+	save_ifs="$IFS"; IFS='~'
+	for cmd in $cmds; do
+	  IFS="$save_ifs"
+	  eval cmd=\"$cmd\"
+	  $opt_silent || {
+	    func_quote_for_expand "$cmd"
+	    eval "func_echo $func_quote_for_expand_result"
+	  }
+	  $opt_dry_run || eval "$cmd" || {
+	    lt_exit=$?
+
+	    # Restore the uninstalled library and exit
+	    if test "$mode" = relink; then
+	      ( cd "$output_objdir" && \
+	        $RM "${realname}T" && \
+		$MV "${realname}U" "$realname" )
+	    fi
+
+	    exit $lt_exit
+	  }
+	done
+	IFS="$save_ifs"
+
+	# Restore the uninstalled library and exit
+	if test "$mode" = relink; then
+	  $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
+
+	  if test -n "$convenience"; then
+	    if test -z "$whole_archive_flag_spec"; then
+	      func_show_eval '${RM}r "$gentop"'
+	    fi
+	  fi
+
+	  exit $EXIT_SUCCESS
+	fi
+
+	# Create links to the real library.
+	for linkname in $linknames; do
+	  if test "$realname" != "$linkname"; then
+	    func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?'
+	  fi
+	done
+
+	# If -module or -export-dynamic was specified, set the dlname.
+	if test "$module" = yes || test "$export_dynamic" = yes; then
+	  # On all known operating systems, these are identical.
+	  dlname="$soname"
+	fi
+      fi
+      ;;
+
+    obj)
+      if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+	func_warning "\`-dlopen' is ignored for objects"
+      fi
+
+      case " $deplibs" in
+      *\ -l* | *\ -L*)
+	func_warning "\`-l' and \`-L' are ignored for objects" ;;
+      esac
+
+      test -n "$rpath" && \
+	func_warning "\`-rpath' is ignored for objects"
+
+      test -n "$xrpath" && \
+	func_warning "\`-R' is ignored for objects"
+
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for objects"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for objects"
+
+      case $output in
+      *.lo)
+	test -n "$objs$old_deplibs" && \
+	  func_fatal_error "cannot build library object \`$output' from non-libtool objects"
+
+	libobj=$output
+	func_lo2o "$libobj"
+	obj=$func_lo2o_result
+	;;
+      *)
+	libobj=
+	obj="$output"
+	;;
+      esac
+
+      # Delete the old objects.
+      $opt_dry_run || $RM $obj $libobj
+
+      # Objects from convenience libraries.  This assumes
+      # single-version convenience libraries.  Whenever we create
+      # different ones for PIC/non-PIC, this we'll have to duplicate
+      # the extraction.
+      reload_conv_objs=
+      gentop=
+      # reload_cmds runs $LD directly, so let us get rid of
+      # -Wl from whole_archive_flag_spec and hope we can get by with
+      # turning comma into space..
+      wl=
+
+      if test -n "$convenience"; then
+	if test -n "$whole_archive_flag_spec"; then
+	  eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
+	  reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+	else
+	  gentop="$output_objdir/${obj}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $convenience
+	  reload_conv_objs="$reload_objs $func_extract_archives_result"
+	fi
+      fi
+
+      # Create the old-style object.
+      reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+
+      output="$obj"
+      func_execute_cmds "$reload_cmds" 'exit $?'
+
+      # Exit if we aren't doing a library object file.
+      if test -z "$libobj"; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$build_libtool_libs" != yes; then
+	if test -n "$gentop"; then
+	  func_show_eval '${RM}r "$gentop"'
+	fi
+
+	# Create an invalid libtool object if no PIC, so that we don't
+	# accidentally link it into a program.
+	# $show "echo timestamp > $libobj"
+	# $opt_dry_run || eval "echo timestamp > $libobj" || exit $?
+	exit $EXIT_SUCCESS
+      fi
+
+      if test -n "$pic_flag" || test "$pic_mode" != default; then
+	# Only do commands if we really have different PIC objects.
+	reload_objs="$libobjs $reload_conv_objs"
+	output="$libobj"
+	func_execute_cmds "$reload_cmds" 'exit $?'
+      fi
+
+      if test -n "$gentop"; then
+	func_show_eval '${RM}r "$gentop"'
+      fi
+
+      exit $EXIT_SUCCESS
+      ;;
+
+    prog)
+      case $host in
+	*cygwin*) func_stripname '' '.exe' "$output"
+	          output=$func_stripname_result.exe;;
+      esac
+      test -n "$vinfo" && \
+	func_warning "\`-version-info' is ignored for programs"
+
+      test -n "$release" && \
+	func_warning "\`-release' is ignored for programs"
+
+      test "$preload" = yes \
+        && test "$dlopen_support" = unknown \
+	&& test "$dlopen_self" = unknown \
+	&& test "$dlopen_self_static" = unknown && \
+	  func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support."
+
+      case $host in
+      *-*-rhapsody* | *-*-darwin1.[012])
+	# On Rhapsody replace the C library is the System framework
+	compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+	finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+	;;
+      esac
+
+      case $host in
+      *-*-darwin*)
+	# Don't allow lazy linking, it breaks C++ global constructors
+	# But is supposedly fixed on 10.4 or later (yay!).
+	if test "$tagname" = CXX ; then
+	  case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
+	    10.[0123])
+	      compile_command="$compile_command ${wl}-bind_at_load"
+	      finalize_command="$finalize_command ${wl}-bind_at_load"
+	    ;;
+	  esac
+	fi
+	# Time to change all our "foo.ltframework" stuff back to "-framework foo"
+	compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+	;;
+      esac
+
+
+      # move library search paths that coincide with paths to not yet
+      # installed libraries to the beginning of the library search list
+      new_libs=
+      for path in $notinst_path; do
+	case " $new_libs " in
+	*" -L$path/$objdir "*) ;;
+	*)
+	  case " $compile_deplibs " in
+	  *" -L$path/$objdir "*)
+	    new_libs="$new_libs -L$path/$objdir" ;;
+	  esac
+	  ;;
+	esac
+      done
+      for deplib in $compile_deplibs; do
+	case $deplib in
+	-L*)
+	  case " $new_libs " in
+	  *" $deplib "*) ;;
+	  *) new_libs="$new_libs $deplib" ;;
+	  esac
+	  ;;
+	*) new_libs="$new_libs $deplib" ;;
+	esac
+      done
+      compile_deplibs="$new_libs"
+
+
+      compile_command="$compile_command $compile_deplibs"
+      finalize_command="$finalize_command $finalize_deplibs"
+
+      if test -n "$rpath$xrpath"; then
+	# If the user specified any rpath flags, then add them.
+	for libdir in $rpath $xrpath; do
+	  # This is the magic to use -rpath.
+	  case "$finalize_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_rpath="$finalize_rpath $libdir" ;;
+	  esac
+	done
+      fi
+
+      # Now hardcode the library paths
+      rpath=
+      hardcode_libdirs=
+      for libdir in $compile_rpath $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) perm_rpath="$perm_rpath $libdir" ;;
+	  esac
+	fi
+	case $host in
+	*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
+	  testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'`
+	  case :$dllsearchpath: in
+	  *":$libdir:"*) ;;
+	  ::) dllsearchpath=$libdir;;
+	  *) dllsearchpath="$dllsearchpath:$libdir";;
+	  esac
+	  case :$dllsearchpath: in
+	  *":$testbindir:"*) ;;
+	  ::) dllsearchpath=$testbindir;;
+	  *) dllsearchpath="$dllsearchpath:$testbindir";;
+	  esac
+	  ;;
+	esac
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      compile_rpath="$rpath"
+
+      rpath=
+      hardcode_libdirs=
+      for libdir in $finalize_rpath; do
+	if test -n "$hardcode_libdir_flag_spec"; then
+	  if test -n "$hardcode_libdir_separator"; then
+	    if test -z "$hardcode_libdirs"; then
+	      hardcode_libdirs="$libdir"
+	    else
+	      # Just accumulate the unique libdirs.
+	      case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in
+	      *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+		;;
+	      *)
+		hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+		;;
+	      esac
+	    fi
+	  else
+	    eval flag=\"$hardcode_libdir_flag_spec\"
+	    rpath="$rpath $flag"
+	  fi
+	elif test -n "$runpath_var"; then
+	  case "$finalize_perm_rpath " in
+	  *" $libdir "*) ;;
+	  *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+	  esac
+	fi
+      done
+      # Substitute the hardcoded libdirs into the rpath.
+      if test -n "$hardcode_libdir_separator" &&
+	 test -n "$hardcode_libdirs"; then
+	libdir="$hardcode_libdirs"
+	eval rpath=\" $hardcode_libdir_flag_spec\"
+      fi
+      finalize_rpath="$rpath"
+
+      if test -n "$libobjs" && test "$build_old_libs" = yes; then
+	# Transform all the library objects into standard objects.
+	compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+	finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+      fi
+
+      func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
+
+      # template prelinking step
+      if test -n "$prelink_cmds"; then
+	func_execute_cmds "$prelink_cmds" 'exit $?'
+      fi
+
+      wrappers_required=yes
+      case $host in
+      *cygwin* | *mingw* )
+        if test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      *cegcc)
+        # Disable wrappers for cegcc, we are cross compiling anyway.
+        wrappers_required=no
+        ;;
+      *)
+        if test "$need_relink" = no || test "$build_libtool_libs" != yes; then
+          wrappers_required=no
+        fi
+        ;;
+      esac
+      if test "$wrappers_required" = no; then
+	# Replace the output file specification.
+	compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	link_command="$compile_command$compile_rpath"
+
+	# We have no uninstalled library dependencies, so finalize right now.
+	exit_status=0
+	func_show_eval "$link_command" 'exit_status=$?'
+
+	# Delete the generated files.
+	if test -f "$output_objdir/${outputname}S.${objext}"; then
+	  func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
+	fi
+
+	exit $exit_status
+      fi
+
+      if test -n "$compile_shlibpath$finalize_shlibpath"; then
+	compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+      fi
+      if test -n "$finalize_shlibpath"; then
+	finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+      fi
+
+      compile_var=
+      finalize_var=
+      if test -n "$runpath_var"; then
+	if test -n "$perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+	if test -n "$finalize_perm_rpath"; then
+	  # We should set the runpath_var.
+	  rpath=
+	  for dir in $finalize_perm_rpath; do
+	    rpath="$rpath$dir:"
+	  done
+	  finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+	fi
+      fi
+
+      if test "$no_install" = yes; then
+	# We don't need to create a wrapper script.
+	link_command="$compile_var$compile_command$compile_rpath"
+	# Replace the output file specification.
+	link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+	# Delete the old output file.
+	$opt_dry_run || $RM $output
+	# Link the executable and exit
+	func_show_eval "$link_command" 'exit $?'
+	exit $EXIT_SUCCESS
+      fi
+
+      if test "$hardcode_action" = relink; then
+	# Fast installation is not supported
+	link_command="$compile_var$compile_command$compile_rpath"
+	relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+	func_warning "this platform does not like uninstalled shared libraries"
+	func_warning "\`$output' will be relinked during installation"
+      else
+	if test "$fast_install" != no; then
+	  link_command="$finalize_var$compile_command$finalize_rpath"
+	  if test "$fast_install" = yes; then
+	    relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+	  else
+	    # fast_install is set to needless
+	    relink_command=
+	  fi
+	else
+	  link_command="$compile_var$compile_command$compile_rpath"
+	  relink_command="$finalize_var$finalize_command$finalize_rpath"
+	fi
+      fi
+
+      # Replace the output file specification.
+      link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+      # Delete the old output files.
+      $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+      func_show_eval "$link_command" 'exit $?'
+
+      # Now create the wrapper script.
+      func_verbose "creating $output"
+
+      # Quote the relink command for shipping.
+      if test -n "$relink_command"; then
+	# Preserve any variables that may affect compiler behavior
+	for var in $variables_saved_for_relink; do
+	  if eval test -z \"\${$var+set}\"; then
+	    relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	  elif eval var_value=\$$var; test -z "$var_value"; then
+	    relink_command="$var=; export $var; $relink_command"
+	  else
+	    func_quote_for_eval "$var_value"
+	    relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	  fi
+	done
+	relink_command="(cd `pwd`; $relink_command)"
+	relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Quote $ECHO for shipping.
+      if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
+	case $progpath in
+	[\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
+	*) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
+	esac
+	qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
+      else
+	qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+      fi
+
+      # Only actually do things if not in dry run mode.
+      $opt_dry_run || {
+	# win32 will think the script is a binary if it has
+	# a .exe suffix, so we strip it off here.
+	case $output in
+	  *.exe) func_stripname '' '.exe' "$output"
+	         output=$func_stripname_result ;;
+	esac
+	# test for cygwin because mv fails w/o .exe extensions
+	case $host in
+	  *cygwin*)
+	    exeext=.exe
+	    func_stripname '' '.exe' "$outputname"
+	    outputname=$func_stripname_result ;;
+	  *) exeext= ;;
+	esac
+	case $host in
+	  *cygwin* | *mingw* )
+	    func_dirname_and_basename "$output" "" "."
+	    output_name=$func_basename_result
+	    output_path=$func_dirname_result
+	    cwrappersource="$output_path/$objdir/lt-$output_name.c"
+	    cwrapper="$output_path/$output_name.exe"
+	    $RM $cwrappersource $cwrapper
+	    trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_cwrapperexe_src > $cwrappersource
+
+	    # The wrapper executable is built using the $host compiler,
+	    # because it contains $host paths and files. If cross-
+	    # compiling, it, like the target executable, must be
+	    # executed on the $host or under an emulation environment.
+	    $opt_dry_run || {
+	      $LTCC $LTCFLAGS -o $cwrapper $cwrappersource
+	      $STRIP $cwrapper
+	    }
+
+	    # Now, create the wrapper script for func_source use:
+	    func_ltwrapper_scriptname $cwrapper
+	    $RM $func_ltwrapper_scriptname_result
+	    trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15
+	    $opt_dry_run || {
+	      # note: this script will not be executed, so do not chmod.
+	      if test "x$build" = "x$host" ; then
+		$cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result
+	      else
+		func_emit_wrapper no > $func_ltwrapper_scriptname_result
+	      fi
+	    }
+	  ;;
+	  * )
+	    $RM $output
+	    trap "$RM $output; exit $EXIT_FAILURE" 1 2 15
+
+	    func_emit_wrapper no > $output
+	    chmod +x $output
+	  ;;
+	esac
+      }
+      exit $EXIT_SUCCESS
+      ;;
+    esac
+
+    # See if we need to build an old-fashioned archive.
+    for oldlib in $oldlibs; do
+
+      if test "$build_libtool_libs" = convenience; then
+	oldobjs="$libobjs_save $symfileobj"
+	addlibs="$convenience"
+	build_libtool_libs=no
+      else
+	if test "$build_libtool_libs" = module; then
+	  oldobjs="$libobjs_save"
+	  build_libtool_libs=no
+	else
+	  oldobjs="$old_deplibs $non_pic_objects"
+	  if test "$preload" = yes && test -f "$symfileobj"; then
+	    oldobjs="$oldobjs $symfileobj"
+	  fi
+	fi
+	addlibs="$old_convenience"
+      fi
+
+      if test -n "$addlibs"; then
+	gentop="$output_objdir/${outputname}x"
+	generated="$generated $gentop"
+
+	func_extract_archives $gentop $addlibs
+	oldobjs="$oldobjs $func_extract_archives_result"
+      fi
+
+      # Do each command in the archive commands.
+      if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+	cmds=$old_archive_from_new_cmds
+      else
+
+	# Add any objects from preloaded convenience libraries
+	if test -n "$dlprefiles"; then
+	  gentop="$output_objdir/${outputname}x"
+	  generated="$generated $gentop"
+
+	  func_extract_archives $gentop $dlprefiles
+	  oldobjs="$oldobjs $func_extract_archives_result"
+	fi
+
+	# POSIX demands no paths to be encoded in archives.  We have
+	# to avoid creating archives with duplicate basenames if we
+	# might have to extract them afterwards, e.g., when creating a
+	# static archive out of a convenience library, or when linking
+	# the entirety of a libtool archive into another (currently
+	# not supported by libtool).
+	if (for obj in $oldobjs
+	    do
+	      func_basename "$obj"
+	      $ECHO "$func_basename_result"
+	    done | sort | sort -uc >/dev/null 2>&1); then
+	  :
+	else
+	  $ECHO "copying selected object files to avoid basename conflicts..."
+	  gentop="$output_objdir/${outputname}x"
+	  generated="$generated $gentop"
+	  func_mkdir_p "$gentop"
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  counter=1
+	  for obj in $save_oldobjs
+	  do
+	    func_basename "$obj"
+	    objbase="$func_basename_result"
+	    case " $oldobjs " in
+	    " ") oldobjs=$obj ;;
+	    *[\ /]"$objbase "*)
+	      while :; do
+		# Make sure we don't pick an alternate name that also
+		# overlaps.
+		newobj=lt$counter-$objbase
+		func_arith $counter + 1
+		counter=$func_arith_result
+		case " $oldobjs " in
+		*[\ /]"$newobj "*) ;;
+		*) if test ! -f "$gentop/$newobj"; then break; fi ;;
+		esac
+	      done
+	      func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
+	      oldobjs="$oldobjs $gentop/$newobj"
+	      ;;
+	    *) oldobjs="$oldobjs $obj" ;;
+	    esac
+	  done
+	fi
+	eval cmds=\"$old_archive_cmds\"
+
+	func_len " $cmds"
+	len=$func_len_result
+	if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+	  cmds=$old_archive_cmds
+	else
+	  # the command line is too long to link in one step, link in parts
+	  func_verbose "using piecewise archive linking..."
+	  save_RANLIB=$RANLIB
+	  RANLIB=:
+	  objlist=
+	  concat_cmds=
+	  save_oldobjs=$oldobjs
+	  oldobjs=
+	  # Is there a better way of finding the last object in the list?
+	  for obj in $save_oldobjs
+	  do
+	    last_oldobj=$obj
+	  done
+	  eval test_cmds=\"$old_archive_cmds\"
+	  func_len " $test_cmds"
+	  len0=$func_len_result
+	  len=$len0
+	  for obj in $save_oldobjs
+	  do
+	    func_len " $obj"
+	    func_arith $len + $func_len_result
+	    len=$func_arith_result
+	    func_append objlist " $obj"
+	    if test "$len" -lt "$max_cmd_len"; then
+	      :
+	    else
+	      # the above command should be used before it gets too long
+	      oldobjs=$objlist
+	      if test "$obj" = "$last_oldobj" ; then
+		RANLIB=$save_RANLIB
+	      fi
+	      test -z "$concat_cmds" || concat_cmds=$concat_cmds~
+	      eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\"
+	      objlist=
+	      len=$len0
+	    fi
+	  done
+	  RANLIB=$save_RANLIB
+	  oldobjs=$objlist
+	  if test "X$oldobjs" = "X" ; then
+	    eval cmds=\"\$concat_cmds\"
+	  else
+	    eval cmds=\"\$concat_cmds~\$old_archive_cmds\"
+	  fi
+	fi
+      fi
+      func_execute_cmds "$cmds" 'exit $?'
+    done
+
+    test -n "$generated" && \
+      func_show_eval "${RM}r$generated"
+
+    # Now create the libtool archive.
+    case $output in
+    *.la)
+      old_library=
+      test "$build_old_libs" = yes && old_library="$libname.$libext"
+      func_verbose "creating $output"
+
+      # Preserve any variables that may affect compiler behavior
+      for var in $variables_saved_for_relink; do
+	if eval test -z \"\${$var+set}\"; then
+	  relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command"
+	elif eval var_value=\$$var; test -z "$var_value"; then
+	  relink_command="$var=; export $var; $relink_command"
+	else
+	  func_quote_for_eval "$var_value"
+	  relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command"
+	fi
+      done
+      # Quote the link command for shipping.
+      relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
+      relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      if test "$hardcode_automatic" = yes ; then
+	relink_command=
+      fi
+
+      # Only create the output if not a dry run.
+      $opt_dry_run || {
+	for installed in no yes; do
+	  if test "$installed" = yes; then
+	    if test -z "$install_libdir"; then
+	      break
+	    fi
+	    output="$output_objdir/$outputname"i
+	    # Replace all uninstalled libtool libraries with the installed ones
+	    newdependency_libs=
+	    for deplib in $dependency_libs; do
+	      case $deplib in
+	      *.la)
+		func_basename "$deplib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$deplib' is not a valid libtool archive"
+		newdependency_libs="$newdependency_libs $libdir/$name"
+		;;
+	      *) newdependency_libs="$newdependency_libs $deplib" ;;
+	      esac
+	    done
+	    dependency_libs="$newdependency_libs"
+	    newdlfiles=
+
+	    for lib in $dlfiles; do
+	      case $lib in
+	      *.la)
+	        func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		newdlfiles="$newdlfiles $libdir/$name"
+		;;
+	      *) newdlfiles="$newdlfiles $lib" ;;
+	      esac
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+	      *.la)
+		# Only pass preopened files to the pseudo-archive (for
+		# eventual linking with the app. that links it) if we
+		# didn't already link the preopened objects directly into
+		# the library:
+		func_basename "$lib"
+		name="$func_basename_result"
+		eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
+		test -z "$libdir" && \
+		  func_fatal_error "\`$lib' is not a valid libtool archive"
+		newdlprefiles="$newdlprefiles $libdir/$name"
+		;;
+	      esac
+	    done
+	    dlprefiles="$newdlprefiles"
+	  else
+	    newdlfiles=
+	    for lib in $dlfiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlfiles="$newdlfiles $abs"
+	    done
+	    dlfiles="$newdlfiles"
+	    newdlprefiles=
+	    for lib in $dlprefiles; do
+	      case $lib in
+		[\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
+		*) abs=`pwd`"/$lib" ;;
+	      esac
+	      newdlprefiles="$newdlprefiles $abs"
+	    done
+	    dlprefiles="$newdlprefiles"
+	  fi
+	  $RM $output
+	  # place dlname in correct position for cygwin
+	  tdlname=$dlname
+	  case $host,$output,$installed,$module,$dlname in
+	    *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+	  esac
+	  $ECHO > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$tdlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags='$new_inherited_linker_flags'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Names of additional weak libraries provided by this library
+weak_library_names='$weak_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=$module
+
+# Files to dlopen/dlpreopen
+dlopen='$dlfiles'
+dlpreopen='$dlprefiles'
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'"
+	  if test "$installed" = no && test "$need_relink" = yes; then
+	    $ECHO >> $output "\
+relink_command=\"$relink_command\""
+	  fi
+	done
+      }
+
+      # Do a symbolic link so that the libtool archive can be found in
+      # LD_LIBRARY_PATH before the program is installed.
+      func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?'
+      ;;
+    esac
+    exit $EXIT_SUCCESS
+}
+
+{ test "$mode" = link || test "$mode" = relink; } &&
+    func_mode_link ${1+"$@"}
+
+
+# func_mode_uninstall arg...
+func_mode_uninstall ()
+{
+    $opt_debug
+    RM="$nonopt"
+    files=
+    rmforce=
+    exit_status=0
+
+    # This variable tells wrapper scripts just to set variables rather
+    # than running their programs.
+    libtool_install_magic="$magic"
+
+    for arg
+    do
+      case $arg in
+      -f) RM="$RM $arg"; rmforce=yes ;;
+      -*) RM="$RM $arg" ;;
+      *) files="$files $arg" ;;
+      esac
+    done
+
+    test -z "$RM" && \
+      func_fatal_help "you must specify an RM program"
+
+    rmdirs=
+
+    origobjdir="$objdir"
+    for file in $files; do
+      func_dirname "$file" "" "."
+      dir="$func_dirname_result"
+      if test "X$dir" = X.; then
+	objdir="$origobjdir"
+      else
+	objdir="$dir/$origobjdir"
+      fi
+      func_basename "$file"
+      name="$func_basename_result"
+      test "$mode" = uninstall && objdir="$dir"
+
+      # Remember objdir for removal later, being careful to avoid duplicates
+      if test "$mode" = clean; then
+	case " $rmdirs " in
+	  *" $objdir "*) ;;
+	  *) rmdirs="$rmdirs $objdir" ;;
+	esac
+      fi
+
+      # Don't error if the file doesn't exist and rm -f was used.
+      if { test -L "$file"; } >/dev/null 2>&1 ||
+	 { test -h "$file"; } >/dev/null 2>&1 ||
+	 test -f "$file"; then
+	:
+      elif test -d "$file"; then
+	exit_status=1
+	continue
+      elif test "$rmforce" = yes; then
+	continue
+      fi
+
+      rmfiles="$file"
+
+      case $name in
+      *.la)
+	# Possibly a libtool archive, so verify it.
+	if func_lalib_p "$file"; then
+	  func_source $dir/$name
+
+	  # Delete the libtool libraries and symlinks.
+	  for n in $library_names; do
+	    rmfiles="$rmfiles $objdir/$n"
+	  done
+	  test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+
+	  case "$mode" in
+	  clean)
+	    case "  $library_names " in
+	    # "  " in the beginning catches empty $dlname
+	    *" $dlname "*) ;;
+	    *) rmfiles="$rmfiles $objdir/$dlname" ;;
+	    esac
+	    test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+	    ;;
+	  uninstall)
+	    if test -n "$library_names"; then
+	      # Do each command in the postuninstall commands.
+	      func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+
+	    if test -n "$old_library"; then
+	      # Do each command in the old_postuninstall commands.
+	      func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1'
+	    fi
+	    # FIXME: should reinstall the best remaining shared library.
+	    ;;
+	  esac
+	fi
+	;;
+
+      *.lo)
+	# Possibly a libtool object, so verify it.
+	if func_lalib_p "$file"; then
+
+	  # Read the .lo file
+	  func_source $dir/$name
+
+	  # Add PIC object to the list of files to remove.
+	  if test -n "$pic_object" &&
+	     test "$pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$pic_object"
+	  fi
+
+	  # Add non-PIC object to the list of files to remove.
+	  if test -n "$non_pic_object" &&
+	     test "$non_pic_object" != none; then
+	    rmfiles="$rmfiles $dir/$non_pic_object"
+	  fi
+	fi
+	;;
+
+      *)
+	if test "$mode" = clean ; then
+	  noexename=$name
+	  case $file in
+	  *.exe)
+	    func_stripname '' '.exe' "$file"
+	    file=$func_stripname_result
+	    func_stripname '' '.exe' "$name"
+	    noexename=$func_stripname_result
+	    # $file with .exe has already been added to rmfiles,
+	    # add $file without .exe
+	    rmfiles="$rmfiles $file"
+	    ;;
+	  esac
+	  # Do a test to see if this is a libtool program.
+	  if func_ltwrapper_p "$file"; then
+	    if func_ltwrapper_executable_p "$file"; then
+	      func_ltwrapper_scriptname "$file"
+	      relink_command=
+	      func_source $func_ltwrapper_scriptname_result
+	      rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+	    else
+	      relink_command=
+	      func_source $dir/$noexename
+	    fi
+
+	    # note $name still contains .exe if it was in $file originally
+	    # as does the version of $file that was added into $rmfiles
+	    rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+	    if test "$fast_install" = yes && test -n "$relink_command"; then
+	      rmfiles="$rmfiles $objdir/lt-$name"
+	    fi
+	    if test "X$noexename" != "X$name" ; then
+	      rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+	    fi
+	  fi
+	fi
+	;;
+      esac
+      func_show_eval "$RM $rmfiles" 'exit_status=1'
+    done
+    objdir="$origobjdir"
+
+    # Try to remove the ${objdir}s in the directories where we deleted files
+    for dir in $rmdirs; do
+      if test -d "$dir"; then
+	func_show_eval "rmdir $dir >/dev/null 2>&1"
+      fi
+    done
+
+    exit $exit_status
+}
+
+{ test "$mode" = uninstall || test "$mode" = clean; } &&
+    func_mode_uninstall ${1+"$@"}
+
+test -z "$mode" && {
+  help="$generic_help"
+  func_fatal_help "you must specify a MODE"
+}
+
+test -z "$exec_cmd" && \
+  func_fatal_help "invalid operation mode \`$mode'"
+
+if test -n "$exec_cmd"; then
+  eval exec "$exec_cmd"
+  exit $EXIT_FAILURE
+fi
+
+exit $exit_status
+
+
+# The TAGs below are defined such that we never get into a situation
+# in which we disable both kinds of libraries.  Given conflicting
+# choices, we go for a static library, that is the most portable,
+# since we can't tell whether shared libraries were disabled because
+# the user asked for that or because the platform doesn't support
+# them.  This is particularly important on AIX, because we don't
+# support having both static and shared libraries enabled at the same
+# time on that platform, so we default to a shared-only configuration.
+# If a disable-shared tag is given, we'll fallback to a static-only
+# configuration.  But we'll never go from static-only to shared-only.
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-shared
+build_libtool_libs=no
+build_old_libs=yes
+# ### END LIBTOOL TAG CONFIG: disable-shared
+
+# ### BEGIN LIBTOOL TAG CONFIG: disable-static
+build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
+# ### END LIBTOOL TAG CONFIG: disable-static
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
+# vi:sw=2
+
diff --git a/conf/ltoptions.m4 b/conf/ltoptions.m4
new file mode 100644
index 0000000..34151a3
--- /dev/null
+++ b/conf/ltoptions.m4
@@ -0,0 +1,368 @@
+# Helper functions for option handling.                    -*- Autoconf -*-
+#
+#   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltoptions.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
+
+
+# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
+# ------------------------------------------
+m4_define([_LT_MANGLE_OPTION],
+[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
+
+
+# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
+# ---------------------------------------
+# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
+# matching handler defined, dispatch to it.  Other OPTION-NAMEs are
+# saved as a flag.
+m4_define([_LT_SET_OPTION],
+[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
+m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
+        _LT_MANGLE_DEFUN([$1], [$2]),
+    [m4_warning([Unknown $1 option `$2'])])[]dnl
+])
+
+
+# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
+# ------------------------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+m4_define([_LT_IF_OPTION],
+[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
+
+
+# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
+# -------------------------------------------------------
+# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
+# are set.
+m4_define([_LT_UNLESS_OPTIONS],
+[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+	    [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
+		      [m4_define([$0_found])])])[]dnl
+m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
+])[]dnl
+])
+
+
+# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
+# ----------------------------------------
+# OPTION-LIST is a space-separated list of Libtool options associated
+# with MACRO-NAME.  If any OPTION has a matching handler declared with
+# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
+# the unknown option and exit.
+m4_defun([_LT_SET_OPTIONS],
+[# Set options
+m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
+    [_LT_SET_OPTION([$1], _LT_Option)])
+
+m4_if([$1],[LT_INIT],[
+  dnl
+  dnl Simply set some default values (i.e off) if boolean options were not
+  dnl specified:
+  _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
+  ])
+  _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
+  ])
+  dnl
+  dnl If no reference was made to various pairs of opposing options, then
+  dnl we run the default mode handler for the pair.  For example, if neither
+  dnl `shared' nor `disable-shared' was passed, we enable building of shared
+  dnl archives by default:
+  _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
+  _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
+  _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
+  		   [_LT_ENABLE_FAST_INSTALL])
+  ])
+])# _LT_SET_OPTIONS
+
+
+## --------------------------------- ##
+## Macros to handle LT_INIT options. ##
+## --------------------------------- ##
+
+# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
+# -----------------------------------------
+m4_define([_LT_MANGLE_DEFUN],
+[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
+
+
+# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
+# -----------------------------------------------
+m4_define([LT_OPTION_DEFINE],
+[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
+])# LT_OPTION_DEFINE
+
+
+# dlopen
+# ------
+LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
+])
+
+AU_DEFUN([AC_LIBTOOL_DLOPEN],
+[_LT_SET_OPTION([LT_INIT], [dlopen])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `dlopen' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
+
+
+# win32-dll
+# ---------
+# Declare package support for building win32 dll's.
+LT_OPTION_DEFINE([LT_INIT], [win32-dll],
+[enable_win32_dll=yes
+
+case $host in
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+  AC_CHECK_TOOL(AS, as, false)
+  AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+  AC_CHECK_TOOL(OBJDUMP, objdump, false)
+  ;;
+esac
+
+test -z "$AS" && AS=as
+_LT_DECL([], [AS],      [0], [Assembler program])dnl
+
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+])# win32-dll
+
+AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+_LT_SET_OPTION([LT_INIT], [win32-dll])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `win32-dll' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
+
+
+# _LT_ENABLE_SHARED([DEFAULT])
+# ----------------------------
+# implement the --enable-shared flag, and supports the `shared' and
+# `disable-shared' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_SHARED],
+[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([shared],
+    [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
+	[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
+
+    _LT_DECL([build_libtool_libs], [enable_shared], [0],
+	[Whether or not to build shared libraries])
+])# _LT_ENABLE_SHARED
+
+LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
+])
+
+AC_DEFUN([AC_DISABLE_SHARED],
+[_LT_SET_OPTION([LT_INIT], [disable-shared])
+])
+
+AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
+AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_SHARED], [])
+dnl AC_DEFUN([AM_DISABLE_SHARED], [])
+
+
+
+# _LT_ENABLE_STATIC([DEFAULT])
+# ----------------------------
+# implement the --enable-static flag, and support the `static' and
+# `disable-static' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_STATIC],
+[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([static],
+    [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
+	[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_static=]_LT_ENABLE_STATIC_DEFAULT)
+
+    _LT_DECL([build_old_libs], [enable_static], [0],
+	[Whether or not to build static libraries])
+])# _LT_ENABLE_STATIC
+
+LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
+
+# Old names:
+AC_DEFUN([AC_ENABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
+])
+
+AC_DEFUN([AC_DISABLE_STATIC],
+[_LT_SET_OPTION([LT_INIT], [disable-static])
+])
+
+AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
+AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AM_ENABLE_STATIC], [])
+dnl AC_DEFUN([AM_DISABLE_STATIC], [])
+
+
+
+# _LT_ENABLE_FAST_INSTALL([DEFAULT])
+# ----------------------------------
+# implement the --enable-fast-install flag, and support the `fast-install'
+# and `disable-fast-install' LT_INIT options.
+# DEFAULT is either `yes' or `no'.  If omitted, it defaults to `yes'.
+m4_define([_LT_ENABLE_FAST_INSTALL],
+[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
+AC_ARG_ENABLE([fast-install],
+    [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
+    [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
+    [p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
+    [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
+
+_LT_DECL([fast_install], [enable_fast_install], [0],
+	 [Whether or not to optimize for fast installation])dnl
+])# _LT_ENABLE_FAST_INSTALL
+
+LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
+LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
+
+# Old names:
+AU_DEFUN([AC_ENABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `fast-install' option into LT_INIT's first parameter.])
+])
+
+AU_DEFUN([AC_DISABLE_FAST_INSTALL],
+[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you put
+the `disable-fast-install' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
+dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
+
+
+# _LT_WITH_PIC([MODE])
+# --------------------
+# implement the --with-pic flag, and support the `pic-only' and `no-pic'
+# LT_INIT options.
+# MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
+m4_define([_LT_WITH_PIC],
+[AC_ARG_WITH([pic],
+    [AS_HELP_STRING([--with-pic],
+	[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
+    [pic_mode="$withval"],
+    [pic_mode=default])
+
+test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
+
+_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
+])# _LT_WITH_PIC
+
+LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
+LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
+
+# Old name:
+AU_DEFUN([AC_LIBTOOL_PICMODE],
+[_LT_SET_OPTION([LT_INIT], [pic-only])
+AC_DIAGNOSE([obsolete],
+[$0: Remove this warning and the call to _LT_SET_OPTION when you
+put the `pic-only' option into LT_INIT's first parameter.])
+])
+
+dnl aclocal-1.4 backwards compatibility:
+dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
+
+## ----------------- ##
+## LTDL_INIT Options ##
+## ----------------- ##
+
+m4_define([_LTDL_MODE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
+		 [m4_define([_LTDL_MODE], [nonrecursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [recursive],
+		 [m4_define([_LTDL_MODE], [recursive])])
+LT_OPTION_DEFINE([LTDL_INIT], [subproject],
+		 [m4_define([_LTDL_MODE], [subproject])])
+
+m4_define([_LTDL_TYPE], [])
+LT_OPTION_DEFINE([LTDL_INIT], [installable],
+		 [m4_define([_LTDL_TYPE], [installable])])
+LT_OPTION_DEFINE([LTDL_INIT], [convenience],
+		 [m4_define([_LTDL_TYPE], [convenience])])
diff --git a/conf/ltsugar.m4 b/conf/ltsugar.m4
new file mode 100644
index 0000000..9000a05
--- /dev/null
+++ b/conf/ltsugar.m4
@@ -0,0 +1,123 @@
+# ltsugar.m4 -- libtool m4 base layer.                         -*-Autoconf-*-
+#
+# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+# Written by Gary V. Vaughan, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 6 ltsugar.m4
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
+
+
+# lt_join(SEP, ARG1, [ARG2...])
+# -----------------------------
+# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
+# associated separator.
+# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
+# versions in m4sugar had bugs.
+m4_define([lt_join],
+[m4_if([$#], [1], [],
+       [$#], [2], [[$2]],
+       [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
+m4_define([_lt_join],
+[m4_if([$#$2], [2], [],
+       [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
+
+
+# lt_car(LIST)
+# lt_cdr(LIST)
+# ------------
+# Manipulate m4 lists.
+# These macros are necessary as long as will still need to support
+# Autoconf-2.59 which quotes differently.
+m4_define([lt_car], [[$1]])
+m4_define([lt_cdr],
+[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
+       [$#], 1, [],
+       [m4_dquote(m4_shift($@))])])
+m4_define([lt_unquote], $1)
+
+
+# lt_append(MACRO-NAME, STRING, [SEPARATOR])
+# ------------------------------------------
+# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
+# Note that neither SEPARATOR nor STRING are expanded; they are appended
+# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
+# No SEPARATOR is output if MACRO-NAME was previously undefined (different
+# than defined and empty).
+#
+# This macro is needed until we can rely on Autoconf 2.62, since earlier
+# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
+m4_define([lt_append],
+[m4_define([$1],
+	   m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
+
+
+
+# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
+# ----------------------------------------------------------
+# Produce a SEP delimited list of all paired combinations of elements of
+# PREFIX-LIST with SUFFIX1 through SUFFIXn.  Each element of the list
+# has the form PREFIXmINFIXSUFFIXn.
+# Needed until we can rely on m4_combine added in Autoconf 2.62.
+m4_define([lt_combine],
+[m4_if(m4_eval([$# > 3]), [1],
+       [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
+[[m4_foreach([_Lt_prefix], [$2],
+	     [m4_foreach([_Lt_suffix],
+		]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
+	[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
+
+
+# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
+# -----------------------------------------------------------------------
+# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
+# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
+m4_define([lt_if_append_uniq],
+[m4_ifdef([$1],
+	  [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
+		 [lt_append([$1], [$2], [$3])$4],
+		 [$5])],
+	  [lt_append([$1], [$2], [$3])$4])])
+
+
+# lt_dict_add(DICT, KEY, VALUE)
+# -----------------------------
+m4_define([lt_dict_add],
+[m4_define([$1($2)], [$3])])
+
+
+# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
+# --------------------------------------------
+m4_define([lt_dict_add_subkey],
+[m4_define([$1($2:$3)], [$4])])
+
+
+# lt_dict_fetch(DICT, KEY, [SUBKEY])
+# ----------------------------------
+m4_define([lt_dict_fetch],
+[m4_ifval([$3],
+	m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
+    m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
+
+
+# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
+# -----------------------------------------------------------------
+m4_define([lt_if_dict_fetch],
+[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
+	[$5],
+    [$6])])
+
+
+# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
+# --------------------------------------------------------------
+m4_define([lt_dict_filter],
+[m4_if([$5], [], [],
+  [lt_join(m4_quote(m4_default([$4], [[, ]])),
+           lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
+		      [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
+])
diff --git a/conf/ltversion.m4 b/conf/ltversion.m4
new file mode 100644
index 0000000..f3c5309
--- /dev/null
+++ b/conf/ltversion.m4
@@ -0,0 +1,23 @@
+# ltversion.m4 -- version numbers			-*- Autoconf -*-
+#
+#   Copyright (C) 2004 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# Generated from ltversion.in.
+
+# serial 3017 ltversion.m4
+# This file is part of GNU Libtool
+
+m4_define([LT_PACKAGE_VERSION], [2.2.6b])
+m4_define([LT_PACKAGE_REVISION], [1.3017])
+
+AC_DEFUN([LTVERSION_VERSION],
+[macro_version='2.2.6b'
+macro_revision='1.3017'
+_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
+_LT_DECL(, macro_revision, 0)
+])
diff --git a/conf/lt~obsolete.m4 b/conf/lt~obsolete.m4
new file mode 100644
index 0000000..637bb20
--- /dev/null
+++ b/conf/lt~obsolete.m4
@@ -0,0 +1,92 @@
+# lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
+#
+#   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+#   Written by Scott James Remnant, 2004.
+#
+# This file is free software; the Free Software Foundation gives
+# unlimited permission to copy and/or distribute it, with or without
+# modifications, as long as this notice is preserved.
+
+# serial 4 lt~obsolete.m4
+
+# These exist entirely to fool aclocal when bootstrapping libtool.
+#
+# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
+# which have later been changed to m4_define as they aren't part of the
+# exported API, or moved to Autoconf or Automake where they belong.
+#
+# The trouble is, aclocal is a bit thick.  It'll see the old AC_DEFUN
+# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
+# using a macro with the same name in our local m4/libtool.m4 it'll
+# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
+# and doesn't know about Autoconf macros at all.)
+#
+# So we provide this file, which has a silly filename so it's always
+# included after everything else.  This provides aclocal with the
+# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
+# because those macros already exist, or will be overwritten later.
+# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. 
+#
+# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
+# Yes, that means every name once taken will need to remain here until
+# we give up compatibility with versions before 1.7, at which point
+# we need to keep only those names which we still refer to.
+
+# This is to help aclocal find these macros, as it can't see m4_define.
+AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
+
+m4_ifndef([AC_LIBTOOL_LINKER_OPTION],	[AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
+m4_ifndef([AC_PROG_EGREP],		[AC_DEFUN([AC_PROG_EGREP])])
+m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH],	[AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_AC_SHELL_INIT],		[AC_DEFUN([_LT_AC_SHELL_INIT])])
+m4_ifndef([_LT_AC_SYS_LIBPATH_AIX],	[AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
+m4_ifndef([_LT_PROG_LTMAIN],		[AC_DEFUN([_LT_PROG_LTMAIN])])
+m4_ifndef([_LT_AC_TAGVAR],		[AC_DEFUN([_LT_AC_TAGVAR])])
+m4_ifndef([AC_LTDL_ENABLE_INSTALL],	[AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
+m4_ifndef([AC_LTDL_PREOPEN],		[AC_DEFUN([AC_LTDL_PREOPEN])])
+m4_ifndef([_LT_AC_SYS_COMPILER],	[AC_DEFUN([_LT_AC_SYS_COMPILER])])
+m4_ifndef([_LT_AC_LOCK],		[AC_DEFUN([_LT_AC_LOCK])])
+m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE],	[AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
+m4_ifndef([_LT_AC_TRY_DLOPEN_SELF],	[AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
+m4_ifndef([AC_LIBTOOL_PROG_CC_C_O],	[AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
+m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
+m4_ifndef([AC_LIBTOOL_OBJDIR],		[AC_DEFUN([AC_LIBTOOL_OBJDIR])])
+m4_ifndef([AC_LTDL_OBJDIR],		[AC_DEFUN([AC_LTDL_OBJDIR])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
+m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP],	[AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
+m4_ifndef([AC_PATH_MAGIC],		[AC_DEFUN([AC_PATH_MAGIC])])
+m4_ifndef([AC_PROG_LD_GNU],		[AC_DEFUN([AC_PROG_LD_GNU])])
+m4_ifndef([AC_PROG_LD_RELOAD_FLAG],	[AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
+m4_ifndef([AC_DEPLIBS_CHECK_METHOD],	[AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
+m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
+m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
+m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS],	[AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
+m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP],	[AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
+m4_ifndef([LT_AC_PROG_EGREP],		[AC_DEFUN([LT_AC_PROG_EGREP])])
+m4_ifndef([LT_AC_PROG_SED],		[AC_DEFUN([LT_AC_PROG_SED])])
+m4_ifndef([_LT_CC_BASENAME],		[AC_DEFUN([_LT_CC_BASENAME])])
+m4_ifndef([_LT_COMPILER_BOILERPLATE],	[AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
+m4_ifndef([_LT_LINKER_BOILERPLATE],	[AC_DEFUN([_LT_LINKER_BOILERPLATE])])
+m4_ifndef([_AC_PROG_LIBTOOL],		[AC_DEFUN([_AC_PROG_LIBTOOL])])
+m4_ifndef([AC_LIBTOOL_SETUP],		[AC_DEFUN([AC_LIBTOOL_SETUP])])
+m4_ifndef([_LT_AC_CHECK_DLFCN],		[AC_DEFUN([_LT_AC_CHECK_DLFCN])])
+m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER],	[AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
+m4_ifndef([_LT_AC_TAGCONFIG],		[AC_DEFUN([_LT_AC_TAGCONFIG])])
+m4_ifndef([AC_DISABLE_FAST_INSTALL],	[AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
+m4_ifndef([_LT_AC_LANG_CXX],		[AC_DEFUN([_LT_AC_LANG_CXX])])
+m4_ifndef([_LT_AC_LANG_F77],		[AC_DEFUN([_LT_AC_LANG_F77])])
+m4_ifndef([_LT_AC_LANG_GCJ],		[AC_DEFUN([_LT_AC_LANG_GCJ])])
+m4_ifndef([AC_LIBTOOL_RC],		[AC_DEFUN([AC_LIBTOOL_RC])])
+m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
+m4_ifndef([_LT_AC_LANG_C_CONFIG],	[AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
+m4_ifndef([_LT_AC_LANG_CXX_CONFIG],	[AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
+m4_ifndef([_LT_AC_LANG_F77_CONFIG],	[AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
+m4_ifndef([_LT_AC_LANG_GCJ_CONFIG],	[AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
+m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],	[AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
+m4_ifndef([_LT_AC_LANG_RC_CONFIG],	[AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
+m4_ifndef([AC_LIBTOOL_CONFIG],		[AC_DEFUN([AC_LIBTOOL_CONFIG])])
+m4_ifndef([_LT_AC_FILE_LTDLL_C],	[AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
diff --git a/conf/missing b/conf/missing
new file mode 100755
index 0000000..28055d2
--- /dev/null
+++ b/conf/missing
@@ -0,0 +1,376 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2009-04-28.21; # UTC
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006,
+# 2008, 2009 Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard at iro.umontreal.ca>, 1996.
+
+# 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p'
+sed_minuso='s/.* -o \([^ ]*\).*/\1/p'
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case $1 in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  autom4te     touch the output file, or create a stub one
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and
+\`g' are ignored when checking the name.
+
+Send bug reports to <bug-automake at gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# normalize program name to check for.
+program=`echo "$1" | sed '
+  s/^gnu-//; t
+  s/^gnu//; t
+  s/^g//; t'`
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).  This is about non-GNU programs, so use $1 not
+# $program.
+case $1 in
+  lex*|yacc*)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar*)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case $program in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case $f in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te*)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison*|yacc*)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f y.tab.h; then
+	echo >y.tab.h
+    fi
+    if test ! -f y.tab.c; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex*|flex*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if test $# -ne 1; then
+        eval LASTARG="\${$#}"
+	case $LASTARG in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if test -f "$SRCFILE"; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if test ! -f lex.yy.c; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit $?
+    fi
+    ;;
+
+  makeinfo*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n "$sed_output"`
+    test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '
+	/^@setfilename/{
+	  s/.* \([^ ]*\) *$/\1/
+	  p
+	  q
+	}' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    # If the file does not exist, the user really needs makeinfo;
+    # let's fail without touching anything.
+    test -f $file || exit 1
+    touch $file
+    ;;
+
+  tar*)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case $firstarg in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case $firstarg in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/conf/pkg.m4 b/conf/pkg.m4
new file mode 100644
index 0000000..c29b6c0
--- /dev/null
+++ b/conf/pkg.m4
@@ -0,0 +1,157 @@
+# pkg.m4 - Macros to locate and utilise pkg-config.            -*- Autoconf -*-
+# 
+# Copyright © 2004 Scott James Remnant <scott at netsplit.com>.
+#
+# 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 of the License, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# PKG_PROG_PKG_CONFIG([MIN-VERSION])
+# ----------------------------------
+AC_DEFUN([PKG_PROG_PKG_CONFIG],
+[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
+m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
+AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=m4_default([$1], [0.9.0])
+	AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		PKG_CONFIG=""
+	fi
+		
+fi[]dnl
+])# PKG_PROG_PKG_CONFIG
+
+# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+#
+# Check to see whether a particular set of modules exists.  Similar
+# to PKG_CHECK_MODULES(), but does not set variables or print errors.
+#
+#
+# Similar to PKG_CHECK_MODULES, make sure that the first instance of
+# this or PKG_CHECK_MODULES is called, or make sure to call
+# PKG_CHECK_EXISTS manually
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_EXISTS],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+if test -n "$PKG_CONFIG" && \
+    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
+  m4_ifval([$2], [$2], [:])
+m4_ifvaln([$3], [else
+  $3])dnl
+fi])
+
+
+# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
+# ---------------------------------------------
+m4_define([_PKG_CONFIG],
+[if test -n "$PKG_CONFIG"; then
+    if test -n "$$1"; then
+        pkg_cv_[]$1="$$1"
+    else
+        PKG_CHECK_EXISTS([$3],
+                         [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
+			 [pkg_failed=yes])
+    fi
+else
+	pkg_failed=untried
+fi[]dnl
+])# _PKG_CONFIG
+
+# _PKG_SHORT_ERRORS_SUPPORTED
+# -----------------------------
+AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi[]dnl
+])# _PKG_SHORT_ERRORS_SUPPORTED
+
+
+# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
+# [ACTION-IF-NOT-FOUND])
+#
+#
+# Note that if there is a possibility the first call to
+# PKG_CHECK_MODULES might not happen, you should be sure to include an
+# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
+#
+#
+# --------------------------------------------------------------
+AC_DEFUN([PKG_CHECK_MODULES],
+[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
+AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
+AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
+
+pkg_failed=no
+AC_MSG_CHECKING([for $1])
+
+_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
+_PKG_CONFIG([$1][_LIBS], [libs], [$2])
+
+m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
+and $1[]_LIBS to avoid the need to call pkg-config.
+See the pkg-config man page for more details.])
+
+if test $pkg_failed = yes; then
+        _PKG_SHORT_ERRORS_SUPPORTED
+        if test $_pkg_short_errors_supported = yes; then
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
+        else 
+	        $1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
+
+	ifelse([$4], , [AC_MSG_ERROR(dnl
+[Package requirements ($2) were not met:
+
+$$1_PKG_ERRORS
+
+Consider adjusting the PKG_CONFIG_PATH environment variable if you
+installed software in a non-standard prefix.
+
+_PKG_TEXT
+])],
+		[AC_MSG_RESULT([no])
+                $4])
+elif test $pkg_failed = untried; then
+	ifelse([$4], , [AC_MSG_FAILURE(dnl
+[The pkg-config script could not be found or is too old.  Make sure it
+is in your PATH or set the PKG_CONFIG environment variable to the full
+path to pkg-config.
+
+_PKG_TEXT
+
+To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
+		[$4])
+else
+	$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
+	$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
+        AC_MSG_RESULT([yes])
+	ifelse([$3], , :, [$3])
+fi[]dnl
+])# PKG_CHECK_MODULES
diff --git a/conf/warn-on-use.h b/conf/warn-on-use.h
new file mode 100644
index 0000000..fdf250e
--- /dev/null
+++ b/conf/warn-on-use.h
@@ -0,0 +1,109 @@
+/* A C macro for emitting warnings if a function is used.
+   Copyright (C) 2010-2011 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 3 of the License, 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
+   for FUNCTION which will then trigger a compiler warning containing
+   the text of "literal string" anywhere that function is called, if
+   supported by the compiler.  If the compiler does not support this
+   feature, the macro expands to an unused extern declaration.
+
+   This macro is useful for marking a function as a potential
+   portability trap, with the intent that "literal string" include
+   instructions on the replacement function that should be used
+   instead.  However, one of the reasons that a function is a
+   portability trap is if it has the wrong signature.  Declaring
+   FUNCTION with a different signature in C is a compilation error, so
+   this macro must use the same type as any existing declaration so
+   that programs that avoid the problematic FUNCTION do not fail to
+   compile merely because they included a header that poisoned the
+   function.  But this implies that _GL_WARN_ON_USE is only safe to
+   use if FUNCTION is known to already have a declaration.  Use of
+   this macro implies that there must not be any other macro hiding
+   the declaration of FUNCTION; but undefining FUNCTION first is part
+   of the poisoning process anyway (although for symbols that are
+   provided only via a macro, the result is a compilation error rather
+   than a warning containing "literal string").  Also note that in
+   C++, it is only safe to use if FUNCTION has no overloads.
+
+   For an example, it is possible to poison 'getline' by:
+   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
+     [getline]) in configure.ac, which potentially defines
+     HAVE_RAW_DECL_GETLINE
+   - adding this code to a header that wraps the system <stdio.h>:
+     #undef getline
+     #if HAVE_RAW_DECL_GETLINE
+     _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
+       "not universally present; use the gnulib module getline");
+     #endif
+
+   It is not possible to directly poison global variables.  But it is
+   possible to write a wrapper accessor function, and poison that
+   (less common usage, like &environ, will cause a compilation error
+   rather than issue the nice warning, but the end result of informing
+   the developer about their portability problem is still achieved):
+   #if HAVE_RAW_DECL_ENVIRON
+   static inline char ***rpl_environ (void) { return &environ; }
+   _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
+   # undef environ
+   # define environ (*rpl_environ ())
+   #endif
+   */
+#ifndef _GL_WARN_ON_USE
+
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
+#  define _GL_WARN_ON_USE(function, message) \
+extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#  define _GL_WARN_ON_USE(function, message) \
+extern __typeof__ (function) function
+# else /* Unsupported.  */
+#  define _GL_WARN_ON_USE(function, message) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+# endif
+#endif
+
+/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
+   is like _GL_WARN_ON_USE (function, "string"), except that the function is
+   declared with the given prototype, consisting of return type, parameters,
+   and attributes.
+   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
+   not work in this case.  */
+#ifndef _GL_WARN_ON_USE_CXX
+# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
+#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+extern rettype function parameters_and_attributes \
+     __attribute__ ((__warning__ (msg)))
+# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
+/* Verify the existence of the function.  */
+#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+extern rettype function parameters_and_attributes
+# else /* Unsupported.  */
+#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
+_GL_WARN_EXTERN_C int _gl_warn_on_use
+# endif
+#endif
+
+/* _GL_WARN_EXTERN_C declaration;
+   performs the declaration with C linkage.  */
+#ifndef _GL_WARN_EXTERN_C
+# if defined __cplusplus
+#  define _GL_WARN_EXTERN_C extern "C"
+# else
+#  define _GL_WARN_EXTERN_C extern
+# endif
+#endif
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..02e4eb3
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,852 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+#ifndef _config_h
+#define _config_h
+
+/* Define to the number of bits in type 'ptrdiff_t'. */
+#undef BITSIZEOF_PTRDIFF_T
+
+/* Define to the number of bits in type 'sig_atomic_t'. */
+#undef BITSIZEOF_SIG_ATOMIC_T
+
+/* Define to the number of bits in type 'size_t'. */
+#undef BITSIZEOF_SIZE_T
+
+/* Define to the number of bits in type 'wchar_t'. */
+#undef BITSIZEOF_WCHAR_T
+
+/* Define to the number of bits in type 'wint_t'. */
+#undef BITSIZEOF_WINT_T
+
+/* What sort of HTTP client is this? */
+#undef CNAME
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+#undef CRAY_STACKSEG_END
+
+/* Client version number */
+#undef CVER
+
+/* Define to 1 if using `alloca.c'. */
+#undef C_ALLOCA
+
+/* Highest DAP version implemented? */
+#undef DAP_PROTOCOL_VERSION
+
+/* dbyte */
+#undef DBYTE
+
+/* dfloat32 */
+#undef DFLOAT32
+
+/* dfloat64 */
+#undef DFLOAT64
+
+/* dint16 */
+#undef DINT16
+
+/* int32 */
+#undef DINT32
+
+/* Set instrumentation to level 1 (see debug.h) */
+#undef DODS_DEBUG
+
+/* Set instrumentation to level 2 */
+#undef DODS_DEBUG2
+
+/* uint16 */
+#undef DUINT16
+
+/* uint32 */
+#undef DUINT32
+
+/* Client name and version combined */
+#undef DVR
+
+/* Should all the classes run ConstraintEvaluator::eval()? */
+#undef EVAL
+
+/* Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string. */
+#undef FUNC_NL_LANGINFO_YESEXPR_WORKS
+
+/* Define to a C preprocessor expression that evaluates to 1 or 0, depending
+   whether the gnulib module malloc-gnu shall be considered present. */
+#undef GNULIB_MALLOC_GNU
+
+/* Define to 1 when the gnulib module btowc should be tested. */
+#undef GNULIB_TEST_BTOWC
+
+/* Define to 1 when the gnulib module malloc-posix should be tested. */
+#undef GNULIB_TEST_MALLOC_POSIX
+
+/* Define to 1 when the gnulib module mbrtowc should be tested. */
+#undef GNULIB_TEST_MBRTOWC
+
+/* Define to 1 when the gnulib module mbsinit should be tested. */
+#undef GNULIB_TEST_MBSINIT
+
+/* Define to 1 when the gnulib module nl_langinfo should be tested. */
+#undef GNULIB_TEST_NL_LANGINFO
+
+/* Define to 1 when the gnulib module wcrtomb should be tested. */
+#undef GNULIB_TEST_WCRTOMB
+
+/* Define to 1 if you have the `alarm' function. */
+#undef HAVE_ALARM
+
+/* Define to 1 if you have 'alloca' after including <alloca.h>, a header that
+   may be supplied by this distribution. */
+#undef HAVE_ALLOCA
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#undef HAVE_ALLOCA_H
+
+/* Define to 1 if you have the `atexit' function. */
+#undef HAVE_ATEXIT
+
+/* Define to 1 if you have the `btowc' function. */
+#undef HAVE_BTOWC
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
+   don't. */
+#undef HAVE_DECL_GETC_UNLOCKED
+
+/* Define to 1 if you have the declaration of `isblank', and to 0 if you
+   don't. */
+#undef HAVE_DECL_ISBLANK
+
+/* Define to 1 if you have the declaration of `iswblank', and to 0 if you
+   don't. */
+#undef HAVE_DECL_ISWBLANK
+
+/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_DIRENT_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the <features.h> header file. */
+#undef HAVE_FEATURES_H
+
+/* Define to 1 if you have the `getcwd' function. */
+#undef HAVE_GETCWD
+
+/* Define to 1 if you have the `getpagesize' function. */
+#undef HAVE_GETPAGESIZE
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `isblank' function. */
+#undef HAVE_ISBLANK
+
+/* Define to 1 if you have the `iswblank' function. */
+#undef HAVE_ISWBLANK
+
+/* Define to 1 if you have the `iswcntrl' function. */
+#undef HAVE_ISWCNTRL
+
+/* Define to 1 if you have the `iswctype' function. */
+#undef HAVE_ISWCTYPE
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+#undef HAVE_LANGINFO_CODESET
+
+/* Define to 1 if you have the <langinfo.h> header file. */
+#undef HAVE_LANGINFO_H
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
+/* Define to 1 if you have the `localtime_r' function. */
+#undef HAVE_LOCALTIME_R
+
+/* Define to 1 if the system has the type `long long int'. */
+#undef HAVE_LONG_LONG_INT
+
+/* Define to 1 if your system has a GNU libc compatible 'malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC_GNU
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if the 'malloc' function is POSIX compliant. */
+#undef HAVE_MALLOC_POSIX
+
+/* Define to 1 if you have the `mbrtowc' function. */
+#undef HAVE_MBRTOWC
+
+/* Define to 1 if you have the `mbsinit' function. */
+#undef HAVE_MBSINIT
+
+/* Define to 1 if <wchar.h> declares mbstate_t. */
+#undef HAVE_MBSTATE_T
+
+/* Define to 1 if you have the `memmove' function. */
+#undef HAVE_MEMMOVE
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#undef HAVE_MEMSET
+
+/* Define to 1 if you have the `mktime' function. */
+#undef HAVE_MKTIME
+
+/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
+#undef HAVE_NDIR_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the `nl_langinfo' function. */
+#undef HAVE_NL_LANGINFO
+
+/* Define to 1 if you have the `pow' function. */
+#undef HAVE_POW
+
+/* Define to 1 if you have the `putenv' function. */
+#undef HAVE_PUTENV
+
+/* Define to 1 if you have the <random.h> header file. */
+#undef HAVE_RANDOM_H
+
+/* Define to 1 if atoll is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_ATOLL
+
+/* Define to 1 if btowc is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_BTOWC
+
+/* Define to 1 if canonicalize_file_name is declared even after undefining
+   macros. */
+#undef HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
+
+/* Define to 1 if chown is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_CHOWN
+
+/* Define to 1 if dup2 is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_DUP2
+
+/* Define to 1 if dup3 is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_DUP3
+
+/* Define to 1 if endusershell is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_ENDUSERSHELL
+
+/* Define to 1 if environ is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_ENVIRON
+
+/* Define to 1 if euidaccess is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_EUIDACCESS
+
+/* Define to 1 if faccessat is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_FACCESSAT
+
+/* Define to 1 if fchdir is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_FCHDIR
+
+/* Define to 1 if fchownat is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_FCHOWNAT
+
+/* Define to 1 if fsync is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_FSYNC
+
+/* Define to 1 if ftruncate is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_FTRUNCATE
+
+/* Define to 1 if getcwd is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETCWD
+
+/* Define to 1 if getdomainname is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETDOMAINNAME
+
+/* Define to 1 if getdtablesize is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETDTABLESIZE
+
+/* Define to 1 if getgroups is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETGROUPS
+
+/* Define to 1 if gethostname is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETHOSTNAME
+
+/* Define to 1 if getloadavg is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETLOADAVG
+
+/* Define to 1 if getlogin is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETLOGIN
+
+/* Define to 1 if getlogin_r is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETLOGIN_R
+
+/* Define to 1 if getpagesize is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETPAGESIZE
+
+/* Define to 1 if getsubopt is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETSUBOPT
+
+/* Define to 1 if getusershell is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GETUSERSHELL
+
+/* Define to 1 if grantpt is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_GRANTPT
+
+/* Define to 1 if initstat_r is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_INITSTAT_R
+
+/* Define to 1 if lchown is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_LCHOWN
+
+/* Define to 1 if link is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_LINK
+
+/* Define to 1 if linkat is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_LINKAT
+
+/* Define to 1 if lseek is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_LSEEK
+
+/* Define to 1 if mbrlen is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MBRLEN
+
+/* Define to 1 if mbrtowc is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MBRTOWC
+
+/* Define to 1 if mbsinit is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MBSINIT
+
+/* Define to 1 if mbsnrtowcs is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MBSNRTOWCS
+
+/* Define to 1 if mbsrtowcs is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MBSRTOWCS
+
+/* Define to 1 if mkdtemp is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MKDTEMP
+
+/* Define to 1 if mkostemp is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MKOSTEMP
+
+/* Define to 1 if mkostemps is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MKOSTEMPS
+
+/* Define to 1 if mkstemp is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MKSTEMP
+
+/* Define to 1 if mkstemps is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_MKSTEMPS
+
+/* Define to 1 if nl_langinfo is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_NL_LANGINFO
+
+/* Define to 1 if pipe is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_PIPE
+
+/* Define to 1 if pipe2 is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_PIPE2
+
+/* Define to 1 if pread is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_PREAD
+
+/* Define to 1 if ptsname is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_PTSNAME
+
+/* Define to 1 if pwrite is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_PWRITE
+
+/* Define to 1 if random_r is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_RANDOM_R
+
+/* Define to 1 if readlink is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_READLINK
+
+/* Define to 1 if readlinkat is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_READLINKAT
+
+/* Define to 1 if realpath is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_REALPATH
+
+/* Define to 1 if rmdir is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_RMDIR
+
+/* Define to 1 if rpmatch is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_RPMATCH
+
+/* Define to 1 if setenv is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SETENV
+
+/* Define to 1 if setstate_r is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SETSTATE_R
+
+/* Define to 1 if setusershell is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SETUSERSHELL
+
+/* Define to 1 if sleep is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SLEEP
+
+/* Define to 1 if srandom_r is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SRANDOM_R
+
+/* Define to 1 if strtod is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_STRTOD
+
+/* Define to 1 if strtoll is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_STRTOLL
+
+/* Define to 1 if strtoull is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_STRTOULL
+
+/* Define to 1 if symlink is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SYMLINK
+
+/* Define to 1 if symlinkat is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_SYMLINKAT
+
+/* Define to 1 if ttyname_r is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_TTYNAME_R
+
+/* Define to 1 if unlink is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_UNLINK
+
+/* Define to 1 if unlinkat is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_UNLINKAT
+
+/* Define to 1 if unlockpt is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_UNLOCKPT
+
+/* Define to 1 if unsetenv is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_UNSETENV
+
+/* Define to 1 if usleep is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_USLEEP
+
+/* Define to 1 if wcrtomb is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_WCRTOMB
+
+/* Define to 1 if wcsnrtombs is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_WCSNRTOMBS
+
+/* Define to 1 if wcsrtombs is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_WCSRTOMBS
+
+/* Define to 1 if wctob is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_WCTOB
+
+/* Define to 1 if wcwidth is declared even after undefining macros. */
+#undef HAVE_RAW_DECL_WCWIDTH
+
+/* Define to 1 if _Exit is declared even after undefining macros. */
+#undef HAVE_RAW_DECL__EXIT
+
+/* Define to 1 if you have the `setenv' function. */
+#undef HAVE_SETENV
+
+/* Define to 1 if 'sig_atomic_t' is a signed integer type. */
+#undef HAVE_SIGNED_SIG_ATOMIC_T
+
+/* Define to 1 if 'wchar_t' is a signed integer type. */
+#undef HAVE_SIGNED_WCHAR_T
+
+/* Define to 1 if 'wint_t' is a signed integer type. */
+#undef HAVE_SIGNED_WINT_T
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#undef HAVE_STDDEF_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strerror' function. */
+#undef HAVE_STRERROR
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the `strtoul' function. */
+#undef HAVE_STRTOUL
+
+/* Define to 1 if the system has the type `struct random_data'. */
+#undef HAVE_STRUCT_RANDOM_DATA
+
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_BLKSIZE
+
+/* Define to 1 if you have the <sys/bitypes.h> header file. */
+#undef HAVE_SYS_BITYPES_H
+
+/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_DIR_H
+
+/* Define to 1 if you have the <sys/inttypes.h> header file. */
+#undef HAVE_SYS_INTTYPES_H
+
+/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
+   */
+#undef HAVE_SYS_NDIR_H
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#undef HAVE_SYS_PARAM_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the `timegm' function. */
+#undef HAVE_TIMEGM
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `unsigned long long int'. */
+#undef HAVE_UNSIGNED_LONG_LONG_INT
+
+/* Define to 1 if you have the <wchar.h> header file. */
+#undef HAVE_WCHAR_H
+
+/* Define if you have the 'wchar_t' type. */
+#undef HAVE_WCHAR_T
+
+/* Define to 1 if you have the `wcrtomb' function. */
+#undef HAVE_WCRTOMB
+
+/* Define to 1 if you have the `wcscoll' function. */
+#undef HAVE_WCSCOLL
+
+/* Define to 1 if you have the <wctype.h> header file. */
+#undef HAVE_WCTYPE_H
+
+/* Define if you have the 'wint_t' type. */
+#undef HAVE_WINT_T
+
+/* Define to 1 if O_NOATIME works. */
+#undef HAVE_WORKING_O_NOATIME
+
+/* Define to 1 if O_NOFOLLOW works. */
+#undef HAVE_WORKING_O_NOFOLLOW
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* Set to the prefix directory */
+#undef LIBDAP_ROOT
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#undef LT_OBJDIR
+
+/* Define if the mbrtowc function has the NULL pwc argument bug. */
+#undef MBRTOWC_NULL_ARG1_BUG
+
+/* Define if the mbrtowc function has the NULL string argument bug. */
+#undef MBRTOWC_NULL_ARG2_BUG
+
+/* Define if the mbrtowc function does not return 0 for a NUL character. */
+#undef MBRTOWC_NUL_RETVAL_BUG
+
+/* Define if the mbrtowc function returns a wrong return value. */
+#undef MBRTOWC_RETVAL_BUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the home page for this package. */
+#undef PACKAGE_URL
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
+   'ptrdiff_t'. */
+#undef PTRDIFF_T_SUFFIX
+
+/* Define if nl_langinfo exists but is overridden by gnulib. */
+#undef REPLACE_NL_LANGINFO
+
+/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
+   'sig_atomic_t'. */
+#undef SIG_ATOMIC_T_SUFFIX
+
+/* The size of `char', as computed by sizeof. */
+#undef SIZEOF_CHAR
+
+/* The size of `double', as computed by sizeof. */
+#undef SIZEOF_DOUBLE
+
+/* The size of `float', as computed by sizeof. */
+#undef SIZEOF_FLOAT
+
+/* The size of `int', as computed by sizeof. */
+#undef SIZEOF_INT
+
+/* The size of `int16_t', as computed by sizeof. */
+#undef SIZEOF_INT16_T
+
+/* The size of `int32_t', as computed by sizeof. */
+#undef SIZEOF_INT32_T
+
+/* The size of `long', as computed by sizeof. */
+#undef SIZEOF_LONG
+
+/* The size of `uint16_t', as computed by sizeof. */
+#undef SIZEOF_UINT16_T
+
+/* The size of `uint32_t', as computed by sizeof. */
+#undef SIZEOF_UINT32_T
+
+/* The size of `uint8_t', as computed by sizeof. */
+#undef SIZEOF_UINT8_T
+
+/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
+   'size_t'. */
+#undef SIZE_T_SUFFIX
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+	STACK_DIRECTION > 0 => grows toward higher addresses
+	STACK_DIRECTION < 0 => grows toward lower addresses
+	STACK_DIRECTION = 0 => direction of growth unknown */
+#undef STACK_DIRECTION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define to 1 if your <sys/time.h> declares `struct tm'. */
+#undef TM_IN_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
+   'wchar_t'. */
+#undef WCHAR_T_SUFFIX
+
+/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type
+   'wint_t'. */
+#undef WINT_T_SUFFIX
+
+/* xdr float32 */
+#undef XDR_FLOAT32
+
+/* xdr float64 */
+#undef XDR_FLOAT64
+
+/* xdr int16 */
+#undef XDR_INT16
+
+/* xdr int32 */
+#undef XDR_INT32
+
+/* xdr uint16 */
+#undef XDR_UINT16
+
+/* xdr uint32 */
+#undef XDR_UINT32
+
+/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a
+   `char[]'. */
+#undef YYTEXT_POINTER
+
+/* Define to 1 if on MINIX. */
+#undef _MINIX
+
+/* Define to 2 if the system does not provide POSIX.1 features except with
+   this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define to 1 if you need to in order for `stat' and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define if you want regoff_t to be at least as wide POSIX requires. */
+#undef _REGEX_LARGE_OFFSETS
+
+/* Define to 500 only on HP-UX. */
+#undef _XOPEN_SOURCE
+
+/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+   calls it, or to nothing if 'inline' is not supported under any name.  */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports
+   the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of
+   earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.
+   __APPLE__ && __MACH__ test for MacOS X.
+   __APPLE_CC__ tests for the Apple compiler and its version.
+   __STDC_VERSION__ tests for the C99 mode.  */
+#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__
+# define __GNUC_STDC_INLINE__ 1
+#endif
+
+/* Define to a type if <wchar.h> does not define. */
+#undef mbstate_t
+
+/* Define to rpl_re_comp if the replacement should be used. */
+#undef re_comp
+
+/* Define to rpl_re_compile_fastmap if the replacement should be used. */
+#undef re_compile_fastmap
+
+/* Define to rpl_re_compile_pattern if the replacement should be used. */
+#undef re_compile_pattern
+
+/* Define to rpl_re_exec if the replacement should be used. */
+#undef re_exec
+
+/* Define to rpl_re_match if the replacement should be used. */
+#undef re_match
+
+/* Define to rpl_re_match_2 if the replacement should be used. */
+#undef re_match_2
+
+/* Define to rpl_re_search if the replacement should be used. */
+#undef re_search
+
+/* Define to rpl_re_search_2 if the replacement should be used. */
+#undef re_search_2
+
+/* Define to rpl_re_set_registers if the replacement should be used. */
+#undef re_set_registers
+
+/* Define to rpl_re_set_syntax if the replacement should be used. */
+#undef re_set_syntax
+
+/* Define to rpl_re_syntax_options if the replacement should be used. */
+#undef re_syntax_options
+
+/* Define to rpl_regcomp if the replacement should be used. */
+#undef regcomp
+
+/* Define to rpl_regerror if the replacement should be used. */
+#undef regerror
+
+/* Define to rpl_regexec if the replacement should be used. */
+#undef regexec
+
+/* Define to rpl_regfree if the replacement should be used. */
+#undef regfree
+
+/* Define to the equivalent of the C99 'restrict' keyword, or to
+   nothing if this is not supported.  Do not define if restrict is
+   supported directly.  */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict or
+   __restrict__, even though the corresponding Sun C compiler ends up with
+   "#define restrict _Restrict" or "#define restrict __restrict__" in the
+   previous line.  Perhaps some future version of Sun C++ will work with
+   restrict; if so, hopefully it defines __RESTRICT like Sun C does.  */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+# define __restrict__
+#endif
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
+
+/* Define as a signed type of the same size as size_t. */
+#undef ssize_t
+
+/* Define as a marker that can be attached to declarations that might not
+    be used.  This helps to reduce warnings, such as from
+    GCC -Wunused-parameter.  */
+#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+# define _GL_UNUSED __attribute__ ((__unused__))
+#else
+# define _GL_UNUSED
+#endif
+/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name
+   is a misnomer outside of parameter lists.  */
+#define _UNUSED_PARAMETER_ _GL_UNUSED
+
+
+/* Define to empty if the keyword `volatile' does not work. Warning: valid
+   code using `volatile' can become incorrect without. Disable with care. */
+#undef volatile
+
+/* Shorthand for gcc's unused attribute feature */
+#if defined(__GNUG__) || defined(__GNUC__)
+#define not_used __attribute__ ((unused))
+#else
+#define not_used 
+#endif /* __GNUG__ || __GNUC__ */
+
+#endif /* _config_h */
diff --git a/config_dap.h b/config_dap.h
new file mode 100644
index 0000000..e9e1c3f
--- /dev/null
+++ b/config_dap.h
@@ -0,0 +1,20 @@
+/* config.h.  Generated by configure.  */
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+#ifndef _config_dap_h
+#define _config_dap_h
+
+#ifdef HAVE_CONFIG_H
+
+#include "config.h"
+
+#endif /* HAVE_CONFIG_H */
+
+/* Shorthand for gcc's unused attribute feature */
+#if defined(__GNUG__) || defined(__GNUC__)
+#define not_used __attribute__ ((unused))
+#else
+#define not_used
+#endif /* __GNUG__ || __GNUC__ */
+
+#endif /* _config_dap_h */
diff --git a/configure b/configure
new file mode 100755
index 0000000..7b1b773
--- /dev/null
+++ b/configure
@@ -0,0 +1,25697 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.65 for libdap 3.11.1.
+#
+# Report bugs to <opendap-tech at opendap.org>.
+#
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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 more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+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
+IFS=$as_save_IFS
+
+     ;;
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org and
+$0: opendap-tech at opendap.org about your system, including
+$0: any error possibly output before this message. Then
+$0: install a modern shell, or manually run the script
+$0: under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# 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
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# 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'"
+
+
+
+# Check that we are running under the correct shell.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+case X$lt_ECHO in
+X*--fallback-echo)
+  # Remove one level of quotation (which was required for Make).
+  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
+  ;;
+esac
+
+ECHO=${lt_ECHO-echo}
+if test "X$1" = X--no-reexec; then
+  # Discard the --no-reexec flag, and continue.
+  shift
+elif test "X$1" = X--fallback-echo; then
+  # Avoid inline document here, it may be left over
+  :
+elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
+  # Yippee, $ECHO works!
+  :
+else
+  # Restart under the correct shell.
+  exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+  # used as fallback echo
+  shift
+  cat <<_LT_EOF
+$*
+_LT_EOF
+  exit 0
+fi
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test -z "$lt_ECHO"; then
+  if test "X${echo_test_string+set}" != Xset; then
+    # find a string as large as possible, as long as the shell can cope with it
+    for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
+      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
+      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
+	 { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
+      then
+        break
+      fi
+    done
+  fi
+
+  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+     test "X$echo_testing_string" = "X$echo_test_string"; then
+    :
+  else
+    # The Solaris, AIX, and Digital Unix default echo programs unquote
+    # backslashes.  This makes it impossible to quote backslashes using
+    #   echo "$something" | sed 's/\\/\\\\/g'
+    #
+    # So, first we look for a working echo in the user's PATH.
+
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for dir in $PATH /usr/ucb; do
+      IFS="$lt_save_ifs"
+      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
+         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        ECHO="$dir/echo"
+        break
+      fi
+    done
+    IFS="$lt_save_ifs"
+
+    if test "X$ECHO" = Xecho; then
+      # We didn't find a better echo, so look for alternatives.
+      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
+         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
+         test "X$echo_testing_string" = "X$echo_test_string"; then
+        # This shell has a builtin print -r that does the trick.
+        ECHO='print -r'
+      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
+	   test "X$CONFIG_SHELL" != X/bin/ksh; then
+        # If we have ksh, try running configure again with it.
+        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+        export ORIGINAL_CONFIG_SHELL
+        CONFIG_SHELL=/bin/ksh
+        export CONFIG_SHELL
+        exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
+      else
+        # Try using printf.
+        ECHO='printf %s\n'
+        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
+	   echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
+	   test "X$echo_testing_string" = "X$echo_test_string"; then
+	  # Cool, printf works
+	  :
+        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
+	  export CONFIG_SHELL
+	  SHELL="$CONFIG_SHELL"
+	  export SHELL
+	  ECHO="$CONFIG_SHELL $0 --fallback-echo"
+        elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
+	     test "X$echo_testing_string" = 'X\t' &&
+	     echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
+	     test "X$echo_testing_string" = "X$echo_test_string"; then
+	  ECHO="$CONFIG_SHELL $0 --fallback-echo"
+        else
+	  # maybe with a smaller string...
+	  prev=:
+
+	  for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
+	    if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
+	    then
+	      break
+	    fi
+	    prev="$cmd"
+	  done
+
+	  if test "$prev" != 'sed 50q "$0"'; then
+	    echo_test_string=`eval $prev`
+	    export echo_test_string
+	    exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
+	  else
+	    # Oops.  We lost completely, so just stick with echo.
+	    ECHO=echo
+	  fi
+        fi
+      fi
+    fi
+  fi
+fi
+
+# Copy echo and quote the copy suitably for passing to libtool from
+# the Makefile, instead of quoting the original, which is used later.
+lt_ECHO=$ECHO
+if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
+   lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
+fi
+
+
+
+
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
+
+# 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`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='libdap'
+PACKAGE_TARNAME='libdap'
+PACKAGE_VERSION='3.11.1'
+PACKAGE_STRING='libdap 3.11.1'
+PACKAGE_BUGREPORT='opendap-tech at opendap.org'
+PACKAGE_URL=''
+
+ac_unique_file="Connect.cc"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_func_list=
+ac_header_list=
+ac_subst_vars='gltests_LTLIBOBJS
+gltests_LIBOBJS
+gl_LTLIBOBJS
+gl_LIBOBJS
+am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+CPPUNIT_LIBS
+CPPUNIT_CFLAGS
+CPPUNIT_FALSE
+CPPUNIT_TRUE
+CPPUNIT_CONFIG
+UUID_LIBS
+PTHREAD_LIBS
+ZLIB_CFLAGS
+ZLIB_LDFLAGS
+ZLIB_LIBS
+XML2_STATIC_LIBS
+xmlprivatelibs
+xmlprivatereq
+XML2_LIBS
+XML2_CFLAGS
+CURL_STATIC_LIBS
+curlprivatelibs
+curlprivatereq
+CURL_LIBS
+CURL_CFLAGS
+PKG_CONFIG
+gltests_WITNESS
+REPLACE_ISWCNTRL
+HAVE_WCTYPE_H
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H
+NEXT_WCTYPE_H
+REPLACE_ISWBLANK
+HAVE_ISWBLANK
+HAVE_ISWCNTRL
+HAVE_WINT_T
+HAVE_FEATURES_H
+HAVE_WCHAR_H
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H
+NEXT_WCHAR_H
+HAVE_UNISTD_H
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H
+NEXT_UNISTD_H
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS
+UNISTD_H_HAVE_WINSOCK2_H
+REPLACE_WRITE
+REPLACE_USLEEP
+REPLACE_UNLINKAT
+REPLACE_UNLINK
+REPLACE_TTYNAME_R
+REPLACE_SYMLINK
+REPLACE_SLEEP
+REPLACE_RMDIR
+REPLACE_READLINK
+REPLACE_PWRITE
+REPLACE_PREAD
+REPLACE_LSEEK
+REPLACE_LINKAT
+REPLACE_LINK
+REPLACE_LCHOWN
+REPLACE_GETPAGESIZE
+REPLACE_GETGROUPS
+REPLACE_GETLOGIN_R
+REPLACE_GETDOMAINNAME
+REPLACE_GETCWD
+REPLACE_FCHOWNAT
+REPLACE_DUP2
+REPLACE_DUP
+REPLACE_CLOSE
+REPLACE_CHOWN
+HAVE_SYS_PARAM_H
+HAVE_OS_H
+HAVE_DECL_TTYNAME_R
+HAVE_DECL_GETUSERSHELL
+HAVE_DECL_GETPAGESIZE
+HAVE_DECL_GETLOGIN_R
+HAVE_DECL_GETDOMAINNAME
+HAVE_DECL_FCHDIR
+HAVE_DECL_ENVIRON
+HAVE_USLEEP
+HAVE_UNLINKAT
+HAVE_SYMLINKAT
+HAVE_SYMLINK
+HAVE_SLEEP
+HAVE_READLINKAT
+HAVE_READLINK
+HAVE_PWRITE
+HAVE_PREAD
+HAVE_PIPE2
+HAVE_PIPE
+HAVE_LINKAT
+HAVE_LINK
+HAVE_LCHOWN
+HAVE_GETPAGESIZE
+HAVE_GETLOGIN
+HAVE_GETHOSTNAME
+HAVE_GETGROUPS
+HAVE_GETDTABLESIZE
+HAVE_FTRUNCATE
+HAVE_FSYNC
+HAVE_FCHOWNAT
+HAVE_FCHDIR
+HAVE_FACCESSAT
+HAVE_EUIDACCESS
+HAVE_DUP3
+HAVE_DUP2
+HAVE_CHOWN
+GNULIB_WRITE
+GNULIB_USLEEP
+GNULIB_UNLINKAT
+GNULIB_UNLINK
+GNULIB_UNISTD_H_SIGPIPE
+GNULIB_UNISTD_H_GETOPT
+GNULIB_TTYNAME_R
+GNULIB_SYMLINKAT
+GNULIB_SYMLINK
+GNULIB_SLEEP
+GNULIB_RMDIR
+GNULIB_READLINKAT
+GNULIB_READLINK
+GNULIB_PWRITE
+GNULIB_PREAD
+GNULIB_PIPE2
+GNULIB_PIPE
+GNULIB_LSEEK
+GNULIB_LINKAT
+GNULIB_LINK
+GNULIB_LCHOWN
+GNULIB_GETUSERSHELL
+GNULIB_GETPAGESIZE
+GNULIB_GETLOGIN_R
+GNULIB_GETLOGIN
+GNULIB_GETHOSTNAME
+GNULIB_GETGROUPS
+GNULIB_GETDTABLESIZE
+GNULIB_GETDOMAINNAME
+GNULIB_GETCWD
+GNULIB_FTRUNCATE
+GNULIB_FSYNC
+GNULIB_FCHOWNAT
+GNULIB_FCHDIR
+GNULIB_FACCESSAT
+GNULIB_EUIDACCESS
+GNULIB_ENVIRON
+GNULIB_DUP3
+GNULIB_DUP2
+GNULIB_CLOSE
+GNULIB_CHOWN
+HAVE_RANDOM_H
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H
+NEXT_STDLIB_H
+STDINT_H
+WINT_T_SUFFIX
+WCHAR_T_SUFFIX
+SIG_ATOMIC_T_SUFFIX
+SIZE_T_SUFFIX
+PTRDIFF_T_SUFFIX
+HAVE_SIGNED_WINT_T
+HAVE_SIGNED_WCHAR_T
+HAVE_SIGNED_SIG_ATOMIC_T
+BITSIZEOF_WINT_T
+BITSIZEOF_WCHAR_T
+BITSIZEOF_SIG_ATOMIC_T
+BITSIZEOF_SIZE_T
+BITSIZEOF_PTRDIFF_T
+HAVE_SYS_BITYPES_H
+HAVE_SYS_INTTYPES_H
+HAVE_STDINT_H
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H
+NEXT_STDINT_H
+HAVE_SYS_TYPES_H
+HAVE_INTTYPES_H
+HAVE_UNSIGNED_LONG_LONG_INT
+HAVE_LONG_LONG_INT
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H
+NEXT_STDDEF_H
+STDDEF_H
+HAVE_WCHAR_T
+REPLACE_NULL
+HAVE__BOOL
+STDBOOL_H
+APPLE_UNIVERSAL_BUILD
+LOCALE_FR_UTF8
+LOCALE_ZH_CN
+LOCALE_JA
+REPLACE_UNSETENV
+REPLACE_STRTOD
+REPLACE_SETENV
+REPLACE_REALPATH
+REPLACE_REALLOC
+REPLACE_PUTENV
+REPLACE_MKSTEMP
+REPLACE_MALLOC
+REPLACE_CANONICALIZE_FILE_NAME
+REPLACE_CALLOC
+HAVE_DECL_UNSETENV
+HAVE_UNLOCKPT
+HAVE_SYS_LOADAVG_H
+HAVE_STRUCT_RANDOM_DATA
+HAVE_STRTOULL
+HAVE_STRTOLL
+HAVE_STRTOD
+HAVE_DECL_SETENV
+HAVE_SETENV
+HAVE_RPMATCH
+HAVE_REALPATH
+HAVE_RANDOM_R
+HAVE_PTSNAME
+HAVE_MKSTEMPS
+HAVE_MKSTEMP
+HAVE_MKOSTEMPS
+HAVE_MKOSTEMP
+HAVE_MKDTEMP
+HAVE_GRANTPT
+HAVE_GETSUBOPT
+HAVE_DECL_GETLOADAVG
+HAVE_CANONICALIZE_FILE_NAME
+HAVE_ATOLL
+HAVE__EXIT
+GNULIB_UNSETENV
+GNULIB_UNLOCKPT
+GNULIB_SYSTEM_POSIX
+GNULIB_STRTOULL
+GNULIB_STRTOLL
+GNULIB_STRTOD
+GNULIB_SETENV
+GNULIB_RPMATCH
+GNULIB_REALPATH
+GNULIB_REALLOC_POSIX
+GNULIB_RANDOM_R
+GNULIB_PUTENV
+GNULIB_PTSNAME
+GNULIB_MKSTEMPS
+GNULIB_MKSTEMP
+GNULIB_MKOSTEMPS
+GNULIB_MKOSTEMP
+GNULIB_MKDTEMP
+GNULIB_MALLOC_POSIX
+GNULIB_GRANTPT
+GNULIB_GETSUBOPT
+GNULIB_GETLOADAVG
+GNULIB_CANONICALIZE_FILE_NAME
+GNULIB_CALLOC_POSIX
+GNULIB_ATOLL
+GNULIB__EXIT
+LOCALCHARSET_TESTS_ENVIRONMENT
+GLIBC21
+HAVE_LANGINFO_YESEXPR
+HAVE_LANGINFO_ERA
+HAVE_LANGINFO_T_FMT_AMPM
+HAVE_LANGINFO_CODESET
+HAVE_LANGINFO_H
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H
+NEXT_LANGINFO_H
+PRAGMA_COLUMNS
+PRAGMA_SYSTEM_HEADER
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE
+INCLUDE_NEXT
+REPLACE_NL_LANGINFO
+HAVE_NL_LANGINFO
+GNULIB_NL_LANGINFO
+LTLIBINTL
+LIBINTL
+pkglibexecdir
+lispdir
+LOCALE_FR
+REPLACE_WCWIDTH
+REPLACE_WCSNRTOMBS
+REPLACE_WCSRTOMBS
+REPLACE_WCRTOMB
+REPLACE_MBSNRTOWCS
+REPLACE_MBSRTOWCS
+REPLACE_MBRLEN
+REPLACE_MBRTOWC
+REPLACE_MBSINIT
+REPLACE_WCTOB
+REPLACE_BTOWC
+REPLACE_MBSTATE_T
+HAVE_DECL_WCWIDTH
+HAVE_DECL_WCTOB
+HAVE_WCSNRTOMBS
+HAVE_WCSRTOMBS
+HAVE_WCRTOMB
+HAVE_MBSNRTOWCS
+HAVE_MBSRTOWCS
+HAVE_MBRLEN
+HAVE_MBRTOWC
+HAVE_MBSINIT
+HAVE_BTOWC
+GNULIB_WCWIDTH
+GNULIB_WCSNRTOMBS
+GNULIB_WCSRTOMBS
+GNULIB_WCRTOMB
+GNULIB_MBSNRTOWCS
+GNULIB_MBSRTOWCS
+GNULIB_MBRLEN
+GNULIB_MBRTOWC
+GNULIB_MBSINIT
+GNULIB_WCTOB
+GNULIB_BTOWC
+ALLOCA_H
+ALLOCA
+GL_COND_LIBTOOL_FALSE
+GL_COND_LIBTOOL_TRUE
+COMPILER_IS_GCC_FALSE
+COMPILER_IS_GCC_TRUE
+USE_C99_TYPES_FALSE
+USE_C99_TYPES_TRUE
+YACC
+CXXCPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+lt_ECHO
+AR
+OBJDUMP
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+LN_S
+LEXLIB
+LEX_OUTPUT_ROOT
+LEX
+EGREP
+GREP
+CPP
+RANLIB
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+ac_ct_CC
+CFLAGS
+CC
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CXX
+CPPFLAGS
+LDFLAGS
+CXXFLAGS
+CXX
+SERVERLIB_VERSION
+SERVERLIB_REVISION
+SERVERLIB_AGE
+SERVERLIB_CURRENT
+CLIENTLIB_VERSION
+CLIENTLIB_REVISION
+CLIENTLIB_AGE
+CLIENTLIB_CURRENT
+LIBDAP_VERSION
+DAPLIB_REVISION
+DAPLIB_AGE
+DAPLIB_CURRENT
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+EVAL
+PACKAGE_SUBMINOR_VERSION
+PACKAGE_MINOR_VERSION
+PACKAGE_MAJOR_VERSION
+DVR
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+DAP_PROTOCOL_VERSION
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+with_included_regex
+with_zlib
+with_cppunit_prefix
+with_cppunit_exec_prefix
+enable_debug
+'
+      ac_precious_vars='build_alias
+host_alias
+target_alias
+CXX
+CXXFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CCC
+CC
+CFLAGS
+CPP
+CXXCPP
+PKG_CONFIG
+CURL_CFLAGS
+CURL_LIBS
+XML2_CFLAGS
+XML2_LIBS'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# 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.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+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
+
+  case $ac_option in
+  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *)	ac_optarg=yes ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_dashdash$ac_option in
+  --)
+    ac_dashdash=yes ;;
+
+  -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)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=*)
+    datadir=$ac_optarg ;;
+
+  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+  | --dataroo | --dataro | --datar)
+    ac_prev=datarootdir ;;
+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+    datarootdir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=no ;;
+
+  -docdir | --docdir | --docdi | --doc | --do)
+    ac_prev=docdir ;;
+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+    docdir=$ac_optarg ;;
+
+  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+    ac_prev=dvidir ;;
+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+    dvidir=$ac_optarg ;;
+
+  -enable-* | --enable-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid feature name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"enable_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval enable_$ac_useropt=\$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 ;;
+
+  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+    ac_prev=htmldir ;;
+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+  | --ht=*)
+    htmldir=$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 ;;
+
+  -localedir | --localedir | --localedi | --localed | --locale)
+    ac_prev=localedir ;;
+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+    localedir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst | --locals)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+    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 ;;
+
+  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+    ac_prev=pdfdir ;;
+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+    pdfdir=$ac_optarg ;;
+
+  -psdir | --psdir | --psdi | --psd | --ps)
+    ac_prev=psdir ;;
+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+    psdir=$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_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=\$ac_optarg ;;
+
+  -without-* | --without-*)
+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+      as_fn_error "invalid package name: $ac_useropt"
+    ac_useropt_orig=$ac_useropt
+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    case $ac_user_opts in
+      *"
+"with_$ac_useropt"
+"*) ;;
+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+	 ac_unrecognized_sep=', ';;
+    esac
+    eval with_$ac_useropt=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 ;;
+
+  -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    case $ac_envvar in #(
+      '' | [0-9]* | *[!_$as_cr_alnum]* )
+      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+    esac
+    eval $ac_envvar=\$ac_optarg
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      $as_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'`
+  as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+  case $enable_option_checking in
+    no) ;;
+    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+  esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \
+		datadir sysconfdir sharedstatedir localstatedir includedir \
+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+		libdir localedir mandir
+do
+  eval ac_val=\$$ac_var
+  # Remove trailing slashes.
+  case $ac_val in
+    */ )
+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+      eval $ac_var=\$ac_val;;
+  esac
+  # Be sure to have absolute directory names.
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* )  continue;;
+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+  esac
+  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+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
+    $as_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
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+  as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+  as_fn_error "pwd does not report name of working directory"
+
+
+# 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 the parent directory.
+  ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_myself" : 'X\(//\)[^/]' \| \
+	 X"$as_myself" : 'X\(//\)$' \| \
+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+    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
+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+  srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+  eval ac_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_env_${ac_var}_value=\$${ac_var}
+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+  eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# 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 libdap 3.11.1 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 \`..']
+
+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]
+  --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]
+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]
+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]
+  --infodir=DIR           info documentation [DATAROOTDIR/info]
+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]
+  --mandir=DIR            man documentation [DATAROOTDIR/man]
+  --docdir=DIR            documentation root [DATAROOTDIR/doc/libdap]
+  --htmldir=DIR           html documentation [DOCDIR]
+  --dvidir=DIR            dvi documentation [DOCDIR]
+  --pdfdir=DIR            pdf documentation [DOCDIR]
+  --psdir=DIR             ps documentation [DOCDIR]
+_ACEOF
+
+  cat <<\_ACEOF
+
+Program names:
+  --program-prefix=PREFIX            prepend PREFIX to installed program names
+  --program-suffix=SUFFIX            append SUFFIX to installed program names
+  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names
+
+System types:
+  --build=BUILD     configure for building on BUILD [guessed]
+  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+  case $ac_init_help in
+     short | recursive ) echo "Configuration of libdap 3.11.1:";;
+   esac
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-option-checking  ignore unrecognized --enable/--with options
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --disable-dependency-tracking  speeds up one-time build
+  --enable-dependency-tracking   do not reject slow dependency extractors
+  --enable-shared[=PKGS]  build shared libraries [default=yes]
+  --enable-static[=PKGS]  build static libraries [default=yes]
+  --enable-fast-install[=PKGS]
+                          optimize for fast installation [default=yes]
+  --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-debug=ARG      Program instrumentation (1,2)
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-pic              try to use only PIC/non-PIC objects [default=use
+                          both]
+  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --without-included-regex
+                          don't compile regex; this is the default on systems
+                          with recent-enough versions of the GNU C Library
+                          (use with caution on other systems).
+  --with-zlib=DIR root directory path of zlib installation defaults to
+                    /usr/local or /usr if not found in /usr/local
+  --without-zlib to disable zlib usage completely
+  --with-cppunit-prefix=PFX   Prefix where CppUnit is installed (optional)
+  --with-cppunit-exec-prefix=PFX  Exec prefix where CppUnit is installed (optional)
+
+Some influential environment variables:
+  CXX         C++ compiler command
+  CXXFLAGS    C++ compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  LIBS        libraries to pass to the linker, e.g. -l<library>
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+              you have headers in a nonstandard directory <include dir>
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  CPP         C preprocessor
+  CXXCPP      C++ preprocessor
+  PKG_CONFIG  path to pkg-config utility
+  CURL_CFLAGS C compiler flags for CURL, overriding pkg-config
+  CURL_LIBS   linker flags for CURL, overriding pkg-config
+  XML2_CFLAGS C compiler flags for XML2, overriding pkg-config
+  XML2_LIBS   linker flags for XML2, overriding pkg-config
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to <opendap-tech at opendap.org>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d "$ac_dir" ||
+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+      continue
+    ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+    cd "$ac_dir" || { ac_status=$?; continue; }
+    # Check for guested 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
+    else
+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi || ac_status=$?
+    cd "$ac_pwd" || { ac_status=$?; break; }
+  done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+  cat <<\_ACEOF
+libdap configure 3.11.1
+generated by GNU Autoconf 2.65
+
+Copyright (C) 2009 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
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_compile
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext
+  if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( cat <<\_ASBOX
+## --------------------------------------- ##
+## Report this to opendap-tech at opendap.org ##
+## --------------------------------------- ##
+_ASBOX
+     ) | sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: program exited with status $ac_status" >&5
+       $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $2 (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_func
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_cpp ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } >/dev/null && {
+	 test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  rm -f conftest.$ac_objext conftest$ac_exeext
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
+  fi
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && {
+	 test -z "$ac_cxx_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then :
+  ac_retval=0
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_retval=1
+fi
+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+  # interfere with the next link command; also delete a directory that is
+  # left behind by Apple's compiler.  We do this before executing the actions.
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_cxx_try_link
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+	 return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+	    return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$4=yes"
+else
+  eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_member
+
+# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
+# --------------------------------------------
+# Tries to find the compile-time value of EXPR in a program that includes
+# INCLUDES, setting VAR accordingly. Returns whether the value could be
+# computed
+ac_fn_c_compute_int ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if test "$cross_compiling" = yes; then
+    # Depending upon the size, compute the lo and hi bounds.
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=0 ac_mid=0
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid; break
+else
+  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
+			if test $ac_lo -le $ac_mid; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) < 0)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=-1 ac_mid=-1
+  while :; do
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) >= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_lo=$ac_mid; break
+else
+  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
+			if test $ac_mid -le $ac_hi; then
+			  ac_lo= ac_hi=
+			  break
+			fi
+			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  done
+else
+  ac_lo= ac_hi=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+# Binary search between lo and hi bounds.
+while test "x$ac_lo" != "x$ac_hi"; do
+  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+static int test_array [1 - 2 * !(($2) <= $ac_mid)];
+test_array [0] = 0
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_hi=$ac_mid
+else
+  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+case $ac_lo in #((
+?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
+'') ac_retval=1 ;;
+esac
+  else
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+static long int longval () { return $2; }
+static unsigned long int ulongval () { return $2; }
+#include <stdio.h>
+#include <stdlib.h>
+int
+main ()
+{
+
+  FILE *f = fopen ("conftest.val", "w");
+  if (! f)
+    return 1;
+  if (($2) < 0)
+    {
+      long int i = longval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%ld", i);
+    }
+  else
+    {
+      unsigned long int i = ulongval ();
+      if (i != ($2))
+	return 1;
+      fprintf (f, "%lu", i);
+    }
+  /* Do not output a trailing newline, as this causes \r\n confusion
+     on some platforms.  */
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
+else
+  ac_retval=1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+rm -f conftest.val
+
+  fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_compute_int
+
+# ac_fn_c_check_decl LINENO SYMBOL VAR
+# ------------------------------------
+# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+ac_fn_c_check_decl ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
+$as_echo_n "checking whether $2 is declared... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+int
+main ()
+{
+#ifndef $2
+  (void) $2;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$3=yes"
+else
+  eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_decl
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by libdap $as_me 3.11.1, which was
+generated by GNU Autoconf 2.65.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+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`
+/usr/bin/hostinfo      = `(/usr/bin/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=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+} >&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_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=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+    2)
+      as_fn_append 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
+      as_fn_append ac_configure_args " '$ac_arg'"
+      ;;
+    esac
+  done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset 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: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+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,
+(
+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+  (set) 2>&1 |
+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+    *${as_nl}ac_space=\ *)
+      sed -n \
+	"s/'\''/'\''\\\\'\'''\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+      ;; #(
+    *)
+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+)
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=\$$ac_var
+      case $ac_val in
+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      esac
+      $as_echo "$ac_var='\''$ac_val'\''"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=\$$ac_var
+	case $ac_val in
+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	esac
+	$as_echo "$ac_var='\''$ac_val'\''"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      cat confdefs.h
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      $as_echo "$as_me: caught signal $ac_signal"
+    $as_echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core core.conftest.* &&
+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > 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
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+  ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+  ac_site_file1=$prefix/share/config.site
+  ac_site_file2=$prefix/etc/config.site
+else
+  ac_site_file1=$ac_default_prefix/share/config.site
+  ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+  test "x$ac_site_file" = xNONE && continue
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_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.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . "$cache_file";;
+      *)                      . "./$cache_file";;
+    esac
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+as_fn_append ac_func_list " btowc"
+as_fn_append ac_header_list " langinfo.h"
+as_fn_append ac_func_list " mbsinit"
+as_fn_append ac_func_list " mbrtowc"
+as_fn_append ac_func_list " nl_langinfo"
+as_fn_append ac_func_list " isblank"
+as_fn_append ac_func_list " iswctype"
+as_fn_append ac_func_list " wcscoll"
+as_fn_append ac_header_list " stdint.h"
+as_fn_append ac_header_list " wchar.h"
+as_fn_append ac_header_list " unistd.h"
+as_fn_append ac_header_list " features.h"
+as_fn_append ac_func_list " wcrtomb"
+as_fn_append ac_func_list " iswcntrl"
+as_fn_append ac_func_list " iswblank"
+as_fn_append ac_header_list " wctype.h"
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; 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,)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_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
+	# differences in whitespace do not lead to failure.
+	ac_old_val_w=`echo x $ac_old_val`
+	ac_new_val_w=`echo x $ac_new_val`
+	if test "$ac_old_val_w" != "$ac_new_val_w"; then
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  ac_cache_corrupted=:
+	else
+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  eval $ac_var=\$ac_old_val
+	fi
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *\'*) ac_arg=$ac_var=`$as_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.
+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+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
+
+
+
+$as_echo "#define DAP_PROTOCOL_VERSION \"3.4\"" >>confdefs.h
+
+
+
+
+ac_aux_dir=
+for ac_dir in conf "$srcdir"/conf; do
+  for ac_t in install-sh install.sh shtool; do
+    if test -f "$ac_dir/$ac_t"; then
+      ac_aux_dir=$ac_dir
+      ac_install_sh="$ac_aux_dir/$ac_t -c"
+      break 2
+    fi
+  done
+done
+if test -z "$ac_aux_dir"; then
+  as_fn_error "cannot find install-sh, install.sh, or shtool in conf \"$srcdir\"/conf" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
+
+
+ac_config_headers="$ac_config_headers config.h dods-datatypes-config.h xdr-datatypes-config.h"
+
+
+
+am__api_version='1.11'
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+  ./ | .// | /[cC]/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    rm -rf conftest.one conftest.two conftest.dir
+	    echo one > conftest.one
+	    echo two > conftest.two
+	    mkdir conftest.dir
+	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	      test -s conftest.one && test -s conftest.two &&
+	      test -s conftest.dir/conftest.one &&
+	      test -s conftest.dir/conftest.two
+	    then
+	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      break 3
+	    fi
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+
+  done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    INSTALL=$ac_install_sh
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name.  Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+  *[\\\"\#\$\&\'\`$am_lf]*)
+    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+  *[\\\"\#\$\&\'\`$am_lf\ \	]*)
+    as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments.  Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+   set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+   if test "$*" = "X"; then
+      # -L didn't work.
+      set X `ls -t "$srcdir/configure" conftest.file`
+   fi
+   rm -f conftest.file
+   if test "$*" != "X $srcdir/configure conftest.file" \
+      && test "$*" != "X conftest.file $srcdir/configure"; then
+
+      # If neither matched, then we have a broken ls.  This can happen
+      # if, for instance, CONFIG_SHELL is bash and it inherits a
+      # broken ls alias from the environment.  This has actually
+      # happened.  Such a system could not be considered "sane".
+      as_fn_error "ls -t appears to fail.  Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+   fi
+
+   test "$2" = conftest.file
+   )
+then
+   # Ok.
+   :
+else
+   as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+  program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+  program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+  *)
+    MISSING="\${SHELL} $am_aux_dir/missing" ;;
+  esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+  am_missing_run="$MISSING --run "
+else
+  am_missing_run=
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+  case $am_aux_dir in
+  *\ * | *\	*)
+    install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+  *)
+    install_sh="\${SHELL} $am_aux_dir/install-sh"
+  esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'.  However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+  if test "${ac_cv_path_mkdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in mkdir gmkdir; do
+	 for ac_exec_ext in '' $ac_executable_extensions; do
+	   { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir (GNU coreutils) '* | \
+	     'mkdir (coreutils) '* | \
+	     'mkdir (fileutils) '4.1*)
+	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       break 3;;
+	   esac
+	 done
+       done
+  done
+IFS=$as_save_IFS
+
+fi
+
+  test -d ./--version && rmdir ./--version
+  if test "${ac_cv_path_mkdir+set}" = set; then
+    MKDIR_P="$ac_cv_path_mkdir -p"
+  else
+    # As a last resort, use the slow shell script.  Don't cache a
+    # value for MKDIR_P within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the value is a relative name.
+    MKDIR_P="$ac_install_sh -d"
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+  [\\/$]* | ?:[\\/]*) ;;
+  */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+  am__leading_dot=.
+else
+  am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+  # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+  # is not polluted with repeated "-I."
+  am__isrc=' -I$(srcdir)'
+  # test to see if srcdir already configured
+  if test -f $srcdir/config.status; then
+    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+  fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+  if (cygpath --version) >/dev/null 2>/dev/null; then
+    CYGPATH_W='cygpath -w'
+  else
+    CYGPATH_W=echo
+  fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='libdap'
+ VERSION='3.11.1'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target.  The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+ac_config_commands="$ac_config_commands tests/atconfig"
+
+
+
+
+$as_echo "#define CNAME \"libdap\"" >>confdefs.h
+
+
+cat >>confdefs.h <<_ACEOF
+#define CVER "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DVR "libdap/$PACKAGE_VERSION"
+_ACEOF
+
+
+
+
+PACKAGE_MAJOR_VERSION=`echo $PACKAGE_VERSION | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\1@'`
+PACKAGE_MINOR_VERSION=`echo $PACKAGE_VERSION | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\2@'`
+PACKAGE_SUBMINOR_VERSION=`echo $PACKAGE_VERSION | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\3@'`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Package Major Version:     $PACKAGE_MAJOR_VERSION" >&5
+$as_echo "$as_me: Package Major Version:     $PACKAGE_MAJOR_VERSION" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Package Minor Version:     $PACKAGE_MINOR_VERSION" >&5
+$as_echo "$as_me: Package Minor Version:     $PACKAGE_MINOR_VERSION" >&6;}
+{ $as_echo "$as_me:${as_lineno-$LINENO}: Package SubMinor Version:  $PACKAGE_SUBMINOR_VERSION" >&5
+$as_echo "$as_me: Package SubMinor Version:  $PACKAGE_SUBMINOR_VERSION" >&6;}
+
+
+
+
+
+
+
+$as_echo "#define EVAL 1" >>confdefs.h
+
+
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "x$host_alias" = x; then
+  ac_cv_host=$ac_cv_build
+else
+  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+
+
+DAPLIB_CURRENT=14
+DAPLIB_AGE=3
+DAPLIB_REVISION=0
+
+
+
+
+LIBDAP_VERSION="$DAPLIB_CURRENT:$DAPLIB_REVISION:$DAPLIB_AGE"
+
+
+CLIENTLIB_CURRENT=4
+CLIENTLIB_AGE=1
+CLIENTLIB_REVISION=0
+
+
+
+
+CLIENTLIB_VERSION="$CLIENTLIB_CURRENT:$CLIENTLIB_REVISION:$CLIENTLIB_AGE"
+
+
+SERVERLIB_CURRENT=9
+SERVERLIB_AGE=2
+SERVERLIB_REVISION=0
+
+
+
+
+SERVERLIB_VERSION="$SERVERLIB_CURRENT:$SERVERLIB_REVISION:$SERVERLIB_AGE"
+
+
+for ac_prog in gawk mawk nawk awk
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AWK+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AWK"; then
+  ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AWK="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$AWK" && break
+done
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5
+$as_echo_n "checking whether the C++ compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+  esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link_default") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile.  We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	then :; else
+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	fi
+	# We set ac_cv_exeext here because the later test for it is not
+	# safe: cross compilers may not add the suffix if given an `-o'
+	# argument, so we may need to know it at that point already.
+	# Even if this section looks crufty: it has the advantage of
+	# actually working.
+	break;;
+    * )
+	break;;
+  esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+  ac_file=''
+fi
+if test -z "$ac_file"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C++ compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5
+$as_echo_n "checking for C++ compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+ac_exeext=$ac_cv_exeext
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot run C++ compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compile") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then :
+  for ac_file in conftest.o conftest.obj conftest.*; do
+  test -f "$ac_file" || continue;
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+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
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+	@echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+  am__include=include
+  am__quote=
+  _am_result=GNU
+  ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+   echo '.include "confinc"' > confmf
+   case `$am_make -s -f confmf 2> /dev/null` in #(
+   *the\ am__doit\ target*)
+     am__include=.include
+     am__quote="\""
+     _am_result=BSD
+     ;;
+   esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+  enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+  am_depcomp="$ac_aux_dir/depcomp"
+  AMDEPBACKSLASH='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+  AMDEP_TRUE=
+  AMDEP_FALSE='#'
+else
+  AMDEP_TRUE='#'
+  AMDEP_FALSE=
+fi
+
+
+
+depcc="$CXX"  am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+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
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+          if test -n "$ac_tool_prefix"; then
+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  fi
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl.exe
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl.exe
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CC" && break
+done
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_c_werror_flag=$ac_c_werror_flag
+   ac_c_werror_flag=yes
+   ac_cv_prog_cc_g=no
+   CFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+else
+  CFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  ac_c_werror_flag=$ac_save_c_werror_flag
+	 CFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+  test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+  x)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+  xno)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+  *)
+    CC="$CC $ac_cv_prog_cc_c89"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+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
+
+depcc="$CC"   am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CC_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CC_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+  am__fastdepCC_TRUE=
+  am__fastdepCC_FALSE='#'
+else
+  am__fastdepCC_TRUE='#'
+  am__fastdepCC_FALSE=
+fi
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+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
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+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
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$GREP"; then
+  ac_path_GREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in grep ggrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+  # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'GREP' >> "conftest.nl"
+    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_GREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_GREP="$ac_path_GREP"
+      ac_path_GREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_GREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_GREP"; then
+    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_GREP=$GREP
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+   then ac_cv_path_EGREP="$GREP -E"
+   else
+     if test -z "$EGREP"; then
+  ac_path_EGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in egrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+  # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'EGREP' >> "conftest.nl"
+    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_EGREP="$ac_path_EGREP"
+      ac_path_EGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_EGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_EGREP"; then
+    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_EGREP=$EGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+  ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+  MINIX=yes
+else
+  MINIX=
+fi
+
+
+  if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+  fi
+
+        case "$host_os" in
+    hpux*)
+
+$as_echo "#define _XOPEN_SOURCE 500" >>confdefs.h
+
+      ;;
+  esac
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_safe_to_define___extensions__=yes
+else
+  ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+  $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+  $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+  $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+
+
+
+
+
+
+
+  # Code from module alloca-opt:
+  # Code from module arg-nonnull:
+  # Code from module btowc:
+  # Code from module c++defs:
+  # Code from module configmake:
+  # Code from module extensions:
+
+  # Code from module gettext-h:
+  # Code from module include_next:
+  # Code from module langinfo:
+  # Code from module localcharset:
+  # Code from module malloc-gnu:
+  # Code from module malloc-posix:
+  # Code from module mbrtowc:
+  # Code from module mbsinit:
+  # Code from module multiarch:
+  # Code from module nl_langinfo:
+  # Code from module regex:
+  # Code from module ssize_t:
+  # Code from module stdbool:
+  # Code from module stddef:
+  # Code from module stdint:
+  # Code from module stdlib:
+  # Code from module streq:
+  # Code from module unistd:
+  # Code from module verify:
+  # Code from module warn-on-use:
+  # Code from module wchar:
+  # Code from module wcrtomb:
+  # Code from module wctype:
+
+
+for ac_prog in flex lex
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LEX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LEX"; then
+  ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LEX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LEX=$ac_cv_prog_LEX
+if test -n "$LEX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LEX" >&5
+$as_echo "$LEX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$LEX" && break
+done
+test -n "$LEX" || LEX=":"
+
+if test "x$LEX" != "x:"; then
+  cat >conftest.l <<_ACEOF
+%%
+a { ECHO; }
+b { REJECT; }
+c { yymore (); }
+d { yyless (1); }
+e { yyless (input () != 0); }
+f { unput (yytext[0]); }
+. { BEGIN INITIAL; }
+%%
+#ifdef YYTEXT_POINTER
+extern char *yytext;
+#endif
+int
+main (void)
+{
+  return ! yylex () + ! yywrap ();
+}
+_ACEOF
+{ { ac_try="$LEX conftest.l"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$LEX conftest.l") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking lex output file root" >&5
+$as_echo_n "checking lex output file root... " >&6; }
+if test "${ac_cv_prog_lex_root+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+if test -f lex.yy.c; then
+  ac_cv_prog_lex_root=lex.yy
+elif test -f lexyy.c; then
+  ac_cv_prog_lex_root=lexyy
+else
+  as_fn_error "cannot find output from $LEX; giving up" "$LINENO" 5
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_root" >&5
+$as_echo "$ac_cv_prog_lex_root" >&6; }
+LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root
+
+if test -z "${LEXLIB+set}"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking lex library" >&5
+$as_echo_n "checking lex library... " >&6; }
+if test "${ac_cv_lib_lex+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    ac_save_LIBS=$LIBS
+    ac_cv_lib_lex='none needed'
+    for ac_lib in '' -lfl -ll; do
+      LIBS="$ac_lib $ac_save_LIBS"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_lex=$ac_lib
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+      test "$ac_cv_lib_lex" != 'none needed' && break
+    done
+    LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_lex" >&5
+$as_echo "$ac_cv_lib_lex" >&6; }
+  test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether yytext is a pointer" >&5
+$as_echo_n "checking whether yytext is a pointer... " >&6; }
+if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # POSIX says lex can declare yytext either as a pointer or an array; the
+# default is implementation-dependent.  Figure out which it is, since
+# not all implementations provide the %pointer and %array declarations.
+ac_cv_prog_lex_yytext_pointer=no
+ac_save_LIBS=$LIBS
+LIBS="$LEXLIB $ac_save_LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#define YYTEXT_POINTER 1
+`cat $LEX_OUTPUT_ROOT.c`
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_prog_lex_yytext_pointer=yes
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_save_LIBS
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_lex_yytext_pointer" >&5
+$as_echo "$ac_cv_prog_lex_yytext_pointer" >&6; }
+if test $ac_cv_prog_lex_yytext_pointer = yes; then
+
+$as_echo "#define YYTEXT_POINTER 1" >>confdefs.h
+
+fi
+rm -f conftest.l $LEX_OUTPUT_ROOT.c
+
+fi
+if test "$LEX" = :; then
+  LEX=${am_missing_run}flex
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+	@echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+  *@@@%%%=?*=@@@%%%*)
+    eval ac_cv_prog_make_${ac_make}_set=yes;;
+  *)
+    eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+  SET_MAKE=
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+case `pwd` in
+  *\ * | *\	*)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.6b'
+macro_revision='1.3017'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in sed gsed; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+  # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+  ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo '' >> "conftest.nl"
+    "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_SED_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_SED="$ac_path_SED"
+      ac_path_SED_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_SED_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_SED"; then
+    as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+  fi
+else
+  ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+  rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+   then ac_cv_path_FGREP="$GREP -F"
+   else
+     if test -z "$FGREP"; then
+  ac_path_FGREP_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_prog in fgrep; do
+    for ac_exec_ext in '' $ac_executable_extensions; do
+      ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+  # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+  ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;;
+*)
+  ac_count=0
+  $as_echo_n 0123456789 >"conftest.in"
+  while :
+  do
+    cat "conftest.in" "conftest.in" >"conftest.tmp"
+    mv "conftest.tmp" "conftest.in"
+    cp "conftest.in" "conftest.nl"
+    $as_echo 'FGREP' >> "conftest.nl"
+    "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break
+    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+    as_fn_arith $ac_count + 1 && ac_count=$as_val
+    if test $ac_count -gt ${ac_path_FGREP_max-0}; then
+      # Best one so far, save it but keep looking for a better one
+      ac_cv_path_FGREP="$ac_path_FGREP"
+      ac_path_FGREP_max=$ac_count
+    fi
+    # 10*(2^10) chars as input seems more than enough
+    test $ac_count -gt 10 && break
+  done
+  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+      $ac_path_FGREP_found && break 3
+    done
+  done
+  done
+IFS=$as_save_IFS
+  if test -z "$ac_cv_path_FGREP"; then
+    as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+  fi
+else
+  ac_cv_path_FGREP=$FGREP
+fi
+
+   fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NM"; then
+  # Let the user override the test.
+  lt_cv_path_NM="$NM"
+else
+  lt_nm_to_check="${ac_tool_prefix}nm"
+  if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+    lt_nm_to_check="$lt_nm_to_check nm"
+  fi
+  for lt_tmp_nm in $lt_nm_to_check; do
+    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+    for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+      IFS="$lt_save_ifs"
+      test -z "$ac_dir" && ac_dir=.
+      tmp_nm="$ac_dir/$lt_tmp_nm"
+      if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+	# Check to see if the nm accepts a BSD-compat flag.
+	# Adding the `sed 1q' prevents false positives on HP-UX, which says:
+	#   nm: unknown option "B" ignored
+	# Tru64's nm complains that /dev/null is an invalid object file
+	case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+	*/dev/null* | *'Invalid file or object type'*)
+	  lt_cv_path_NM="$tmp_nm -B"
+	  break
+	  ;;
+	*)
+	  case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+	  */dev/null*)
+	    lt_cv_path_NM="$tmp_nm -p"
+	    break
+	    ;;
+	  *)
+	    lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+	    continue # so that we can try to find one that supports BSD flags
+	    ;;
+	  esac
+	  ;;
+	esac
+      fi
+    done
+    IFS="$lt_save_ifs"
+  done
+  : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+  NM="$lt_cv_path_NM"
+else
+  # Didn't find any BSD compatible name lister, look for dumpbin.
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DUMPBIN"; then
+  ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$DUMPBIN" && break
+  done
+fi
+if test -z "$DUMPBIN"; then
+  ac_ct_DUMPBIN=$DUMPBIN
+  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DUMPBIN"; then
+  ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_DUMPBIN" && break
+done
+
+  if test "x$ac_ct_DUMPBIN" = x; then
+    DUMPBIN=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DUMPBIN=$ac_ct_DUMPBIN
+  fi
+fi
+
+
+  if test "$DUMPBIN" != ":"; then
+    NM="$DUMPBIN"
+  fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_nm_interface="BSD nm"
+  echo "int some_variable = 0;" > conftest.$ac_ext
+  (eval echo "\"\$as_me:6484: $ac_compile\"" >&5)
+  (eval "$ac_compile" 2>conftest.err)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:6487: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+  cat conftest.err >&5
+  (eval echo "\"\$as_me:6490: output\"" >&5)
+  cat conftest.out >&5
+  if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+    lt_cv_nm_interface="MS dumpbin"
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+    i=0
+  teststring="ABCD"
+
+  case $build_os in
+  msdosdjgpp*)
+    # On DJGPP, this test can blow up pretty badly due to problems in libc
+    # (any single argument exceeding 2000 bytes causes a buffer overrun
+    # during glob expansion).  Even if it were fixed, the result of this
+    # check would be larger than it should be.
+    lt_cv_sys_max_cmd_len=12288;    # 12K is about right
+    ;;
+
+  gnu*)
+    # Under GNU Hurd, this test is not required because there is
+    # no limit to the length of command line arguments.
+    # Libtool will interpret -1 as no limit whatsoever
+    lt_cv_sys_max_cmd_len=-1;
+    ;;
+
+  cygwin* | mingw* | cegcc*)
+    # On Win9x/ME, this test blows up -- it succeeds, but takes
+    # about 5 minutes as the teststring grows exponentially.
+    # Worse, since 9x/ME are not pre-emptively multitasking,
+    # you end up with a "frozen" computer, even though with patience
+    # the test eventually succeeds (with a max line length of 256k).
+    # Instead, let's just punt: use the minimum linelength reported by
+    # all of the supported platforms: 8192 (on NT/2K/XP).
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  amigaos*)
+    # On AmigaOS with pdksh, this test takes hours, literally.
+    # So we just punt and use a minimum line length of 8192.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
+  netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+    # This has been around since 386BSD, at least.  Likely further.
+    if test -x /sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+    elif test -x /usr/sbin/sysctl; then
+      lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+    else
+      lt_cv_sys_max_cmd_len=65536	# usable default for all BSDs
+    fi
+    # And add a safety zone
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+    lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    ;;
+
+  interix*)
+    # We know the value 262144 and hardcode it with a safety zone (like BSD)
+    lt_cv_sys_max_cmd_len=196608
+    ;;
+
+  osf*)
+    # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+    # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+    # nice to cause kernel panics so lets avoid the loop below.
+    # First set a reasonable default.
+    lt_cv_sys_max_cmd_len=16384
+    #
+    if test -x /sbin/sysconfig; then
+      case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+        *1*) lt_cv_sys_max_cmd_len=-1 ;;
+      esac
+    fi
+    ;;
+  sco3.2v5*)
+    lt_cv_sys_max_cmd_len=102400
+    ;;
+  sysv5* | sco5v6* | sysv4.2uw2*)
+    kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+    if test -n "$kargmax"; then
+      lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[	 ]//'`
+    else
+      lt_cv_sys_max_cmd_len=32768
+    fi
+    ;;
+  *)
+    lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+    if test -n "$lt_cv_sys_max_cmd_len"; then
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+    else
+      # Make teststring a little bigger before we do anything with it.
+      # a 1K string should be a reasonable start.
+      for i in 1 2 3 4 5 6 7 8 ; do
+        teststring=$teststring$teststring
+      done
+      SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+      # If test is not a shell built-in, we'll probably end up computing a
+      # maximum length that is only half of the actual maximum length, but
+      # we can't tell.
+      while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
+	         = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+	      test $i != 17 # 1/2 MB should be enough
+      do
+        i=`expr $i + 1`
+        teststring=$teststring$teststring
+      done
+      # Only check the string length outside the loop.
+      lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+      teststring=
+      # Add a significant safety factor because C++ compilers can tack on
+      # massive amounts of additional arguments before passing them to the
+      # linker.  It appears as though 1/2 is a usable value.
+      lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+    fi
+    ;;
+  esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,, \
+    && eval 'test $(( 1 + 1 )) -eq 2 \
+    && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+  && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+    >/dev/null 2>&1 \
+  && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  lt_unset=unset
+else
+  lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+    # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+  lt_SP2NL='tr \040 \012'
+  lt_NL2SP='tr \015\012 \040\040'
+  ;;
+ *) # EBCDIC based system
+  lt_SP2NL='tr \100 \n'
+  lt_NL2SP='tr \r\n \100\100'
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+  darwin*)
+    if test "$GCC" = yes; then
+      reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+    else
+      reload_cmds='$LD$reload_flag -o $output$reload_objs'
+    fi
+    ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OBJDUMP"; then
+  ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+  ac_ct_OBJDUMP=$OBJDUMP
+  # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OBJDUMP"; then
+  ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OBJDUMP="objdump"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OBJDUMP" = x; then
+    OBJDUMP="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OBJDUMP=$ac_ct_OBJDUMP
+  fi
+else
+  OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+beos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+bsdi[45]*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+  lt_cv_file_magic_cmd='/usr/bin/file -L'
+  lt_cv_file_magic_test_file=/shlib/libc.so
+  ;;
+
+cygwin*)
+  # func_win32_libid is a shell function defined in ltmain.sh
+  lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+  lt_cv_file_magic_cmd='func_win32_libid'
+  ;;
+
+mingw* | pw32*)
+  # Base MSYS/MinGW do not provide the 'file' command needed by
+  # func_win32_libid shell function, so use a weaker test based on 'objdump',
+  # unless we find 'file', for example because we are cross-compiling.
+  if ( file / ) >/dev/null 2>&1; then
+    lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+    lt_cv_file_magic_cmd='func_win32_libid'
+  else
+    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    lt_cv_file_magic_cmd='$OBJDUMP -f'
+  fi
+  ;;
+
+cegcc)
+  # use the weaker test based on 'objdump'. See mingw*.
+  lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+  lt_cv_file_magic_cmd='$OBJDUMP -f'
+  ;;
+
+darwin* | rhapsody*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+freebsd* | dragonfly*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    case $host_cpu in
+    i*86 )
+      # Not sure whether the presence of OpenBSD here was a mistake.
+      # Let's accept both of them until this is cleared up.
+      lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+      lt_cv_file_magic_cmd=/usr/bin/file
+      lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+      ;;
+    esac
+  else
+    lt_cv_deplibs_check_method=pass_all
+  fi
+  ;;
+
+gnu*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+hpux10.20* | hpux11*)
+  lt_cv_file_magic_cmd=/usr/bin/file
+  case $host_cpu in
+  ia64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+    lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+    ;;
+  hppa*64*)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+    ;;
+  *)
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_file_magic_test_file=/usr/lib/libc.sl
+    ;;
+  esac
+  ;;
+
+interix[3-9]*)
+  # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+  lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $LD in
+  *-32|*"-32 ") libmagic=32-bit;;
+  *-n32|*"-n32 ") libmagic=N32;;
+  *-64|*"-64 ") libmagic=64-bit;;
+  *) libmagic=never-match;;
+  esac
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+netbsd*)
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+  fi
+  ;;
+
+newos6*)
+  lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+  lt_cv_file_magic_cmd=/usr/bin/file
+  lt_cv_file_magic_test_file=/usr/lib/libnls.so
+  ;;
+
+*nto* | *qnx*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+openbsd*)
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+  else
+    lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+  fi
+  ;;
+
+osf3* | osf4* | osf5*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+rdos*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+solaris*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
+sysv4 | sysv4.3*)
+  case $host_vendor in
+  motorola)
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+    lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+    ;;
+  ncr)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  sequent)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+    ;;
+  sni)
+    lt_cv_file_magic_cmd='/bin/file'
+    lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+    lt_cv_file_magic_test_file=/lib/libc.so
+    ;;
+  siemens)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  pc)
+    lt_cv_deplibs_check_method=pass_all
+    ;;
+  esac
+  ;;
+
+tpf*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_AR="ar"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    AR=$ac_ct_AR
+  fi
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_STRIP="strip"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_RANLIB" = x; then
+    RANLIB=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    RANLIB=$ac_ct_RANLIB
+  fi
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+  case $host_os in
+  openbsd*)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    ;;
+  *)
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    ;;
+  esac
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix.  What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+  symcode='[BCDT]'
+  ;;
+cygwin* | mingw* | pw32* | cegcc*)
+  symcode='[ABCDGISTW]'
+  ;;
+hpux*)
+  if test "$host_cpu" = ia64; then
+    symcode='[ABCDEGRST]'
+  fi
+  ;;
+irix* | nonstopux*)
+  symcode='[BCDEGRST]'
+  ;;
+osf*)
+  symcode='[BCDEGQRST]'
+  ;;
+solaris*)
+  symcode='[BDRT]'
+  ;;
+sco3.2v5*)
+  symcode='[DT]'
+  ;;
+sysv4.2uw2*)
+  symcode='[DT]'
+  ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+  symcode='[ABDT]'
+  ;;
+sysv4)
+  symcode='[DFNSTU]'
+  ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+  symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+  opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+  ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+  # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+  symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+  # Write the raw and C identifiers.
+  if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+    # Fake it for dumpbin and say T for any non-static function
+    # and D for any global variable.
+    # Also find C++ and __fastcall symbols from MSVC++,
+    # which start with @ or ?.
+    lt_cv_sys_global_symbol_pipe="$AWK '"\
+"     {last_section=section; section=\$ 3};"\
+"     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+"     \$ 0!~/External *\|/{next};"\
+"     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+"     {if(hide[section]) next};"\
+"     {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+"     {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+"     s[1]~/^[@?]/{print s[1], s[1]; next};"\
+"     s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+"     ' prfx=^$ac_symprfx"
+  else
+    lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[	 ]\($symcode$symcode*\)[	 ][	 ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+  fi
+
+  # Check to see that the pipe works correctly.
+  pipe_works=no
+
+  rm -f conftest*
+  cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$nlist"; then
+      # Try sorting and uniquifying the output.
+      if sort "$nlist" | uniq > "$nlist"T; then
+	mv -f "$nlist"T "$nlist"
+      else
+	rm -f "$nlist"T
+      fi
+
+      # Make sure that we snagged all the symbols we need.
+      if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+	if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+	  cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+	  # Now generate the symbol file.
+	  eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+	  cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols.  */
+const struct {
+  const char *name;
+  void       *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+  { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+	  $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/  {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+	  cat <<\_LT_EOF >> conftest.$ac_ext
+  {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+  return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+	  # Now try linking the two files.
+	  mv conftest.$ac_objext conftstm.$ac_objext
+	  lt_save_LIBS="$LIBS"
+	  lt_save_CFLAGS="$CFLAGS"
+	  LIBS="conftstm.$ac_objext"
+	  CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+	  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+	    pipe_works=yes
+	  fi
+	  LIBS="$lt_save_LIBS"
+	  CFLAGS="$lt_save_CFLAGS"
+	else
+	  echo "cannot find nm_test_func in $nlist" >&5
+	fi
+      else
+	echo "cannot find nm_test_var in $nlist" >&5
+      fi
+    else
+      echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "$progname: failed program was:" >&5
+    cat conftest.$ac_ext >&5
+  fi
+  rm -rf conftest* conftst*
+
+  # Do not use the global_symbol_pipe unless it works.
+  if test "$pipe_works" = yes; then
+    break
+  else
+    lt_cv_sys_global_symbol_pipe=
+  fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+  lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+  enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.$ac_objext` in
+      *ELF-32*)
+	HPUX_IA64_MODE="32"
+	;;
+      *ELF-64*)
+	HPUX_IA64_MODE="64"
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+*-*-irix6*)
+  # Find out which ABI we are using.
+  echo '#line 7684 "configure"' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    if test "$lt_cv_prog_gnu_ld" = yes; then
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -melf32bsmip"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -melf32bmipn32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -melf64bmip"
+	;;
+      esac
+    else
+      case `/usr/bin/file conftest.$ac_objext` in
+	*32-bit*)
+	  LD="${LD-ld} -32"
+	  ;;
+	*N32*)
+	  LD="${LD-ld} -n32"
+	  ;;
+	*64-bit*)
+	  LD="${LD-ld} -64"
+	  ;;
+      esac
+    fi
+  fi
+  rm -rf conftest*
+  ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+      *32-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_i386_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_i386"
+	    ;;
+	  ppc64-*linux*|powerpc64-*linux*)
+	    LD="${LD-ld} -m elf32ppclinux"
+	    ;;
+	  s390x-*linux*)
+	    LD="${LD-ld} -m elf_s390"
+	    ;;
+	  sparc64-*linux*)
+	    LD="${LD-ld} -m elf32_sparc"
+	    ;;
+	esac
+	;;
+      *64-bit*)
+	case $host in
+	  x86_64-*kfreebsd*-gnu)
+	    LD="${LD-ld} -m elf_x86_64_fbsd"
+	    ;;
+	  x86_64-*linux*)
+	    LD="${LD-ld} -m elf_x86_64"
+	    ;;
+	  ppc*-*linux*|powerpc*-*linux*)
+	    LD="${LD-ld} -m elf64ppc"
+	    ;;
+	  s390*-*linux*|s390*-*tpf*)
+	    LD="${LD-ld} -m elf64_s390"
+	    ;;
+	  sparc*-*linux*)
+	    LD="${LD-ld} -m elf64_sparc"
+	    ;;
+	esac
+	;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+
+*-*-sco3.2v5*)
+  # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+  SAVE_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -belf"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  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
+
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_cc_needs_belf=yes
+else
+  lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+     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
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+  if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+    # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+    CFLAGS="$SAVE_CFLAGS"
+  fi
+  ;;
+sparc*-*solaris*)
+  # Find out which ABI we are using.
+  echo 'int i;' > conftest.$ac_ext
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    case `/usr/bin/file conftest.o` in
+    *64-bit*)
+      case $lt_cv_prog_gnu_ld in
+      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      *)
+	if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+	  LD="${LD-ld} -64"
+	fi
+	;;
+      esac
+      ;;
+    esac
+  fi
+  rm -rf conftest*
+  ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+  case $host_os in
+    rhapsody* | darwin*)
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$DSYMUTIL"; then
+  ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+  ac_ct_DSYMUTIL=$DSYMUTIL
+  # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_DSYMUTIL"; then
+  ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_DSYMUTIL" = x; then
+    DSYMUTIL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    DSYMUTIL=$ac_ct_DSYMUTIL
+  fi
+else
+  DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$NMEDIT"; then
+  ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+  ac_ct_NMEDIT=$NMEDIT
+  # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_NMEDIT"; then
+  ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_NMEDIT="nmedit"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_NMEDIT" = x; then
+    NMEDIT=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    NMEDIT=$ac_ct_NMEDIT
+  fi
+else
+  NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$LIPO"; then
+  ac_cv_prog_LIPO="$LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+  ac_ct_LIPO=$LIPO
+  # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_LIPO"; then
+  ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_LIPO="lipo"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_LIPO" = x; then
+    LIPO=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    LIPO=$ac_ct_LIPO
+  fi
+else
+  LIPO="$ac_cv_prog_LIPO"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL"; then
+  ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+  ac_ct_OTOOL=$OTOOL
+  # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL"; then
+  ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL="otool"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL" = x; then
+    OTOOL=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL=$ac_ct_OTOOL
+  fi
+else
+  OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+    if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$OTOOL64"; then
+  ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+  ac_ct_OTOOL64=$OTOOL64
+  # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_OTOOL64"; then
+  ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_OTOOL64="otool64"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_OTOOL64" = x; then
+    OTOOL64=":"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    OTOOL64=$ac_ct_OTOOL64
+  fi
+else
+  OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_apple_cc_single_mod=no
+      if test -z "${LT_MULTI_MODULE}"; then
+	# By default we will add the -single_module flag. You can override
+	# by either setting the environment variable LT_MULTI_MODULE
+	# non-empty at configure time, or by adding -multi_module to the
+	# link flags.
+	rm -rf libconftest.dylib*
+	echo "int foo(void){return 1;}" > conftest.c
+	echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+	$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+	  -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+        _lt_result=$?
+	if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+	  lt_cv_apple_cc_single_mod=yes
+	else
+	  cat conftest.err >&5
+	fi
+	rm -rf libconftest.dylib*
+	rm -f conftest.*
+      fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_exported_symbols_list=no
+      save_LDFLAGS=$LDFLAGS
+      echo "_main" > conftest.sym
+      LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  lt_cv_ld_exported_symbols_list=yes
+else
+  lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+	LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+    case $host_os in
+    rhapsody* | darwin1.[012])
+      _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+    darwin1.*)
+      _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+    darwin*) # darwin 5.x on
+      # if running on 10.5 or later, the deployment target defaults
+      # to the OS version, if on x86, and 10.4, the deployment
+      # target defaults to 10.4. Don't you love it?
+      case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+	10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+	10.[012]*)
+	  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+	10.*)
+	  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+      esac
+    ;;
+  esac
+    if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+      _lt_dar_single_mod='$single_module'
+    fi
+    if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+      _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+    else
+      _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+    fi
+    if test "$DSYMUTIL" != ":"; then
+      _lt_dsymutil='~$DSYMUTIL $lib || :'
+    else
+      _lt_dsymutil=
+    fi
+    ;;
+  esac
+
+for ac_header in dlfcn.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+  if test -n "$CCC"; then
+    CXX=$CCC
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$CXX"; then
+  ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+    test -n "$CXX" && break
+  done
+fi
+if test -z "$CXX"; then
+  ac_ct_CXX=$CXX
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_CXX"; then
+  ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_ac_ct_CXX="$ac_prog"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  test -n "$ac_ct_CXX" && break
+done
+
+  if test "x$ac_ct_CXX" = x; then
+    CXX="g++"
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CXX=$ac_ct_CXX
+  fi
+fi
+
+  fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+  { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    sed '10a\
+... rest of stderr output deleted ...
+         10q' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+  fi
+  rm -f conftest.er1 conftest.err
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_compiler_gnu+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_compiler_gnu=yes
+else
+  ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+  GXX=yes
+else
+  GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+   ac_cxx_werror_flag=yes
+   ac_cv_prog_cxx_g=no
+   CXXFLAGS="-g"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+else
+  CXXFLAGS=""
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+  ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+	 CXXFLAGS="-g"
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+  ac_cv_prog_cxx_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+  CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+  if test "$GXX" = yes; then
+    CXXFLAGS="-g -O2"
+  else
+    CXXFLAGS="-g"
+  fi
+else
+  if test "$GXX" = yes; then
+    CXXFLAGS="-O2"
+  else
+    CXXFLAGS=
+  fi
+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
+
+depcc="$CXX"  am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+  # We make a subdir and do the tests there.  Otherwise we can end up
+  # making bogus files that we don't know about and never remove.  For
+  # instance it was reported that on HP-UX the gcc test will end up
+  # making a dummy file named `D' -- because `-MD' means `put the output
+  # in D'.
+  mkdir conftest.dir
+  # Copy depcomp to subdir because otherwise we won't find it if we're
+  # using a relative directory.
+  cp "$am_depcomp" conftest.dir
+  cd conftest.dir
+  # We will build objects and dependencies in a subdirectory because
+  # it helps to detect inapplicable dependency modes.  For instance
+  # both Tru64's cc and ICC support -MD to output dependencies as a
+  # side effect of compilation, but ICC will put the dependencies in
+  # the current directory while Tru64 will put them in the object
+  # directory.
+  mkdir sub
+
+  am_cv_CXX_dependencies_compiler_type=none
+  if test "$am_compiler_list" = ""; then
+     am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+  fi
+  am__universal=false
+  case " $depcc " in #(
+     *\ -arch\ *\ -arch\ *) am__universal=true ;;
+     esac
+
+  for depmode in $am_compiler_list; do
+    # Setup a source with many dependencies, because some compilers
+    # like to wrap large dependency lists on column 80 (with \), and
+    # we should not choose a depcomp mode which is confused by this.
+    #
+    # We need to recreate these files for each test, as the compiler may
+    # overwrite some of them when testing with obscure command lines.
+    # This happens at least with the AIX C compiler.
+    : > sub/conftest.c
+    for i in 1 2 3 4 5 6; do
+      echo '#include "conftst'$i'.h"' >> sub/conftest.c
+      # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+      # Solaris 8's {/usr,}/bin/sh.
+      touch sub/conftst$i.h
+    done
+    echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+    # We check with `-c' and `-o' for the sake of the "dashmstdout"
+    # mode.  It turns out that the SunPro C++ compiler does not properly
+    # handle `-M -o', and we need to detect this.  Also, some Intel
+    # versions had trouble with output in subdirs
+    am__obj=sub/conftest.${OBJEXT-o}
+    am__minus_obj="-o $am__obj"
+    case $depmode in
+    gcc)
+      # This depmode causes a compiler race in universal mode.
+      test "$am__universal" = false || continue
+      ;;
+    nosideeffect)
+      # after this tag, mechanisms are not by side-effect, so they'll
+      # only be used when explicitly requested
+      if test "x$enable_dependency_tracking" = xyes; then
+	continue
+      else
+	break
+      fi
+      ;;
+    msvisualcpp | msvcmsys)
+      # This compiler won't grok `-c -o', but also, the minuso test has
+      # not run yet.  These depmodes are late enough in the game, and
+      # so weak that their functioning should not be impacted.
+      am__obj=conftest.${OBJEXT-o}
+      am__minus_obj=
+      ;;
+    none) break ;;
+    esac
+    if depmode=$depmode \
+       source=sub/conftest.c object=$am__obj \
+       depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+       $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+         >/dev/null 2>conftest.err &&
+       grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+       grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+       ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+      # icc doesn't choke on unknown options, it will just issue warnings
+      # or remarks (even with -Werror).  So we grep stderr for any message
+      # that says an option was ignored or not supported.
+      # When given -MP, icc 7.0 and 7.1 complain thusly:
+      #   icc: Command line warning: ignoring option '-M'; no argument required
+      # The diagnosis changed in icc 8.0:
+      #   icc: Command line remark: option '-MP' not supported
+      if (grep 'ignoring option' conftest.err ||
+          grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+        am_cv_CXX_dependencies_compiler_type=$depmode
+        break
+      fi
+    fi
+  done
+
+  cd ..
+  rm -rf conftest.dir
+else
+  am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+  test "x$enable_dependency_tracking" != xno \
+  && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+  am__fastdepCXX_TRUE=
+  am__fastdepCXX_FALSE='#'
+else
+  am__fastdepCXX_TRUE='#'
+  am__fastdepCXX_FALSE=
+fi
+
+
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5
+$as_echo_n "checking how to run the C++ preprocessor... " >&6; }
+if test -z "$CXXCPP"; then
+  if test "${ac_cv_prog_CXXCPP+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+      # Double quotes because CXXCPP needs to be expanded
+    for CXXCPP in "$CXX -E" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+  break
+fi
+
+    done
+    ac_cv_prog_CXXCPP=$CXXCPP
+
+fi
+  CXXCPP=$ac_cv_prog_CXXCPP
+else
+  ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+
+else
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_cxx_try_cpp "$LINENO"; then :
+  # Broken: success on invalid input.
+continue
+else
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+_lt_caught_CXX_error=yes; }
+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
+
+else
+  _lt_caught_CXX_error=yes
+fi
+
+
+
+
+
+# Set options
+
+
+
+        enable_dlopen=no
+
+
+  enable_win32_dll=no
+
+
+            # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+  enableval=$enable_shared; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_shared=yes ;;
+    no) enable_shared=no ;;
+    *)
+      enable_shared=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_shared=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+  # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+  enableval=$enable_static; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_static=yes ;;
+    no) enable_static=no ;;
+    *)
+     enable_static=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_static=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+  withval=$with_pic; pic_mode="$withval"
+else
+  pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+  # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+  enableval=$enable_fast_install; p=${PACKAGE-default}
+    case $enableval in
+    yes) enable_fast_install=yes ;;
+    no) enable_fast_install=no ;;
+    *)
+      enable_fast_install=no
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for pkg in $enableval; do
+	IFS="$lt_save_ifs"
+	if test "X$pkg" = "X$p"; then
+	  enable_fast_install=yes
+	fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
+else
+  enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+  lt_cv_objdir=.libs
+else
+  # MS-DOS does not allow filenames that begin with a dot.
+  lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+case $host_os in
+aix3*)
+  # AIX sometimes has problems with the GCC collect2 program.  For some
+  # reason, if we set the COLLECT_NAMES environment variable, the problems
+  # vanish in a puff of smoke.
+  if test "X${COLLECT_NAMES+set}" != Xset; then
+    COLLECT_NAMES=
+    export COLLECT_NAMES
+  fi
+  ;;
+esac
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+  if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/${ac_tool_prefix}file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+  if test -n "$ac_tool_prefix"; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $MAGIC_CMD in
+[\\/*] |  ?:[\\/]*)
+  lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+  ;;
+*)
+  lt_save_MAGIC_CMD="$MAGIC_CMD"
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+  for ac_dir in $ac_dummy; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/file; then
+      lt_cv_path_MAGIC_CMD="$ac_dir/file"
+      if test -n "$file_magic_test_file"; then
+	case $deplibs_check_method in
+	"file_magic "*)
+	  file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+	  MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+	  if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+	    $EGREP "$file_magic_regex" > /dev/null; then
+	    :
+	  else
+	    cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such.  This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem.  Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool at gnu.org
+
+_LT_EOF
+	  fi ;;
+	esac
+      fi
+      break
+    fi
+  done
+  IFS="$lt_save_ifs"
+  MAGIC_CMD="$lt_save_MAGIC_CMD"
+  ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  else
+    MAGIC_CMD=:
+  fi
+fi
+
+  fi
+  ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+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
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_rtti_exceptions=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="-fno-rtti -fno-exceptions"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:9473: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:9477: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_rtti_exceptions=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+    lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+    :
+fi
+
+fi
+
+
+
+
+
+
+  lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  if test "$GCC" = yes; then
+    lt_prog_compiler_wl='-Wl,'
+    lt_prog_compiler_static='-static'
+
+    case $host_os in
+      aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic='-fno-common'
+      ;;
+
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='-fPIC'
+	;;
+      esac
+      ;;
+
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+
+    msdosdjgpp*)
+      # Just because we use GCC doesn't mean we suddenly get shared libraries
+      # on systems that don't support them.
+      lt_prog_compiler_can_build_shared=no
+      enable_shared=no
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic=-Kconform_pic
+      fi
+      ;;
+
+    *)
+      lt_prog_compiler_pic='-fPIC'
+      ;;
+    esac
+  else
+    # PORTME Check for flag to pass linker flags through the system compiler.
+    case $host_os in
+    aix*)
+      lt_prog_compiler_wl='-Wl,'
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static='-Bstatic'
+      else
+	lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+      fi
+      ;;
+
+    mingw* | cygwin* | pw32* | os2* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      lt_prog_compiler_pic='-DDLL_EXPORT'
+      ;;
+
+    hpux9* | hpux10* | hpux11*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+      # not for PA HP-UX.
+      case $host_cpu in
+      hppa*64*|ia64*)
+	# +Z the default
+	;;
+      *)
+	lt_prog_compiler_pic='+Z'
+	;;
+      esac
+      # Is there a better lt_prog_compiler_static that works with the bundled CC?
+      lt_prog_compiler_static='${wl}-a ${wl}archive'
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      lt_prog_compiler_wl='-Wl,'
+      # PIC (with -KPIC) is the default.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    linux* | k*bsd*-gnu)
+      case $cc_basename in
+      # old Intel for x86_64 which still supported -KPIC.
+      ecc*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-KPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # icc used to be incompatible with GCC.
+      # ICC 10 doesn't accept -KPIC any more.
+      icc* | ifort*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fPIC'
+	lt_prog_compiler_static='-static'
+        ;;
+      # Lahey Fortran 8.1.
+      lf95*)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='--shared'
+	lt_prog_compiler_static='--static'
+	;;
+      pgcc* | pgf77* | pgf90* | pgf95*)
+        # Portland Group compilers (*not* the Pentium gcc compiler,
+	# which looks to be a dead project)
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-fpic'
+	lt_prog_compiler_static='-Bstatic'
+        ;;
+      ccc*)
+        lt_prog_compiler_wl='-Wl,'
+        # All Alpha code is PIC.
+        lt_prog_compiler_static='-non_shared'
+        ;;
+      xl*)
+	# IBM XL C 8.0/Fortran 10.1 on PPC
+	lt_prog_compiler_wl='-Wl,'
+	lt_prog_compiler_pic='-qpic'
+	lt_prog_compiler_static='-qstaticlink'
+	;;
+      *)
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)
+	  # Sun C 5.9
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl='-Wl,'
+	  ;;
+	*Sun\ F*)
+	  # Sun Fortran 8.3 passes all unrecognized flags to the linker
+	  lt_prog_compiler_pic='-KPIC'
+	  lt_prog_compiler_static='-Bstatic'
+	  lt_prog_compiler_wl=''
+	  ;;
+	esac
+	;;
+      esac
+      ;;
+
+    newsos6)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *nto* | *qnx*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic='-fPIC -shared'
+      ;;
+
+    osf3* | osf4* | osf5*)
+      lt_prog_compiler_wl='-Wl,'
+      # All OSF/1 code is PIC.
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    rdos*)
+      lt_prog_compiler_static='-non_shared'
+      ;;
+
+    solaris*)
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      case $cc_basename in
+      f77* | f90* | f95*)
+	lt_prog_compiler_wl='-Qoption ld ';;
+      *)
+	lt_prog_compiler_wl='-Wl,';;
+      esac
+      ;;
+
+    sunos4*)
+      lt_prog_compiler_wl='-Qoption ld '
+      lt_prog_compiler_pic='-PIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4 | sysv4.2uw2* | sysv4.3*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec ;then
+	lt_prog_compiler_pic='-Kconform_pic'
+	lt_prog_compiler_static='-Bstatic'
+      fi
+      ;;
+
+    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_pic='-KPIC'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    unicos*)
+      lt_prog_compiler_wl='-Wl,'
+      lt_prog_compiler_can_build_shared=no
+      ;;
+
+    uts4*)
+      lt_prog_compiler_pic='-pic'
+      lt_prog_compiler_static='-Bstatic'
+      ;;
+
+    *)
+      lt_prog_compiler_can_build_shared=no
+      ;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic=
+    ;;
+  *)
+    lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:9812: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:9816: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+    case $lt_prog_compiler_pic in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+     esac
+else
+    lt_prog_compiler_pic=
+     lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+    :
+else
+    lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:9917: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:9921: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:9972: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:9976: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  runpath_var=
+  allow_undefined_flag=
+  always_export_symbols=no
+  archive_cmds=
+  archive_expsym_cmds=
+  compiler_needs_object=no
+  enable_shared_with_static_runtimes=no
+  export_dynamic_flag_spec=
+  export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  hardcode_automatic=no
+  hardcode_direct=no
+  hardcode_direct_absolute=no
+  hardcode_libdir_flag_spec=
+  hardcode_libdir_flag_spec_ld=
+  hardcode_libdir_separator=
+  hardcode_minus_L=no
+  hardcode_shlibpath_var=unsupported
+  inherit_rpath=no
+  link_all_deplibs=unknown
+  module_cmds=
+  module_expsym_cmds=
+  old_archive_from_new_cmds=
+  old_archive_from_expsyms_cmds=
+  thread_safe_flag_spec=
+  whole_archive_flag_spec=
+  # include_expsyms should be a list of space-separated symbols to be *always*
+  # included in the symbol list
+  include_expsyms=
+  # exclude_expsyms can be an extended regexp of symbols to exclude
+  # it will be wrapped by ` (' and `)$', so one must not match beginning or
+  # end of line.  Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+  # as well as any symbol that contains `d'.
+  exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+  # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+  # platforms (ab)use it in PIC code, but their linkers get confused if
+  # the symbol is explicitly referenced.  Since portable code cannot
+  # rely on this symbol name, it's probably fine to never include it in
+  # preloaded symbol tables.
+  # Exclude shared library initialization/finalization symbols.
+  extract_expsyms_cmds=
+
+  case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    # FIXME: the MSVC++ port hasn't been tested in a loooong time
+    # When not using gcc, we currently assume that we are using
+    # Microsoft Visual C++.
+    if test "$GCC" != yes; then
+      with_gnu_ld=no
+    fi
+    ;;
+  interix*)
+    # we just hope/assume this is gcc and not c89 (= MSVC++)
+    with_gnu_ld=yes
+    ;;
+  openbsd*)
+    with_gnu_ld=no
+    ;;
+  esac
+
+  ld_shlibs=yes
+  if test "$with_gnu_ld" = yes; then
+    # If archive_cmds runs LD, not CC, wlarc should be empty
+    wlarc='${wl}'
+
+    # Set some defaults for GNU ld with shared library support. These
+    # are reset later if shared libraries are not supported. Putting them
+    # here allows them to be overridden if necessary.
+    runpath_var=LD_RUN_PATH
+    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+    export_dynamic_flag_spec='${wl}--export-dynamic'
+    # ancient GNU ld didn't support --whole-archive et. al.
+    if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+      whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+    else
+      whole_archive_flag_spec=
+    fi
+    supports_anon_versioning=no
+    case `$LD -v 2>&1` in
+      *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+      *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+      *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+      *\ 2.11.*) ;; # other 2.11 versions
+      *) supports_anon_versioning=yes ;;
+    esac
+
+    # See if GNU ld supports shared libraries.
+    case $host_os in
+    aix[3-9]*)
+      # On AIX/PPC, the GNU linker is very broken
+      if test "$host_cpu" != ia64; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support.  If you
+*** really care for shared libraries, you may want to modify your PATH
+*** so that a non-GNU linker is found, and then restart.
+
+_LT_EOF
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    beos*)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	allow_undefined_flag=unsupported
+	# Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	# support --undefined.  This deserves some investigation.  FIXME
+	archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+      # as there is no search path for DLLs.
+      hardcode_libdir_flag_spec='-L$libdir'
+      allow_undefined_flag=unsupported
+      always_export_symbols=no
+      enable_shared_with_static_runtimes=yes
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+      if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+        archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+	# If the export-symbols file already is a .def file (1st line
+	# is EXPORTS), use it as is; otherwise, prepend...
+	archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	  cp $export_symbols $output_objdir/$soname.def;
+	else
+	  echo EXPORTS > $output_objdir/$soname.def;
+	  cat $export_symbols >> $output_objdir/$soname.def;
+	fi~
+	$CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    interix[3-9]*)
+      hardcode_direct=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+      export_dynamic_flag_spec='${wl}-E'
+      # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+      # Instead, shared libraries are loaded at an image base (0x10000000 by
+      # default) and relocated if they conflict, which is a slow very memory
+      # consuming and fragmenting process.  To avoid this, we pick a random,
+      # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+      # time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+      archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+      ;;
+
+    gnu* | linux* | tpf* | k*bsd*-gnu)
+      tmp_diet=no
+      if test "$host_os" = linux-dietlibc; then
+	case $cc_basename in
+	  diet\ *) tmp_diet=yes;;	# linux-dietlibc with static linking (!diet-dyn)
+	esac
+      fi
+      if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+	 && test "$tmp_diet" = no
+      then
+	tmp_addflag=
+	tmp_sharedflag='-shared'
+	case $cc_basename,$host_cpu in
+        pgcc*)				# Portland Group C compiler
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag'
+	  ;;
+	pgf77* | pgf90* | pgf95*)	# Portland Group f77 and f90 compilers
+	  whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  tmp_addflag=' $pic_flag -Mnomain' ;;
+	ecc*,ia64* | icc*,ia64*)	# Intel C compiler on ia64
+	  tmp_addflag=' -i_dynamic' ;;
+	efc*,ia64* | ifort*,ia64*)	# Intel Fortran compiler on ia64
+	  tmp_addflag=' -i_dynamic -nofor_main' ;;
+	ifc* | ifort*)			# Intel Fortran compiler
+	  tmp_addflag=' -nofor_main' ;;
+	lf95*)				# Lahey Fortran 8.1
+	  whole_archive_flag_spec=
+	  tmp_sharedflag='--shared' ;;
+	xl[cC]*)			# IBM XL C 8.0 on PPC (deal with xlf below)
+	  tmp_sharedflag='-qmkshrobj'
+	  tmp_addflag= ;;
+	esac
+	case `$CC -V 2>&1 | sed 5q` in
+	*Sun\ C*)			# Sun C 5.9
+	  whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	  compiler_needs_object=yes
+	  tmp_sharedflag='-G' ;;
+	*Sun\ F*)			# Sun Fortran 8.3
+	  tmp_sharedflag='-G' ;;
+	esac
+	archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+        if test "x$supports_anon_versioning" = xyes; then
+          archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	    cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	    echo "local: *; };" >> $output_objdir/$libname.ver~
+	    $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+        fi
+
+	case $cc_basename in
+	xlf*)
+	  # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+	  whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+	  hardcode_libdir_flag_spec=
+	  hardcode_libdir_flag_spec_ld='-rpath $libdir'
+	  archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+	  if test "x$supports_anon_versioning" = xyes; then
+	    archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+	      cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+	      echo "local: *; };" >> $output_objdir/$libname.ver~
+	      $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+	  fi
+	  ;;
+	esac
+      else
+        ld_shlibs=no
+      fi
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+	wlarc=
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      fi
+      ;;
+
+    solaris*)
+      if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+      elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+      case `$LD -v 2>&1` in
+        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+	ld_shlibs=no
+	cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems.  Therefore, libtool
+*** is disabling shared libraries support.  We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer.  Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+	;;
+	*)
+	  # For security reasons, it is highly recommended that you always
+	  # use absolute paths for naming shared libraries, and exclude the
+	  # DT_RUNPATH tag from executables and libraries.  But doing so
+	  # requires that you compile everything twice, which is a pain.
+	  if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	    hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+	    archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+	  else
+	    ld_shlibs=no
+	  fi
+	;;
+      esac
+      ;;
+
+    sunos4*)
+      archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      wlarc=
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+      else
+	ld_shlibs=no
+      fi
+      ;;
+    esac
+
+    if test "$ld_shlibs" = no; then
+      runpath_var=
+      hardcode_libdir_flag_spec=
+      export_dynamic_flag_spec=
+      whole_archive_flag_spec=
+    fi
+  else
+    # PORTME fill in a description of your system's linker (not GNU ld)
+    case $host_os in
+    aix3*)
+      allow_undefined_flag=unsupported
+      always_export_symbols=yes
+      archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+      # Note: this linker hardcodes the directories in LIBPATH if there
+      # are no directories specified by -L.
+      hardcode_minus_L=yes
+      if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+	# Neither direct hardcoding nor static linking is supported with a
+	# broken collect2.
+	hardcode_direct=unsupported
+      fi
+      ;;
+
+    aix[4-9]*)
+      if test "$host_cpu" = ia64; then
+	# On IA64, the linker does run time linking by default, so we don't
+	# have to do anything special.
+	aix_use_runtimelinking=no
+	exp_sym_flag='-Bexport'
+	no_entry_flag=""
+      else
+	# If we're using GNU nm, then we don't want the "-C" option.
+	# -C means demangle to AIX nm, but means don't demangle with GNU nm
+	if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+	  export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	else
+	  export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+	fi
+	aix_use_runtimelinking=no
+
+	# Test if we are trying to use run time linking or normal
+	# AIX style linking. If -brtl is somewhere in LDFLAGS, we
+	# need to do runtime linking.
+	case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	  for ld_flag in $LDFLAGS; do
+	  if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+	    aix_use_runtimelinking=yes
+	    break
+	  fi
+	  done
+	  ;;
+	esac
+
+	exp_sym_flag='-bexport'
+	no_entry_flag='-bnoentry'
+      fi
+
+      # When large executables or shared objects are built, AIX ld can
+      # have problems creating the table of contents.  If linking a library
+      # or program results in "error TOC overflow" add -mminimal-toc to
+      # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+      # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+      archive_cmds=''
+      hardcode_direct=yes
+      hardcode_direct_absolute=yes
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      file_list_spec='${wl}-f,'
+
+      if test "$GCC" = yes; then
+	case $host_os in aix4.[012]|aix4.[012].*)
+	# We only want to do this on AIX 4.2 and lower, the check
+	# below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	   strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	  # We have reworked collect2
+	  :
+	  else
+	  # We have old collect2
+	  hardcode_direct=unsupported
+	  # It fails to find uninstalled libraries when the uninstalled
+	  # path is not listed in the libpath.  Setting hardcode_minus_L
+	  # to unsupported forces relinking
+	  hardcode_minus_L=yes
+	  hardcode_libdir_flag_spec='-L$libdir'
+	  hardcode_libdir_separator=
+	  fi
+	  ;;
+	esac
+	shared_flag='-shared'
+	if test "$aix_use_runtimelinking" = yes; then
+	  shared_flag="$shared_flag "'${wl}-G'
+	fi
+      else
+	# not using gcc
+	if test "$host_cpu" = ia64; then
+	# VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	# chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+	else
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag='${wl}-G'
+	  else
+	    shared_flag='${wl}-bM:SRE'
+	  fi
+	fi
+      fi
+
+      export_dynamic_flag_spec='${wl}-bexpall'
+      # It seems that -bexpall does not export symbols beginning with
+      # underscore (_), so it is better to generate a list of symbols to export.
+      always_export_symbols=yes
+      if test "$aix_use_runtimelinking" = yes; then
+	# Warning - without using the other runtime loading flags (-brtl),
+	# -berok will link without error, but may produce a broken library.
+	allow_undefined_flag='-berok'
+        # Determine the default libpath from the value encoded in an
+        # empty executable.
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+      else
+	if test "$host_cpu" = ia64; then
+	  hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+	  allow_undefined_flag="-z nodefs"
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+	else
+	 # Determine the default libpath from the value encoded in an
+	 # empty executable.
+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	 hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+	  # Warning - without using the other run time loading flags,
+	  # -berok will link without error, but may produce a broken library.
+	  no_undefined_flag=' ${wl}-bernotok'
+	  allow_undefined_flag=' ${wl}-berok'
+	  # Exported symbols can be pulled into shared objects from archives
+	  whole_archive_flag_spec='$convenience'
+	  archive_cmds_need_lc=yes
+	  # This is similar to how AIX traditionally builds its shared libraries.
+	  archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+	fi
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+            archive_expsym_cmds=''
+        ;;
+      m68k)
+            archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+            hardcode_libdir_flag_spec='-L$libdir'
+            hardcode_minus_L=yes
+        ;;
+      esac
+      ;;
+
+    bsdi[45]*)
+      export_dynamic_flag_spec=-rdynamic
+      ;;
+
+    cygwin* | mingw* | pw32* | cegcc*)
+      # When not using gcc, we currently assume that we are using
+      # Microsoft Visual C++.
+      # hardcode_libdir_flag_spec is actually meaningless, as there is
+      # no search path for DLLs.
+      hardcode_libdir_flag_spec=' '
+      allow_undefined_flag=unsupported
+      # Tell ltmain to make .lib files, not .a files.
+      libext=lib
+      # Tell ltmain to make .dll files, not .so files.
+      shrext_cmds=".dll"
+      # FIXME: Setting linknames here is a bad hack.
+      archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
+      # The linker will automatically build a .lib file if we build a DLL.
+      old_archive_from_new_cmds='true'
+      # FIXME: Should let the user specify the lib program.
+      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+      fix_srcfile_path='`cygpath -w "$srcfile"`'
+      enable_shared_with_static_runtimes=yes
+      ;;
+
+    darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc=no
+  hardcode_direct=no
+  hardcode_automatic=yes
+  hardcode_shlibpath_var=unsupported
+  whole_archive_flag_spec=''
+  link_all_deplibs=yes
+  allow_undefined_flag="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+  else
+  ld_shlibs=no
+  fi
+
+      ;;
+
+    dgux*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    freebsd1*)
+      ld_shlibs=no
+      ;;
+
+    # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+    # support.  Future versions do this automatically, but an explicit c++rt0.o
+    # does not break anything, and helps significantly (at the cost of a little
+    # extra space).
+    freebsd2.2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+    freebsd2*)
+      archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+    freebsd* | dragonfly*)
+      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    hpux9*)
+      if test "$GCC" = yes; then
+	archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      else
+	archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+      fi
+      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_direct=yes
+
+      # hardcode_minus_L: Not really in the search PATH,
+      # but as the default location of the library.
+      hardcode_minus_L=yes
+      export_dynamic_flag_spec='${wl}-E'
+      ;;
+
+    hpux10*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_flag_spec_ld='+b $libdir'
+	hardcode_libdir_separator=:
+	hardcode_direct=yes
+	hardcode_direct_absolute=yes
+	export_dynamic_flag_spec='${wl}-E'
+	# hardcode_minus_L: Not really in the search PATH,
+	# but as the default location of the library.
+	hardcode_minus_L=yes
+      fi
+      ;;
+
+    hpux11*)
+      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      else
+	case $host_cpu in
+	hppa*64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	ia64*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	esac
+      fi
+      if test "$with_gnu_ld" = no; then
+	hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+	hardcode_libdir_separator=:
+
+	case $host_cpu in
+	hppa*64*|ia64*)
+	  hardcode_direct=no
+	  hardcode_shlibpath_var=no
+	  ;;
+	*)
+	  hardcode_direct=yes
+	  hardcode_direct_absolute=yes
+	  export_dynamic_flag_spec='${wl}-E'
+
+	  # hardcode_minus_L: Not really in the search PATH,
+	  # but as the default location of the library.
+	  hardcode_minus_L=yes
+	  ;;
+	esac
+      fi
+      ;;
+
+    irix5* | irix6* | nonstopux*)
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	# Try to use the -exported_symbol ld option, if it does not
+	# work, assume that -exports_file does not work either and
+	# implicitly export all symbols.
+        save_LDFLAGS="$LDFLAGS"
+        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+        LDFLAGS="$save_LDFLAGS"
+      else
+	archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      inherit_rpath=yes
+      link_all_deplibs=yes
+      ;;
+
+    netbsd*)
+      if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'  # a.out
+      else
+	archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags'      # ELF
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_direct=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    newsos6)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_direct=yes
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      hardcode_shlibpath_var=no
+      ;;
+
+    *nto* | *qnx*)
+      ;;
+
+    openbsd*)
+      if test -f /usr/libexec/ld.so; then
+	hardcode_direct=yes
+	hardcode_shlibpath_var=no
+	hardcode_direct_absolute=yes
+	if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	  archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+	  hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	  export_dynamic_flag_spec='${wl}-E'
+	else
+	  case $host_os in
+	   openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+	     archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+	     hardcode_libdir_flag_spec='-R$libdir'
+	     ;;
+	   *)
+	     archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+	     hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+	     ;;
+	  esac
+	fi
+      else
+	ld_shlibs=no
+      fi
+      ;;
+
+    os2*)
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_minus_L=yes
+      allow_undefined_flag=unsupported
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+      ;;
+
+    osf3*)
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      hardcode_libdir_separator=:
+      ;;
+
+    osf4* | osf5*)	# as osf3* with the addition of -msym flag
+      if test "$GCC" = yes; then
+	allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+      else
+	allow_undefined_flag=' -expect_unresolved \*'
+	archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+	$CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+	# Both c and cxx compiler support -rpath directly
+	hardcode_libdir_flag_spec='-rpath $libdir'
+      fi
+      archive_cmds_need_lc='no'
+      hardcode_libdir_separator=:
+      ;;
+
+    solaris*)
+      no_undefined_flag=' -z defs'
+      if test "$GCC" = yes; then
+	wlarc='${wl}'
+	archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+      else
+	case `$CC -V 2>&1` in
+	*"Compilers 5.0"*)
+	  wlarc=''
+	  archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+	  ;;
+	*)
+	  wlarc='${wl}'
+	  archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	  $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+	  ;;
+	esac
+      fi
+      hardcode_libdir_flag_spec='-R$libdir'
+      hardcode_shlibpath_var=no
+      case $host_os in
+      solaris2.[0-5] | solaris2.[0-5].*) ;;
+      *)
+	# The compiler driver will combine and reorder linker options,
+	# but understands `-z linker_flag'.  GCC discards it without `$wl',
+	# but is careful enough not to reorder.
+	# Supported since Solaris 2.6 (maybe 2.5.1?)
+	if test "$GCC" = yes; then
+	  whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+	else
+	  whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+	fi
+	;;
+      esac
+      link_all_deplibs=yes
+      ;;
+
+    sunos4*)
+      if test "x$host_vendor" = xsequent; then
+	# Use $CC to link under sequent, because it throws in some extra .o
+	# files that make .init and .fini sections work.
+	archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+      fi
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_direct=yes
+      hardcode_minus_L=yes
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4)
+      case $host_vendor in
+	sni)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=yes # is this really true???
+	;;
+	siemens)
+	  ## LD is ld it makes a PLAMLIB
+	  ## CC just makes a GrossModule.
+	  archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+	  reload_cmds='$CC -r -o $output$reload_objs'
+	  hardcode_direct=no
+        ;;
+	motorola)
+	  archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	  hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+	;;
+      esac
+      runpath_var='LD_RUN_PATH'
+      hardcode_shlibpath_var=no
+      ;;
+
+    sysv4.3*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_shlibpath_var=no
+      export_dynamic_flag_spec='-Bexport'
+      ;;
+
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+	hardcode_shlibpath_var=no
+	runpath_var=LD_RUN_PATH
+	hardcode_runpath_var=yes
+	ld_shlibs=yes
+      fi
+      ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag='${wl}-z,text'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    sysv5* | sco3.2v5* | sco5v6*)
+      # Note: We can NOT use -z defs as we might desire, because we do not
+      # link with -lc, and that would cause any symbols used from libc to
+      # always be unresolved, which means just about no library would
+      # ever link correctly.  If we're not using GNU ld we use -z text
+      # though, which does catch some bad symbols but isn't as heavy-handed
+      # as -z defs.
+      no_undefined_flag='${wl}-z,text'
+      allow_undefined_flag='${wl}-z,nodefs'
+      archive_cmds_need_lc=no
+      hardcode_shlibpath_var=no
+      hardcode_libdir_flag_spec='${wl}-R,$libdir'
+      hardcode_libdir_separator=':'
+      link_all_deplibs=yes
+      export_dynamic_flag_spec='${wl}-Bexport'
+      runpath_var='LD_RUN_PATH'
+
+      if test "$GCC" = yes; then
+	archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      else
+	archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+      fi
+      ;;
+
+    uts4*)
+      archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+      hardcode_libdir_flag_spec='-L$libdir'
+      hardcode_shlibpath_var=no
+      ;;
+
+    *)
+      ld_shlibs=no
+      ;;
+    esac
+
+    if test x$host_vendor = xsni; then
+      case $host in
+      sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+	export_dynamic_flag_spec='${wl}-Blargedynsym'
+	;;
+      esac
+    fi
+  fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl
+	pic_flag=$lt_prog_compiler_pic
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag
+        allow_undefined_flag=
+        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        then
+	  archive_cmds_need_lc=no
+        else
+	  archive_cmds_need_lc=yes
+        fi
+        allow_undefined_flag=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
+$as_echo "$archive_cmds_need_lc" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+  case $host_os in
+    darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+    *) lt_awk_arg="/^libraries:/" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+    # if the path contains ";" then we assume it to be the separator
+    # otherwise default to the standard path separator (i.e. ":") - it is
+    # assumed that no part of a normal pathname contains ";" but that should
+    # okay in the real world where ";" in dirpaths is itself problematic.
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
+  else
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+  fi
+  # Ok, now we have the path, separated by spaces, we can step through it
+  # and add multilib dir if necessary.
+  lt_tmp_lt_search_path_spec=
+  lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+  for lt_sys_path in $lt_search_path_spec; do
+    if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+      lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+    else
+      test -d "$lt_sys_path" && \
+	lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+    fi
+  done
+  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+  lt_foo="";
+  lt_count=0;
+  for (lt_i = NF; lt_i > 0; lt_i--) {
+    if ($lt_i != "" && $lt_i != ".") {
+      if ($lt_i == "..") {
+        lt_count++;
+      } else {
+        if (lt_count == 0) {
+          lt_foo="/" $lt_i lt_foo;
+        } else {
+          lt_count--;
+        }
+      }
+    }
+  }
+  if (lt_foo != "") { lt_freq[lt_foo]++; }
+  if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+else
+  sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+       LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+   test -n "$runpath_var" ||
+   test "X$hardcode_automatic" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+     test "$hardcode_minus_L" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+   test "$inherit_rpath" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+  if test "x$enable_dlopen" != xyes; then
+  enable_dlopen=unknown
+  enable_dlopen_self=unknown
+  enable_dlopen_self_static=unknown
+else
+  lt_cv_dlopen=no
+  lt_cv_dlopen_libs=
+
+  case $host_os in
+  beos*)
+    lt_cv_dlopen="load_add_on"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+    ;;
+
+  mingw* | pw32* | cegcc*)
+    lt_cv_dlopen="LoadLibrary"
+    lt_cv_dlopen_libs=
+    ;;
+
+  cygwin*)
+    lt_cv_dlopen="dlopen"
+    lt_cv_dlopen_libs=
+    ;;
+
+  darwin*)
+  # if libdl is installed we need to link against it
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+    lt_cv_dlopen="dyld"
+    lt_cv_dlopen_libs=
+    lt_cv_dlopen_self=yes
+
+fi
+
+    ;;
+
+  *)
+    ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_shl_load=yes
+else
+  ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+  lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+  ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dl_dlopen=yes
+else
+  ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_svld_dlopen=yes
+else
+  ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+  lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_dld_dld_link=yes
+else
+  ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+  lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+    ;;
+  esac
+
+  if test "x$lt_cv_dlopen" != xno; then
+    enable_dlopen=yes
+  else
+    enable_dlopen=no
+  fi
+
+  case $lt_cv_dlopen in
+  dlopen)
+    save_CPPFLAGS="$CPPFLAGS"
+    test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+    save_LDFLAGS="$LDFLAGS"
+    wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+    save_LIBS="$LIBS"
+    LIBS="$lt_cv_dlopen_libs $LIBS"
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 12339 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+    if test "x$lt_cv_dlopen_self" = xyes; then
+      wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  	  if test "$cross_compiling" = yes; then :
+  lt_cv_dlopen_self_static=cross
+else
+  lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+  lt_status=$lt_dlunknown
+  cat > conftest.$ac_ext <<_LT_EOF
+#line 12435 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+#  define LT_DLGLOBAL		RTLD_GLOBAL
+#else
+#  ifdef DL_GLOBAL
+#    define LT_DLGLOBAL		DL_GLOBAL
+#  else
+#    define LT_DLGLOBAL		0
+#  endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+   find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+#  ifdef RTLD_LAZY
+#    define LT_DLLAZY_OR_NOW		RTLD_LAZY
+#  else
+#    ifdef DL_LAZY
+#      define LT_DLLAZY_OR_NOW		DL_LAZY
+#    else
+#      ifdef RTLD_NOW
+#        define LT_DLLAZY_OR_NOW	RTLD_NOW
+#      else
+#        ifdef DL_NOW
+#          define LT_DLLAZY_OR_NOW	DL_NOW
+#        else
+#          define LT_DLLAZY_OR_NOW	0
+#        endif
+#      endif
+#    endif
+#  endif
+#endif
+
+void fnord() { int i=42;}
+int main ()
+{
+  void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+  int status = $lt_dlunknown;
+
+  if (self)
+    {
+      if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
+      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      /* dlclose (self); */
+    }
+  else
+    puts (dlerror ());
+
+  return status;
+}
+_LT_EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+    (./conftest; exit; ) >&5 2>/dev/null
+    lt_status=$?
+    case x$lt_status in
+      x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+      x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+    esac
+  else :
+    # compilation failed
+    lt_cv_dlopen_self_static=no
+  fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+    fi
+
+    CPPFLAGS="$save_CPPFLAGS"
+    LDFLAGS="$save_LDFLAGS"
+    LIBS="$save_LIBS"
+    ;;
+  esac
+
+  case $lt_cv_dlopen_self in
+  yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+  *) enable_dlopen_self=unknown ;;
+  esac
+
+  case $lt_cv_dlopen_self_static in
+  yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+  *) enable_dlopen_self_static=unknown ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+  test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+  test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+  case $host_os in
+  darwin*)
+    if test -n "$STRIP" ; then
+      striplib="$STRIP -x"
+      old_striplib="$STRIP -S"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    fi
+    ;;
+  *)
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    ;;
+  esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+  # Report which library types will actually be built
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+  test "$can_build_shared" = "no" && enable_shared=no
+
+  # On AIX, shared libraries and static libraries use the same namespace, and
+  # are all built from PIC.
+  case $host_os in
+  aix3*)
+    test "$enable_shared" = yes && enable_static=no
+    if test -n "$RANLIB"; then
+      archive_cmds="$archive_cmds~\$RANLIB \$lib"
+      postinstall_cmds='$RANLIB $lib'
+    fi
+    ;;
+
+  aix[4-9]*)
+    if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+      test "$enable_shared" = yes && enable_static=no
+    fi
+    ;;
+  esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+  # Make sure either enable_shared or enable_static is yes.
+  test "$enable_shared" = yes || enable_static=yes
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+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
+
+CC="$lt_save_CC"
+
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working.  Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+  # Code to be used in simple compile tests
+  lt_simple_compile_test_code="int some_variable = 0;"
+
+  # Code to be used in simple link tests
+  lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+  # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+  # save warnings/boilerplate of simple test code
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+  ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+  # Allow CC to be a program name with arguments.
+  lt_save_CC=$CC
+  lt_save_LD=$LD
+  lt_save_GCC=$GCC
+  GCC=$GXX
+  lt_save_with_gnu_ld=$with_gnu_ld
+  lt_save_path_LD=$lt_cv_path_LD
+  if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+    lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+  else
+    $as_unset lt_cv_prog_gnu_ld
+  fi
+  if test -n "${lt_cv_path_LDCXX+set}"; then
+    lt_cv_path_LD=$lt_cv_path_LDCXX
+  else
+    $as_unset lt_cv_path_LD
+  fi
+  test -z "${LDCXX+set}" || LD=$LDCXX
+  CC=${CXX-"c++"}
+  compiler=$CC
+  compiler_CXX=$CC
+  for cc_temp in $compiler""; do
+  case $cc_temp in
+    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+    \-*) ;;
+    *) break;;
+  esac
+done
+cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+
+
+  if test -n "$compiler"; then
+    # We don't want -fno-exception when compiling C++ code, so set the
+    # no_builtin_flag separately
+    if test "$GXX" = yes; then
+      lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+    else
+      lt_prog_compiler_no_builtin_flag_CXX=
+    fi
+
+    if test "$GXX" = yes; then
+      # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+  withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+  with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+  # Check if gcc -print-prog-name=ld gives a path.
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+  case $host in
+  *-*-mingw*)
+    # gcc leaves a trailing carriage return which upsets mingw
+    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+  *)
+    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+  esac
+  case $ac_prog in
+    # Accept absolute paths.
+    [\\/]* | ?:[\\/]*)
+      re_direlt='/[^/][^/]*/\.\./'
+      # Canonicalize the pathname of ld
+      ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+      while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+	ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+      done
+      test -z "$LD" && LD="$ac_prog"
+      ;;
+  "")
+    # If it fails, then pretend we aren't using GCC.
+    ac_prog=ld
+    ;;
+  *)
+    # If it is relative, then search for the first ld in PATH.
+    with_gnu_ld=unknown
+    ;;
+  esac
+elif test "$with_gnu_ld" = yes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -z "$LD"; then
+  lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+  for ac_dir in $PATH; do
+    IFS="$lt_save_ifs"
+    test -z "$ac_dir" && ac_dir=.
+    if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+      lt_cv_path_LD="$ac_dir/$ac_prog"
+      # Check to see if the program is GNU ld.  I'd rather use --version,
+      # but apparently some variants of GNU ld only accept -v.
+      # Break only if it was the GNU/non-GNU ld that we prefer.
+      case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+      *GNU* | *'with BFD'*)
+	test "$with_gnu_ld" != no && break
+	;;
+      *)
+	test "$with_gnu_ld" != yes && break
+	;;
+      esac
+    fi
+  done
+  IFS="$lt_save_ifs"
+else
+  lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  lt_cv_prog_gnu_ld=yes
+  ;;
+*)
+  lt_cv_prog_gnu_ld=no
+  ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+      # Check if GNU C++ uses GNU ld as the underlying linker, since the
+      # archiving commands below assume that GNU ld is being used.
+      if test "$with_gnu_ld" = yes; then
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+        # If archive_cmds runs LD, not CC, wlarc should be empty
+        # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+        #     investigate it a little bit more. (MM)
+        wlarc='${wl}'
+
+        # ancient GNU ld didn't support --whole-archive et. al.
+        if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+	  $GREP 'no-whole-archive' > /dev/null; then
+          whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+        else
+          whole_archive_flag_spec_CXX=
+        fi
+      else
+        with_gnu_ld=no
+        wlarc=
+
+        # A generic and very simple default shared library creation
+        # command for GNU C++ for the case where it uses the native
+        # linker, instead of GNU ld.  If possible, this setting should
+        # overridden to take advantage of the native linker features on
+        # the platform it is being used on.
+        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+      fi
+
+      # Commands to make compiler produce verbose output that lists
+      # what "hidden" libraries, object files and flags are used when
+      # linking a shared library.
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+    else
+      GXX=no
+      with_gnu_ld=no
+      wlarc=
+    fi
+
+    # PORTME: fill in a description of your system's C++ link characteristics
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+    ld_shlibs_CXX=yes
+    case $host_os in
+      aix3*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+      aix[4-9]*)
+        if test "$host_cpu" = ia64; then
+          # On IA64, the linker does run time linking by default, so we don't
+          # have to do anything special.
+          aix_use_runtimelinking=no
+          exp_sym_flag='-Bexport'
+          no_entry_flag=""
+        else
+          aix_use_runtimelinking=no
+
+          # Test if we are trying to use run time linking or normal
+          # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+          # need to do runtime linking.
+          case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+	    for ld_flag in $LDFLAGS; do
+	      case $ld_flag in
+	      *-brtl*)
+	        aix_use_runtimelinking=yes
+	        break
+	        ;;
+	      esac
+	    done
+	    ;;
+          esac
+
+          exp_sym_flag='-bexport'
+          no_entry_flag='-bnoentry'
+        fi
+
+        # When large executables or shared objects are built, AIX ld can
+        # have problems creating the table of contents.  If linking a library
+        # or program results in "error TOC overflow" add -mminimal-toc to
+        # CXXFLAGS/CFLAGS for g++/gcc.  In the cases where that is not
+        # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+        archive_cmds_CXX=''
+        hardcode_direct_CXX=yes
+        hardcode_direct_absolute_CXX=yes
+        hardcode_libdir_separator_CXX=':'
+        link_all_deplibs_CXX=yes
+        file_list_spec_CXX='${wl}-f,'
+
+        if test "$GXX" = yes; then
+          case $host_os in aix4.[012]|aix4.[012].*)
+          # We only want to do this on AIX 4.2 and lower, the check
+          # below for broken collect2 doesn't work under 4.3+
+	  collect2name=`${CC} -print-prog-name=collect2`
+	  if test -f "$collect2name" &&
+	     strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+	  then
+	    # We have reworked collect2
+	    :
+	  else
+	    # We have old collect2
+	    hardcode_direct_CXX=unsupported
+	    # It fails to find uninstalled libraries when the uninstalled
+	    # path is not listed in the libpath.  Setting hardcode_minus_L
+	    # to unsupported forces relinking
+	    hardcode_minus_L_CXX=yes
+	    hardcode_libdir_flag_spec_CXX='-L$libdir'
+	    hardcode_libdir_separator_CXX=
+	  fi
+          esac
+          shared_flag='-shared'
+	  if test "$aix_use_runtimelinking" = yes; then
+	    shared_flag="$shared_flag "'${wl}-G'
+	  fi
+        else
+          # not using gcc
+          if test "$host_cpu" = ia64; then
+	  # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+	  # chokes on -Wl,-G. The following line is correct:
+	  shared_flag='-G'
+          else
+	    if test "$aix_use_runtimelinking" = yes; then
+	      shared_flag='${wl}-G'
+	    else
+	      shared_flag='${wl}-bM:SRE'
+	    fi
+          fi
+        fi
+
+        export_dynamic_flag_spec_CXX='${wl}-bexpall'
+        # It seems that -bexpall does not export symbols beginning with
+        # underscore (_), so it is better to generate a list of symbols to
+	# export.
+        always_export_symbols_CXX=yes
+        if test "$aix_use_runtimelinking" = yes; then
+          # Warning - without using the other runtime loading flags (-brtl),
+          # -berok will link without error, but may produce a broken library.
+          allow_undefined_flag_CXX='-berok'
+          # Determine the default libpath from the value encoded in an empty
+          # executable.
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+          hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+          archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        else
+          if test "$host_cpu" = ia64; then
+	    hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+	    allow_undefined_flag_CXX="-z nodefs"
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+          else
+	    # Determine the default libpath from the value encoded in an
+	    # empty executable.
+	    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+    /Import File Strings/,/^$/ {
+	/^0/ {
+	    s/^0  *\(.*\)$/\1/
+	    p
+	}
+    }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+	    # Warning - without using the other run time loading flags,
+	    # -berok will link without error, but may produce a broken library.
+	    no_undefined_flag_CXX=' ${wl}-bernotok'
+	    allow_undefined_flag_CXX=' ${wl}-berok'
+	    # Exported symbols can be pulled into shared objects from archives
+	    whole_archive_flag_spec_CXX='$convenience'
+	    archive_cmds_need_lc_CXX=yes
+	    # This is similar to how AIX traditionally builds its shared
+	    # libraries.
+	    archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+          fi
+        fi
+        ;;
+
+      beos*)
+	if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+	  allow_undefined_flag_CXX=unsupported
+	  # Joseph Beckenbach <jrb3 at best.com> says some releases of gcc
+	  # support --undefined.  This deserves some investigation.  FIXME
+	  archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      chorus*)
+        case $cc_basename in
+          *)
+	  # FIXME: insert proper C++ library support
+	  ld_shlibs_CXX=no
+	  ;;
+        esac
+        ;;
+
+      cygwin* | mingw* | pw32* | cegcc*)
+        # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+        # as there is no search path for DLLs.
+        hardcode_libdir_flag_spec_CXX='-L$libdir'
+        allow_undefined_flag_CXX=unsupported
+        always_export_symbols_CXX=no
+        enable_shared_with_static_runtimes_CXX=yes
+
+        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+          archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+          # If the export-symbols file already is a .def file (1st line
+          # is EXPORTS), use it as is; otherwise, prepend...
+          archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+	    cp $export_symbols $output_objdir/$soname.def;
+          else
+	    echo EXPORTS > $output_objdir/$soname.def;
+	    cat $export_symbols >> $output_objdir/$soname.def;
+          fi~
+          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+        else
+          ld_shlibs_CXX=no
+        fi
+        ;;
+      darwin* | rhapsody*)
+
+
+  archive_cmds_need_lc_CXX=no
+  hardcode_direct_CXX=no
+  hardcode_automatic_CXX=yes
+  hardcode_shlibpath_var_CXX=unsupported
+  whole_archive_flag_spec_CXX=''
+  link_all_deplibs_CXX=yes
+  allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+  case $cc_basename in
+     ifort*) _lt_dar_can_shared=yes ;;
+     *) _lt_dar_can_shared=$GCC ;;
+  esac
+  if test "$_lt_dar_can_shared" = "yes"; then
+    output_verbose_link_cmd=echo
+    archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+    module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+    archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+    module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+       if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+      archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+      archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+    fi
+
+  else
+  ld_shlibs_CXX=no
+  fi
+
+	;;
+
+      dgux*)
+        case $cc_basename in
+          ec++*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          ghcx*)
+	    # Green Hills C++ Compiler
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      freebsd[12]*)
+        # C++ shared libraries reported to be fairly broken before
+	# switch to ELF
+        ld_shlibs_CXX=no
+        ;;
+
+      freebsd-elf*)
+        archive_cmds_need_lc_CXX=no
+        ;;
+
+      freebsd* | dragonfly*)
+        # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+        # conventions
+        ld_shlibs_CXX=yes
+        ;;
+
+      gnu*)
+        ;;
+
+      hpux9*)
+        hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        export_dynamic_flag_spec_CXX='${wl}-E'
+        hardcode_direct_CXX=yes
+        hardcode_minus_L_CXX=yes # Not in the search PATH,
+				             # but as the default
+				             # location of the library.
+
+        case $cc_basename in
+          CC*)
+            # FIXME: insert proper C++ library support
+            ld_shlibs_CXX=no
+            ;;
+          aCC*)
+            archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            # Commands to make compiler produce verbose output that lists
+            # what "hidden" libraries, object files and flags are used when
+            # linking a shared library.
+            #
+            # There doesn't appear to be a way to prevent this compiler from
+            # explicitly linking system object files so we need to strip them
+            # from the output so that they don't get included in the library
+            # dependencies.
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+            ;;
+          *)
+            if test "$GXX" = yes; then
+              archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+            else
+              # FIXME: insert proper C++ library support
+              ld_shlibs_CXX=no
+            fi
+            ;;
+        esac
+        ;;
+
+      hpux10*|hpux11*)
+        if test $with_gnu_ld = no; then
+	  hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+	  hardcode_libdir_separator_CXX=:
+
+          case $host_cpu in
+            hppa*64*|ia64*)
+              ;;
+            *)
+	      export_dynamic_flag_spec_CXX='${wl}-E'
+              ;;
+          esac
+        fi
+        case $host_cpu in
+          hppa*64*|ia64*)
+            hardcode_direct_CXX=no
+            hardcode_shlibpath_var_CXX=no
+            ;;
+          *)
+            hardcode_direct_CXX=yes
+            hardcode_direct_absolute_CXX=yes
+            hardcode_minus_L_CXX=yes # Not in the search PATH,
+					         # but as the default
+					         # location of the library.
+            ;;
+        esac
+
+        case $cc_basename in
+          CC*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          aCC*)
+	    case $host_cpu in
+	      hppa*64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      ia64*)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	      *)
+	        archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	        ;;
+	    esac
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test $with_gnu_ld = no; then
+	        case $host_cpu in
+	          hppa*64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          ia64*)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	          *)
+	            archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	            ;;
+	        esac
+	      fi
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      interix[3-9]*)
+	hardcode_direct_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	export_dynamic_flag_spec_CXX='${wl}-E'
+	# Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+	# Instead, shared libraries are loaded at an image base (0x10000000 by
+	# default) and relocated if they conflict, which is a slow very memory
+	# consuming and fragmenting process.  To avoid this, we pick a random,
+	# 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+	# time.  Moving up from 0x10000000 also allows more sbrk(2) space.
+	archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+	;;
+      irix5* | irix6*)
+        case $cc_basename in
+          CC*)
+	    # SGI C++
+	    archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    if test "$GXX" = yes; then
+	      if test "$with_gnu_ld" = no; then
+	        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+	      else
+	        archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+	      fi
+	    fi
+	    link_all_deplibs_CXX=yes
+	    ;;
+        esac
+        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+        hardcode_libdir_separator_CXX=:
+        inherit_rpath_CXX=yes
+        ;;
+
+      linux* | k*bsd*-gnu)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+	    archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+	    old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+	    ;;
+	  icpc* | ecpc* )
+	    # Intel C++
+	    with_gnu_ld=yes
+	    # version 8.0 and above of icpc choke on multiply defined symbols
+	    # if we add $predep_objects and $postdep_objects, however 7.1 and
+	    # earlier do not add the objects themselves.
+	    case `$CC -V 2>&1` in
+	      *"Version 7."*)
+	        archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	      *)  # Version 8.0 or newer
+	        tmp_idyn=
+	        case $host_cpu in
+		  ia64*) tmp_idyn=' -i_dynamic';;
+		esac
+	        archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+		archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+		;;
+	    esac
+	    archive_cmds_need_lc_CXX=no
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+	    ;;
+          pgCC* | pgcpp*)
+            # Portland Group C++ compiler
+	    case `$CC -V` in
+	    *pgCC\ [1-5]* | *pgcpp\ [1-5]*)
+	      prelink_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+		compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+	      old_archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+		$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+		$RANLIB $oldlib'
+	      archive_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='tpldir=Template.dir~
+		rm -rf $tpldir~
+		$CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+		$CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    *) # Version 6 will use weak symbols
+	      archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+	      archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+	      ;;
+	    esac
+
+	    hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+            ;;
+	  cxx*)
+	    # Compaq C++
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname  -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+	    runpath_var=LD_RUN_PATH
+	    hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  xl*)
+	    # IBM XL 8.0 on PPC, with GNU ld
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	    export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+	    archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+	    if test "x$supports_anon_versioning" = xyes; then
+	      archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+		cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+		echo "local: *; };" >> $output_objdir/$libname.ver~
+		$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+	    fi
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      no_undefined_flag_CXX=' -zdefs'
+	      archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	      archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+	      hardcode_libdir_flag_spec_CXX='-R$libdir'
+	      whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+	      compiler_needs_object_CXX=yes
+
+	      # Not sure whether something based on
+	      # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+	      # would be better.
+	      output_verbose_link_cmd='echo'
+
+	      # Archives containing C++ object files must be created using
+	      # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	      # necessary to make sure instantiated templates are included
+	      # in the archive.
+	      old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+
+      lynxos*)
+        # FIXME: insert proper C++ library support
+	ld_shlibs_CXX=no
+	;;
+
+      m88k*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+	;;
+
+      mvs*)
+        case $cc_basename in
+          cxx*)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	  *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+	esac
+	;;
+
+      netbsd*)
+        if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+	  archive_cmds_CXX='$LD -Bshareable  -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+	  wlarc=
+	  hardcode_libdir_flag_spec_CXX='-R$libdir'
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	fi
+	# Workaround some broken pre-1.5 toolchains
+	output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+	;;
+
+      *nto* | *qnx*)
+        ld_shlibs_CXX=yes
+	;;
+
+      openbsd2*)
+        # C++ shared libraries are fairly broken
+	ld_shlibs_CXX=no
+	;;
+
+      openbsd*)
+	if test -f /usr/libexec/ld.so; then
+	  hardcode_direct_CXX=yes
+	  hardcode_shlibpath_var_CXX=no
+	  hardcode_direct_absolute_CXX=yes
+	  archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+	  hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	  if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+	    archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+	    export_dynamic_flag_spec_CXX='${wl}-E'
+	    whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+	  fi
+	  output_verbose_link_cmd=echo
+	else
+	  ld_shlibs_CXX=no
+	fi
+	;;
+
+      osf3* | osf4* | osf5*)
+        case $cc_basename in
+          KCC*)
+	    # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+	    # KCC will only create a shared library if the output file
+	    # ends with ".so" (or ".sl" for HP-UX), so rename the library
+	    # to its proper name (with version) after linking.
+	    archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+	    hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+	    hardcode_libdir_separator_CXX=:
+
+	    # Archives containing C++ object files must be created using
+	    # the KAI C++ compiler.
+	    case $host in
+	      osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+	      *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+	    esac
+	    ;;
+          RCC*)
+	    # Rational C++ 2.4.1
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          cxx*)
+	    case $host in
+	      osf3*)
+	        allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+		;;
+	      *)
+	        allow_undefined_flag_CXX=' -expect_unresolved \*'
+	        archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+	        archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+	          echo "-hidden">> $lib.exp~
+	          $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+	          $RM $lib.exp'
+	        hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+		;;
+	    esac
+
+	    hardcode_libdir_separator_CXX=:
+
+	    # Commands to make compiler produce verbose output that lists
+	    # what "hidden" libraries, object files and flags are used when
+	    # linking a shared library.
+	    #
+	    # There doesn't appear to be a way to prevent this compiler from
+	    # explicitly linking system object files so we need to strip them
+	    # from the output so that they don't get included in the library
+	    # dependencies.
+	    output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+	    ;;
+	  *)
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+	      case $host in
+	        osf3*)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	        *)
+	          archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+		  ;;
+	      esac
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+	      hardcode_libdir_separator_CXX=:
+
+	      # Commands to make compiler produce verbose output that lists
+	      # what "hidden" libraries, object files and flags are used when
+	      # linking a shared library.
+	      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+
+	    else
+	      # FIXME: insert proper C++ library support
+	      ld_shlibs_CXX=no
+	    fi
+	    ;;
+        esac
+        ;;
+
+      psos*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      sunos4*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.x
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          lcc*)
+	    # Lucid
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      solaris*)
+        case $cc_basename in
+          CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+            archive_cmds_need_lc_CXX=yes
+	    no_undefined_flag_CXX=' -zdefs'
+	    archive_cmds_CXX='$CC -G${allow_undefined_flag}  -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+	    archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+	      $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	    hardcode_libdir_flag_spec_CXX='-R$libdir'
+	    hardcode_shlibpath_var_CXX=no
+	    case $host_os in
+	      solaris2.[0-5] | solaris2.[0-5].*) ;;
+	      *)
+		# The compiler driver will combine and reorder linker options,
+		# but understands `-z linker_flag'.
+	        # Supported since Solaris 2.6 (maybe 2.5.1?)
+		whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+	        ;;
+	    esac
+	    link_all_deplibs_CXX=yes
+
+	    output_verbose_link_cmd='echo'
+
+	    # Archives containing C++ object files must be created using
+	    # "CC -xar", where "CC" is the Sun C++ compiler.  This is
+	    # necessary to make sure instantiated templates are included
+	    # in the archive.
+	    old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+	    ;;
+          gcx*)
+	    # Green Hills C++ Compiler
+	    archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+	    # The C++ compiler must be used to create the archive.
+	    old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+	    ;;
+          *)
+	    # GNU C++ compiler with Solaris linker
+	    if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+	      no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+	      if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+	        archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      else
+	        # g++ 2.7 appears to require `-G' NOT `-shared' on this
+	        # platform.
+	        archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+	        archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+		  $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+	        # Commands to make compiler produce verbose output that lists
+	        # what "hidden" libraries, object files and flags are used when
+	        # linking a shared library.
+	        output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+	      fi
+
+	      hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+	      case $host_os in
+		solaris2.[0-5] | solaris2.[0-5].*) ;;
+		*)
+		  whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+		  ;;
+	      esac
+	    fi
+	    ;;
+        esac
+        ;;
+
+    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+      no_undefined_flag_CXX='${wl}-z,text'
+      archive_cmds_need_lc_CXX=no
+      hardcode_shlibpath_var_CXX=no
+      runpath_var='LD_RUN_PATH'
+
+      case $cc_basename in
+        CC*)
+	  archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+	*)
+	  archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	  ;;
+      esac
+      ;;
+
+      sysv5* | sco3.2v5* | sco5v6*)
+	# Note: We can NOT use -z defs as we might desire, because we do not
+	# link with -lc, and that would cause any symbols used from libc to
+	# always be unresolved, which means just about no library would
+	# ever link correctly.  If we're not using GNU ld we use -z text
+	# though, which does catch some bad symbols but isn't as heavy-handed
+	# as -z defs.
+	no_undefined_flag_CXX='${wl}-z,text'
+	allow_undefined_flag_CXX='${wl}-z,nodefs'
+	archive_cmds_need_lc_CXX=no
+	hardcode_shlibpath_var_CXX=no
+	hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+	hardcode_libdir_separator_CXX=':'
+	link_all_deplibs_CXX=yes
+	export_dynamic_flag_spec_CXX='${wl}-Bexport'
+	runpath_var='LD_RUN_PATH'
+
+	case $cc_basename in
+          CC*)
+	    archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	  *)
+	    archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+	    ;;
+	esac
+      ;;
+
+      tandem*)
+        case $cc_basename in
+          NCC*)
+	    # NonStop-UX NCC 3.20
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+          *)
+	    # FIXME: insert proper C++ library support
+	    ld_shlibs_CXX=no
+	    ;;
+        esac
+        ;;
+
+      vxworks*)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+
+      *)
+        # FIXME: insert proper C++ library support
+        ld_shlibs_CXX=no
+        ;;
+    esac
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+    test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+    GCC_CXX="$GXX"
+    LD_CXX="$LD"
+
+    ## CAVEAT EMPTOR:
+    ## There is no encapsulation within the following macros, do not change
+    ## the running order or otherwise move them around unless you know exactly
+    ## what you are doing...
+    # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+  Foo (void) { a = 0; }
+private:
+  int a;
+};
+_LT_EOF
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  # Parse the compiler output and extract the necessary
+  # objects, libraries and library flags.
+
+  # Sentinel used to keep track of whether or not we are before
+  # the conftest object file.
+  pre_test_object_deps_done=no
+
+  for p in `eval "$output_verbose_link_cmd"`; do
+    case $p in
+
+    -L* | -R* | -l*)
+       # Some compilers place space between "-{L,R}" and the path.
+       # Remove the space.
+       if test $p = "-L" ||
+          test $p = "-R"; then
+	 prev=$p
+	 continue
+       else
+	 prev=
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 case $p in
+	 -L* | -R*)
+	   # Internal compiler library paths should come after those
+	   # provided the user.  The postdeps already come after the
+	   # user supplied libs so there is no need to process them.
+	   if test -z "$compiler_lib_search_path_CXX"; then
+	     compiler_lib_search_path_CXX="${prev}${p}"
+	   else
+	     compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+	   fi
+	   ;;
+	 # The "-l" case would never come before the object being
+	 # linked, so don't bother handling this case.
+	 esac
+       else
+	 if test -z "$postdeps_CXX"; then
+	   postdeps_CXX="${prev}${p}"
+	 else
+	   postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+	 fi
+       fi
+       ;;
+
+    *.$objext)
+       # This assumes that the test object file only shows up
+       # once in the compiler output.
+       if test "$p" = "conftest.$objext"; then
+	 pre_test_object_deps_done=yes
+	 continue
+       fi
+
+       if test "$pre_test_object_deps_done" = no; then
+	 if test -z "$predep_objects_CXX"; then
+	   predep_objects_CXX="$p"
+	 else
+	   predep_objects_CXX="$predep_objects_CXX $p"
+	 fi
+       else
+	 if test -z "$postdep_objects_CXX"; then
+	   postdep_objects_CXX="$p"
+	 else
+	   postdep_objects_CXX="$postdep_objects_CXX $p"
+	 fi
+       fi
+       ;;
+
+    *) ;; # Ignore the rest.
+
+    esac
+  done
+
+  # Clean up.
+  rm -f a.out a.exe
+else
+  echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+  # Interix 3.5 installs completely hosed .la files for C++, so rather than
+  # hack all around it, let's just trust "g++" to DTRT.
+  predep_objects_CXX=
+  postdep_objects_CXX=
+  postdeps_CXX=
+  ;;
+
+linux*)
+  case `$CC -V 2>&1 | sed 5q` in
+  *Sun\ C*)
+    # Sun C++ 5.9
+
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+
+solaris*)
+  case $cc_basename in
+  CC*)
+    # The more standards-conforming stlport4 library is
+    # incompatible with the Cstd library. Avoid specifying
+    # it if it's in CXXFLAGS. Ignore libCrun as
+    # -library=stlport4 depends on it.
+    case " $CXX $CXXFLAGS " in
+    *" -library=stlport4 "*)
+      solaris_use_stlport4=yes
+      ;;
+    esac
+
+    # Adding this requires a known-good setup of shared libraries for
+    # Sun compiler versions before 5.6, else PIC objects from an old
+    # archive will be linked into the output, leading to subtle bugs.
+    if test "$solaris_use_stlport4" != yes; then
+      postdeps_CXX='-library=Cstd -library=Crun'
+    fi
+    ;;
+  esac
+  ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+  # C++ specific cases for pic, static, wl, etc.
+  if test "$GXX" = yes; then
+    lt_prog_compiler_wl_CXX='-Wl,'
+    lt_prog_compiler_static_CXX='-static'
+
+    case $host_os in
+    aix*)
+      # All AIX code is PIC.
+      if test "$host_cpu" = ia64; then
+	# AIX 5 now supports IA64 processor
+	lt_prog_compiler_static_CXX='-Bstatic'
+      fi
+      ;;
+
+    amigaos*)
+      case $host_cpu in
+      powerpc)
+            # see comment about AmigaOS4 .so support
+            lt_prog_compiler_pic_CXX='-fPIC'
+        ;;
+      m68k)
+            # FIXME: we need at least 68020 code to build shared libraries, but
+            # adding the `-m68020' flag to GCC prevents building anything better,
+            # like `-m68040'.
+            lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+        ;;
+      esac
+      ;;
+
+    beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+      # PIC is the default for these OSes.
+      ;;
+    mingw* | cygwin* | os2* | pw32* | cegcc*)
+      # This hack is so that the source file can tell whether it is being
+      # built for inclusion in a dll (and should export symbols for example).
+      # Although the cygwin gcc ignores -fPIC, still need this for old-style
+      # (--disable-auto-import) libraries
+      lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+      ;;
+    darwin* | rhapsody*)
+      # PIC is the default on this platform
+      # Common symbols not allowed in MH_DYLIB files
+      lt_prog_compiler_pic_CXX='-fno-common'
+      ;;
+    *djgpp*)
+      # DJGPP does not support shared libraries at all
+      lt_prog_compiler_pic_CXX=
+      ;;
+    interix[3-9]*)
+      # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+      # Instead, we relocate shared libraries at runtime.
+      ;;
+    sysv4*MP*)
+      if test -d /usr/nec; then
+	lt_prog_compiler_pic_CXX=-Kconform_pic
+      fi
+      ;;
+    hpux*)
+      # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+      # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
+      # sets the default TLS model and affects inlining.
+      case $host_cpu in
+      hppa*64*)
+	;;
+      *)
+	lt_prog_compiler_pic_CXX='-fPIC'
+	;;
+      esac
+      ;;
+    *qnx* | *nto*)
+      # QNX uses GNU C++, but need to define -shared option too, otherwise
+      # it will coredump.
+      lt_prog_compiler_pic_CXX='-fPIC -shared'
+      ;;
+    *)
+      lt_prog_compiler_pic_CXX='-fPIC'
+      ;;
+    esac
+  else
+    case $host_os in
+      aix[4-9]*)
+	# All AIX code is PIC.
+	if test "$host_cpu" = ia64; then
+	  # AIX 5 now supports IA64 processor
+	  lt_prog_compiler_static_CXX='-Bstatic'
+	else
+	  lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+	fi
+	;;
+      chorus*)
+	case $cc_basename in
+	cxch68*)
+	  # Green Hills C++ Compiler
+	  # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+	  ;;
+	esac
+	;;
+      dgux*)
+	case $cc_basename in
+	  ec++*)
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  ghcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      freebsd* | dragonfly*)
+	# FreeBSD uses GNU C++
+	;;
+      hpux9* | hpux10* | hpux11*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    if test "$host_cpu" != ia64; then
+	      lt_prog_compiler_pic_CXX='+Z'
+	    fi
+	    ;;
+	  aCC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+	    case $host_cpu in
+	    hppa*64*|ia64*)
+	      # +Z the default
+	      ;;
+	    *)
+	      lt_prog_compiler_pic_CXX='+Z'
+	      ;;
+	    esac
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      interix*)
+	# This is c89, which is MS Visual C++ (no shared libs)
+	# Anyone wants to do a port?
+	;;
+      irix5* | irix6* | nonstopux*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    # CC pic flag -KPIC is the default.
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      linux* | k*bsd*-gnu)
+	case $cc_basename in
+	  KCC*)
+	    # KAI C++ Compiler
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    ;;
+	  ecpc* )
+	    # old Intel C++ for x86_64 which still supported -KPIC.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  icpc* )
+	    # Intel C++, used to be incompatible with GCC.
+	    # ICC 10 doesn't accept -KPIC any more.
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fPIC'
+	    lt_prog_compiler_static_CXX='-static'
+	    ;;
+	  pgCC* | pgcpp*)
+	    # Portland Group C++ compiler
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-fpic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  cxx*)
+	    # Compaq C++
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  xlc* | xlC*)
+	    # IBM XL 8.0 on PPC
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-qpic'
+	    lt_prog_compiler_static_CXX='-qstaticlink'
+	    ;;
+	  *)
+	    case `$CC -V 2>&1 | sed 5q` in
+	    *Sun\ C*)
+	      # Sun C++ 5.9
+	      lt_prog_compiler_pic_CXX='-KPIC'
+	      lt_prog_compiler_static_CXX='-Bstatic'
+	      lt_prog_compiler_wl_CXX='-Qoption ld '
+	      ;;
+	    esac
+	    ;;
+	esac
+	;;
+      lynxos*)
+	;;
+      m88k*)
+	;;
+      mvs*)
+	case $cc_basename in
+	  cxx*)
+	    lt_prog_compiler_pic_CXX='-W c,exportall'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      netbsd*)
+	;;
+      *qnx* | *nto*)
+        # QNX uses GNU C++, but need to define -shared option too, otherwise
+        # it will coredump.
+        lt_prog_compiler_pic_CXX='-fPIC -shared'
+        ;;
+      osf3* | osf4* | osf5*)
+	case $cc_basename in
+	  KCC*)
+	    lt_prog_compiler_wl_CXX='--backend -Wl,'
+	    ;;
+	  RCC*)
+	    # Rational C++ 2.4.1
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  cxx*)
+	    # Digital/Compaq C++
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    # Make sure the PIC flag is empty.  It appears that all Alpha
+	    # Linux and Compaq Tru64 Unix objects are PIC.
+	    lt_prog_compiler_pic_CXX=
+	    lt_prog_compiler_static_CXX='-non_shared'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      psos*)
+	;;
+      solaris*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.2, 5.x and Centerline C++
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    lt_prog_compiler_wl_CXX='-Qoption ld '
+	    ;;
+	  gcx*)
+	    # Green Hills C++ Compiler
+	    lt_prog_compiler_pic_CXX='-PIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sunos4*)
+	case $cc_basename in
+	  CC*)
+	    # Sun C++ 4.x
+	    lt_prog_compiler_pic_CXX='-pic'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	  lcc*)
+	    # Lucid
+	    lt_prog_compiler_pic_CXX='-pic'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+	case $cc_basename in
+	  CC*)
+	    lt_prog_compiler_wl_CXX='-Wl,'
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    lt_prog_compiler_static_CXX='-Bstatic'
+	    ;;
+	esac
+	;;
+      tandem*)
+	case $cc_basename in
+	  NCC*)
+	    # NonStop-UX NCC 3.20
+	    lt_prog_compiler_pic_CXX='-KPIC'
+	    ;;
+	  *)
+	    ;;
+	esac
+	;;
+      vxworks*)
+	;;
+      *)
+	lt_prog_compiler_can_build_shared_CXX=no
+	;;
+    esac
+  fi
+
+case $host_os in
+  # For platforms which do not support PIC, -DPIC is meaningless:
+  *djgpp*)
+    lt_prog_compiler_pic_CXX=
+    ;;
+  *)
+    lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+    ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic_works_CXX=no
+   ac_outfile=conftest.$ac_objext
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+   lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   # The option is referenced via a variable to avoid confusing sed.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:14391: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>conftest.err)
+   ac_status=$?
+   cat conftest.err >&5
+   echo "$as_me:14395: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s "$ac_outfile"; then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings other than the usual output.
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+     if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_pic_works_CXX=yes
+     fi
+   fi
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+    case $lt_prog_compiler_pic_CXX in
+     "" | " "*) ;;
+     *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+     esac
+else
+    lt_prog_compiler_pic_CXX=
+     lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_static_works_CXX=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler_static_works_CXX=yes
+       fi
+     else
+       lt_cv_prog_compiler_static_works_CXX=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+    :
+else
+    lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:14490: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:14494: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_c_o_CXX=no
+   $RM -r conftest 2>/dev/null
+   mkdir conftest
+   cd conftest
+   mkdir out
+   echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+   lt_compiler_flag="-o out/conftest2.$ac_objext"
+   # Insert the option either (1) after the last *FLAGS variable, or
+   # (2) before a word containing "conftest.", or (3) at the end.
+   # Note that $ac_compile itself does not contain backslashes and begins
+   # with a dollar sign (not a hyphen), so the echo should work correctly.
+   lt_compile=`echo "$ac_compile" | $SED \
+   -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+   -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+   -e 's:$: $lt_compiler_flag:'`
+   (eval echo "\"\$as_me:14542: $lt_compile\"" >&5)
+   (eval "$lt_compile" 2>out/conftest.err)
+   ac_status=$?
+   cat out/conftest.err >&5
+   echo "$as_me:14546: \$? = $ac_status" >&5
+   if (exit $ac_status) && test -s out/conftest2.$ac_objext
+   then
+     # The compiler can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+     if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+       lt_cv_prog_compiler_c_o_CXX=yes
+     fi
+   fi
+   chmod u+w . 2>&5
+   $RM conftest*
+   # SGI C++ compiler will create directory out/ii_files/ for
+   # template instantiation
+   test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+   $RM out/* && rmdir out
+   cd ..
+   $RM -r conftest
+   $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+  # do not overwrite the value of need_locks provided by the user
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+  hard_links=yes
+  $RM conftest*
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  touch conftest.a
+  ln conftest.a conftest.b 2>&5 || hard_links=no
+  ln conftest.a conftest.b 2>/dev/null && hard_links=no
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+  if test "$hard_links" = no; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+    need_locks=warn
+  fi
+else
+  need_locks=no
+fi
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+  export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  case $host_os in
+  aix[4-9]*)
+    # If we're using GNU nm, then we don't want the "-C" option.
+    # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
+      export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    else
+      export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+    fi
+    ;;
+  pw32*)
+    export_symbols_cmds_CXX="$ltdll_cmds"
+  ;;
+  cygwin* | mingw* | cegcc*)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  *)
+    export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  ;;
+  esac
+  exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+  # Assume -lc should be added
+  archive_cmds_need_lc_CXX=yes
+
+  if test "$enable_shared" = yes && test "$GCC" = yes; then
+    case $archive_cmds_CXX in
+    *'~'*)
+      # FIXME: we may have to deal with multi-command sequences.
+      ;;
+    '$CC '*)
+      # Test whether the compiler implicitly links with -lc since on some
+      # systems, -lgcc has to come before -lc. If gcc already passes -lc
+      # to ld, don't add -lc before -lgcc.
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+      $RM conftest*
+      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+      if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } 2>conftest.err; then
+        soname=conftest
+        lib=conftest
+        libobjs=conftest.$ac_objext
+        deplibs=
+        wl=$lt_prog_compiler_wl_CXX
+	pic_flag=$lt_prog_compiler_pic_CXX
+        compiler_flags=-v
+        linker_flags=-v
+        verstring=
+        output_objdir=.
+        libname=conftest
+        lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+        allow_undefined_flag_CXX=
+        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+  (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+        then
+	  archive_cmds_need_lc_CXX=no
+        else
+	  archive_cmds_need_lc_CXX=yes
+        fi
+        allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+      else
+        cat conftest.err 1>&5
+      fi
+      $RM conftest*
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX" >&5
+$as_echo "$archive_cmds_need_lc_CXX" >&6; }
+      ;;
+    esac
+  fi
+  ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+  shlibpath_var=LIBPATH
+
+  # AIX 3 has no versioning support, so we append a major version to the name.
+  soname_spec='${libname}${release}${shared_ext}$major'
+  ;;
+
+aix[4-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  hardcode_into_libs=yes
+  if test "$host_cpu" = ia64; then
+    # AIX 5 supports IA64
+    library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+    shlibpath_var=LD_LIBRARY_PATH
+  else
+    # With GCC up to 2.95.x, collect2 would create an import file
+    # for dependence libraries.  The import file would start with
+    # the line `#! .'.  This would cause the generated library to
+    # depend on `.', always an invalid library.  This was fixed in
+    # development snapshots of GCC prior to 3.0.
+    case $host_os in
+      aix4 | aix4.[01] | aix4.[01].*)
+      if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+	   echo ' yes '
+	   echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+	:
+      else
+	can_build_shared=no
+      fi
+      ;;
+    esac
+    # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+    # soname into executable. Probably we can add versioning support to
+    # collect2, so additional links can be useful in future.
+    if test "$aix_use_runtimelinking" = yes; then
+      # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+      # instead of lib<name>.a to let people know that these are not
+      # typical AIX shared libraries.
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    else
+      # We preserve .a as extension for shared libraries through AIX4.2
+      # and later when we are not doing run time linking.
+      library_names_spec='${libname}${release}.a $libname.a'
+      soname_spec='${libname}${release}${shared_ext}$major'
+    fi
+    shlibpath_var=LIBPATH
+  fi
+  ;;
+
+amigaos*)
+  case $host_cpu in
+  powerpc)
+    # Since July 2007 AmigaOS4 officially supports .so libraries.
+    # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    ;;
+  m68k)
+    library_names_spec='$libname.ixlibrary $libname.a'
+    # Create ${libname}_ixlibrary.a entries in /sys/libs.
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    ;;
+  esac
+  ;;
+
+beos*)
+  library_names_spec='${libname}${shared_ext}'
+  dynamic_linker="$host_os ld.so"
+  shlibpath_var=LIBRARY_PATH
+  ;;
+
+bsdi[45]*)
+  version_type=linux
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+  sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+  # the default ld.so.conf also contains /usr/contrib/lib and
+  # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+  # libtool to hard-code these into programs
+  ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+  version_type=windows
+  shrext_cmds=".dll"
+  need_version=no
+  need_lib_prefix=no
+
+  case $GCC,$host_os in
+  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+    library_names_spec='$libname.dll.a'
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname~
+      chmod a+x \$dldir/$dlname~
+      if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+        eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+      fi'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+
+    case $host_os in
+    cygwin*)
+      # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+      soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+      ;;
+    mingw* | cegcc*)
+      # MinGW DLLs use traditional 'lib' prefix
+      soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH printed by
+        # mingw gcc, but we are running on Cygwin. Gcc prints its search
+        # path with ; separators, and with drive letters. We can handle the
+        # drive letters (cygwin fileutils understands them), so leave them,
+        # especially as we might pass files found there to a mingw objdump,
+        # which wouldn't understand a cygwinified path. Ahh.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      ;;
+    pw32*)
+      # pw32 DLLs use 'pw' prefix rather than 'lib'
+      library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+      ;;
+    esac
+    ;;
+
+  *)
+    library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    ;;
+  esac
+  dynamic_linker='Win32 ld.exe'
+  # FIXME: first we should search . and the directory the executable is in
+  shlibpath_var=PATH
+  ;;
+
+darwin* | rhapsody*)
+  dynamic_linker="$host_os dyld"
+  version_type=darwin
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+  soname_spec='${libname}${release}${major}$shared_ext'
+  shlibpath_overrides_runpath=yes
+  shlibpath_var=DYLD_LIBRARY_PATH
+  shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+  sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+  ;;
+
+dgux*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+freebsd1*)
+  dynamic_linker=no
+  ;;
+
+freebsd* | dragonfly*)
+  # DragonFly does not have aout.  When/if they implement a new
+  # versioning mechanism, adjust this.
+  if test -x /usr/bin/objformat; then
+    objformat=`/usr/bin/objformat`
+  else
+    case $host_os in
+    freebsd[123]*) objformat=aout ;;
+    *) objformat=elf ;;
+    esac
+  fi
+  version_type=freebsd-$objformat
+  case $version_type in
+    freebsd-elf*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+      need_version=no
+      need_lib_prefix=no
+      ;;
+    freebsd-*)
+      library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+      need_version=yes
+      ;;
+  esac
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_os in
+  freebsd2*)
+    shlibpath_overrides_runpath=yes
+    ;;
+  freebsd3.[01]* | freebsdelf3.[01]*)
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+  freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+    shlibpath_overrides_runpath=no
+    hardcode_into_libs=yes
+    ;;
+  *) # from 4.6 on, and DragonFly
+    shlibpath_overrides_runpath=yes
+    hardcode_into_libs=yes
+    ;;
+  esac
+  ;;
+
+gnu*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  hardcode_into_libs=yes
+  ;;
+
+hpux9* | hpux10* | hpux11*)
+  # Give a soname corresponding to the major version so that dld.sl refuses to
+  # link against other versions.
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  case $host_cpu in
+  ia64*)
+    shrext_cmds='.so'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.so"
+    shlibpath_var=LD_LIBRARY_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    if test "X$HPUX_IA64_MODE" = X32; then
+      sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+    else
+      sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+    fi
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  hppa*64*)
+    shrext_cmds='.sl'
+    hardcode_into_libs=yes
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+    shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+    sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+    ;;
+  *)
+    shrext_cmds='.sl'
+    dynamic_linker="$host_os dld.sl"
+    shlibpath_var=SHLIB_PATH
+    shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    ;;
+  esac
+  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  postinstall_cmds='chmod 555 $lib'
+  ;;
+
+interix[3-9]*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+irix5* | irix6* | nonstopux*)
+  case $host_os in
+    nonstopux*) version_type=nonstopux ;;
+    *)
+	if test "$lt_cv_prog_gnu_ld" = yes; then
+		version_type=linux
+	else
+		version_type=irix
+	fi ;;
+  esac
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+  case $host_os in
+  irix5* | nonstopux*)
+    libsuff= shlibsuff=
+    ;;
+  *)
+    case $LD in # libtool.m4 will add one of these switches to LD
+    *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+      libsuff= shlibsuff= libmagic=32-bit;;
+    *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+      libsuff=32 shlibsuff=N32 libmagic=N32;;
+    *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+      libsuff=64 shlibsuff=64 libmagic=64-bit;;
+    *) libsuff= shlibsuff= libmagic=never-match;;
+    esac
+    ;;
+  esac
+  shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+  shlibpath_overrides_runpath=no
+  sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+  sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+  hardcode_into_libs=yes
+  ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+  dynamic_linker=no
+  ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  # Some binutils ld are patched to set DT_RUNPATH
+  save_LDFLAGS=$LDFLAGS
+  save_libdir=$libdir
+  eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+       LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+  if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+  shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+  LDFLAGS=$save_LDFLAGS
+  libdir=$save_libdir
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  # Append ld.so.conf contents to the search path
+  if test -f /etc/ld.so.conf; then
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[	 ]*hwcap[	 ]/d;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+  fi
+
+  # We used to test for /lib/ld.so.1 and disable shared libraries on
+  # powerpc, because MkLinux only supported shared libraries with the
+  # GNU dynamic linker.  Since this was broken with cross compilers,
+  # most powerpc-linux boxes support dynamic linking these days and
+  # people can always --disable-shared, the test was removed, and we
+  # assume the GNU/Linux dynamic linker is in use.
+  dynamic_linker='GNU/Linux ld.so'
+  ;;
+
+netbsd*)
+  version_type=sunos
+  need_lib_prefix=no
+  need_version=no
+  if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+    finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+    dynamic_linker='NetBSD (a.out) ld.so'
+  else
+    library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+    soname_spec='${libname}${release}${shared_ext}$major'
+    dynamic_linker='NetBSD ld.elf_so'
+  fi
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  ;;
+
+newsos6)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  ;;
+
+*nto* | *qnx*)
+  version_type=qnx
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  dynamic_linker='ldqnx.so'
+  ;;
+
+openbsd*)
+  version_type=sunos
+  sys_lib_dlsearch_path_spec="/usr/lib"
+  need_lib_prefix=no
+  # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+  case $host_os in
+    openbsd3.3 | openbsd3.3.*)	need_version=yes ;;
+    *)				need_version=no  ;;
+  esac
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+    case $host_os in
+      openbsd2.[89] | openbsd2.[89].*)
+	shlibpath_overrides_runpath=no
+	;;
+      *)
+	shlibpath_overrides_runpath=yes
+	;;
+      esac
+  else
+    shlibpath_overrides_runpath=yes
+  fi
+  ;;
+
+os2*)
+  libname_spec='$name'
+  shrext_cmds=".dll"
+  need_lib_prefix=no
+  library_names_spec='$libname${shared_ext} $libname.a'
+  dynamic_linker='OS/2 ld.exe'
+  shlibpath_var=LIBPATH
+  ;;
+
+osf3* | osf4* | osf5*)
+  version_type=osf
+  need_lib_prefix=no
+  need_version=no
+  soname_spec='${libname}${release}${shared_ext}$major'
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+  sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+  ;;
+
+rdos*)
+  dynamic_linker=no
+  ;;
+
+solaris*)
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  # ldd complains unless libraries are executable
+  postinstall_cmds='chmod +x $lib'
+  ;;
+
+sunos4*)
+  version_type=sunos
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+  finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  if test "$with_gnu_ld" = yes; then
+    need_lib_prefix=no
+  fi
+  need_version=yes
+  ;;
+
+sysv4 | sysv4.3*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  case $host_vendor in
+    sni)
+      shlibpath_overrides_runpath=no
+      need_lib_prefix=no
+      runpath_var=LD_RUN_PATH
+      ;;
+    siemens)
+      need_lib_prefix=no
+      ;;
+    motorola)
+      need_lib_prefix=no
+      need_version=no
+      shlibpath_overrides_runpath=no
+      sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+      ;;
+  esac
+  ;;
+
+sysv4*MP*)
+  if test -d /usr/nec ;then
+    version_type=linux
+    library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+    soname_spec='$libname${shared_ext}.$major'
+    shlibpath_var=LD_LIBRARY_PATH
+  fi
+  ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+  version_type=freebsd-elf
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  hardcode_into_libs=yes
+  if test "$with_gnu_ld" = yes; then
+    sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+  else
+    sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+    case $host_os in
+      sco3.2v5*)
+        sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+	;;
+    esac
+  fi
+  sys_lib_dlsearch_path_spec='/usr/lib'
+  ;;
+
+tpf*)
+  # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
+  version_type=linux
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+uts4*)
+  version_type=linux
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LD_LIBRARY_PATH
+  ;;
+
+*)
+  dynamic_linker=no
+  ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+  variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+  sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+  sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+   test -n "$runpath_var_CXX" ||
+   test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+  # We can hardcode non-existent directories.
+  if test "$hardcode_direct_CXX" != no &&
+     # If the only mechanism to avoid hardcoding is shlibpath_var, we
+     # have to relink, otherwise we might link with an installed library
+     # when we should be linking with a yet-to-be-installed one
+     ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+     test "$hardcode_minus_L_CXX" != no; then
+    # Linking always hardcodes the temporary library directory.
+    hardcode_action_CXX=relink
+  else
+    # We can link without hardcoding, and we can hardcode nonexisting dirs.
+    hardcode_action_CXX=immediate
+  fi
+else
+  # We cannot hardcode anything, or else we can only hardcode existing
+  # directories.
+  hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+   test "$inherit_rpath_CXX" = yes; then
+  # Fast installation is not supported
+  enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+     test "$enable_shared" = no; then
+  # Fast installation is not necessary
+  enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+  fi # test -n "$compiler"
+
+  CC=$lt_save_CC
+  LDCXX=$LD
+  LD=$lt_save_LD
+  GCC=$lt_save_GCC
+  with_gnu_ld=$lt_save_with_gnu_ld
+  lt_cv_path_LDCXX=$lt_cv_path_LD
+  lt_cv_path_LD=$lt_save_path_LD
+  lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+  lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+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
+
+
+
+
+
+
+
+
+
+
+
+
+
+        ac_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+# Extract the first word of "bison", so it can be a program name with args.
+set dummy bison; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_YACC+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$YACC"; then
+  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_YACC="bison"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+YACC=$ac_cv_prog_YACC
+if test -n "$YACC"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
+$as_echo "$YACC" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <$ac_hdr>
+
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_ac_Header=yes"
+else
+  eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
+
+ac_header_dirent=$ac_hdr; break
+fi
+
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' dir; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if test "${ac_cv_search_opendir+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
+int
+main ()
+{
+return opendir ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' x; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_opendir+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_opendir+set}" = set; then :
+
+else
+  ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdc=yes
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      return 2;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+  ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if test "${ac_cv_header_sys_wait_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+int
+main ()
+{
+  int s;
+  wait (&s);
+  s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_sys_wait_h=yes
+else
+  ac_cv_header_sys_wait_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+if test $ac_cv_header_sys_wait_h = yes; then
+
+$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+
+fi
+
+for ac_header in fcntl.h malloc.h memory.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
+$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
+if test "${ac_cv_c_const+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+/* FIXME: Include the comments suggested by Paul. */
+#ifndef __cplusplus
+  /* Ultrix mips cc rejects this.  */
+  typedef int charset[2];
+  const charset cs;
+  /* SunOS 4.1.1 cc rejects this.  */
+  char const *const *pcpcc;
+  char **ppc;
+  /* NEC SVR4.0.2 mips cc rejects this.  */
+  struct point {int x, y;};
+  static struct point const zero = {0,0};
+  /* AIX XL C 1.02.0.0 rejects this.
+     It does not let you subtract one const X* pointer from another in
+     an arm of an if-expression whose if-part is not a constant
+     expression */
+  const char *g = "string";
+  pcpcc = &g + (g ? g-g : 0);
+  /* HPUX 7.0 cc rejects these. */
+  ++pcpcc;
+  ppc = (char**) pcpcc;
+  pcpcc = (char const *const *) ppc;
+  { /* SCO 3.2v4 cc rejects this.  */
+    char *t;
+    char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+    *t++ = 0;
+    if (s) return 0;
+  }
+  { /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+    int x[] = {25, 17};
+    const int *foo = &x[0];
+    ++foo;
+  }
+  { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+    typedef const int *iptr;
+    iptr p = 0;
+    ++p;
+  }
+  { /* AIX XL C 1.02.0.0 rejects this saying
+       "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+    struct s { int j; const int *ap[3]; };
+    struct s *b; b->j = 5;
+  }
+  { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+    const int foo = 10;
+    if (!foo) return 0;
+  }
+  return !cs[0] && !zero.x;
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_const=yes
+else
+  ac_cv_c_const=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
+$as_echo "$ac_cv_c_const" >&6; }
+if test $ac_cv_c_const = no; then
+
+$as_echo "#define const /**/" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if test "${ac_cv_c_inline+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __cplusplus
+typedef int foo_t;
+static $ac_kw foo_t static_foo () {return 0; }
+$ac_kw foo_t foo () {return 0; }
+#endif
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_inline=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  test "$ac_cv_c_inline" != no && break
+done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
+
+case $ac_cv_c_inline in
+  inline | yes) ;;
+  *)
+    case $ac_cv_c_inline in
+      no) ac_val=;;
+      *) ac_val=$ac_cv_c_inline;;
+    esac
+    cat >>confdefs.h <<_ACEOF
+#ifndef __cplusplus
+#define inline $ac_val
+#endif
+_ACEOF
+    ;;
+esac
+
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = x""yes; then :
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define size_t unsigned int
+_ACEOF
+
+fi
+
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blksize" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+_ACEOF
+
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if test "${ac_cv_header_time+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+
+int
+main ()
+{
+if ((struct tm *) 0)
+return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_time=yes
+else
+  ac_cv_header_time=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
+if test $ac_cv_header_time = yes; then
+
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether struct tm is in sys/time.h or time.h" >&5
+$as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
+if test "${ac_cv_struct_tm+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <time.h>
+
+int
+main ()
+{
+struct tm tm;
+				     int *p = &tm.tm_sec;
+				     return !p;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_struct_tm=time.h
+else
+  ac_cv_struct_tm=sys/time.h
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_struct_tm" >&5
+$as_echo "$ac_cv_struct_tm" >&6; }
+if test $ac_cv_struct_tm = sys/time.h; then
+
+$as_echo "#define TM_IN_SYS_TIME 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working volatile" >&5
+$as_echo_n "checking for working volatile... " >&6; }
+if test "${ac_cv_c_volatile+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+volatile int x;
+int * volatile y = (int *) 0;
+return !x && !y;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_volatile=yes
+else
+  ac_cv_c_volatile=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_volatile" >&5
+$as_echo "$ac_cv_c_volatile" >&6; }
+if test $ac_cv_c_volatile = no; then
+
+$as_echo "#define volatile /**/" >>confdefs.h
+
+fi
+
+    # Ignore the errors about AC_TRY_RUN missing an argument. jhrg 5/2/95
+
+
+
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5
+$as_echo_n "checking size of int... " >&6; }
+if test "${ac_cv_sizeof_int+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_int" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_int=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5
+$as_echo "$ac_cv_sizeof_int" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+_ACEOF
+
+
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5
+$as_echo_n "checking size of long... " >&6; }
+if test "${ac_cv_sizeof_long+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_long" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (long)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_long=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5
+$as_echo "$ac_cv_sizeof_long" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+_ACEOF
+
+
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5
+$as_echo_n "checking size of char... " >&6; }
+if test "${ac_cv_sizeof_char+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_char" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (char)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_char=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5
+$as_echo "$ac_cv_sizeof_char" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+_ACEOF
+
+
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of double" >&5
+$as_echo_n "checking size of double... " >&6; }
+if test "${ac_cv_sizeof_double+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (double))" "ac_cv_sizeof_double"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_double" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (double)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_double=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_double" >&5
+$as_echo "$ac_cv_sizeof_double" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+_ACEOF
+
+
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of float" >&5
+$as_echo_n "checking size of float... " >&6; }
+if test "${ac_cv_sizeof_float+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (float))" "ac_cv_sizeof_float"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_float" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (float)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_float=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_float" >&5
+$as_echo "$ac_cv_sizeof_float" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_FLOAT $ac_cv_sizeof_float
+_ACEOF
+
+
+
+    # check for C99 types, headers and functions
+    ac_fn_c_check_header_mongrel "$LINENO" "inttypes.h" "ac_cv_header_inttypes_h" "$ac_includes_default"
+if test "x$ac_cv_header_inttypes_h" = x""yes; then :
+  dap_inttypes_header=yes
+fi
+
+
+    # DINT32 4
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int32_t" >&5
+$as_echo_n "checking size of int32_t... " >&6; }
+if test "${ac_cv_sizeof_int32_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int32_t))" "ac_cv_sizeof_int32_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_int32_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int32_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_int32_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int32_t" >&5
+$as_echo "$ac_cv_sizeof_int32_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT32_T $ac_cv_sizeof_int32_t
+_ACEOF
+
+
+    # DUINT32
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint32_t" >&5
+$as_echo_n "checking size of uint32_t... " >&6; }
+if test "${ac_cv_sizeof_uint32_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint32_t))" "ac_cv_sizeof_uint32_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_uint32_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (uint32_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_uint32_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint32_t" >&5
+$as_echo "$ac_cv_sizeof_uint32_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UINT32_T $ac_cv_sizeof_uint32_t
+_ACEOF
+
+
+    # DINT16 short
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int16_t" >&5
+$as_echo_n "checking size of int16_t... " >&6; }
+if test "${ac_cv_sizeof_int16_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int16_t))" "ac_cv_sizeof_int16_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_int16_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (int16_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_int16_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int16_t" >&5
+$as_echo "$ac_cv_sizeof_int16_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_INT16_T $ac_cv_sizeof_int16_t
+_ACEOF
+
+
+    # DUINT16 unsigned short
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint16_t" >&5
+$as_echo_n "checking size of uint16_t... " >&6; }
+if test "${ac_cv_sizeof_uint16_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint16_t))" "ac_cv_sizeof_uint16_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_uint16_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (uint16_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_uint16_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint16_t" >&5
+$as_echo "$ac_cv_sizeof_uint16_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UINT16_T $ac_cv_sizeof_uint16_t
+_ACEOF
+
+
+    # DBYTE 1
+    # The cast to long int works around a bug in the HP C Compiler
+# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
+# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
+# This bug is HP SR number 8606223364.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of uint8_t" >&5
+$as_echo_n "checking size of uint8_t... " >&6; }
+if test "${ac_cv_sizeof_uint8_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (uint8_t))" "ac_cv_sizeof_uint8_t"        "$ac_includes_default"; then :
+
+else
+  if test "$ac_cv_type_uint8_t" = yes; then
+     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "cannot compute sizeof (uint8_t)
+See \`config.log' for more details." "$LINENO" 5; }; }
+   else
+     ac_cv_sizeof_uint8_t=0
+   fi
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_uint8_t" >&5
+$as_echo "$ac_cv_sizeof_uint8_t" >&6; }
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define SIZEOF_UINT8_T $ac_cv_sizeof_uint8_t
+_ACEOF
+
+
+    if test x"$dap_inttypes_header" = x'yes' -a $ac_cv_sizeof_int32_t -eq 4 -a $ac_cv_sizeof_int16_t -eq 2 -a $ac_cv_sizeof_uint8_t -eq 1 -a $ac_cv_sizeof_double -eq 8; then
+        dap_use_c99_types=yes
+    fi
+     if test x"$dap_use_c99_types" = 'xyes'; then
+  USE_C99_TYPES_TRUE=
+  USE_C99_TYPES_FALSE='#'
+else
+  USE_C99_TYPES_TRUE='#'
+  USE_C99_TYPES_FALSE=
+fi
+
+
+    # I've separated the typedefs from the config.h header because other
+    # projects which use the DAP were getting conflicts with their includes,
+    # or the includes of still other libraries, and config.h. The
+    # config.h header is now included only by .cc and .c files and headers
+    # that need the typedefs use dods-datatypes.h.
+    # there are 2 possibilities for the definition of dods_int32, ...,
+    # types. First possibility is that the C99 types are used and
+    # dods-datatypes-static.h is copied. In that case the following
+    # definitions are not really usefull. In case the C99 types are
+    # not available, dods-datatypes-config.h.in is used to generate
+    # dods-datatypes.h.
+    # The code below makes dods-datatypes-config.h stand on its own.
+    # 8/2/2000 jhrg
+
+    # DMH: Divide into two sets of tests: one for DODS and one for XDR
+    if test x"$dap_use_c99_types" = 'xyes'; then
+        DODS_INT32=int32_t
+        DODS_UINT32=uint32_t
+        DODS_INT16=int16_t
+        DODS_UINT16=uint16_t
+        DODS_BYTE=uint8_t
+    else
+        DODS_INT16=short
+        DODS_UINT16="unsigned short"
+	DODS_INT32=int
+	DODS_UINT32="unsigned int"
+	DODS_BYTE="unsigned char"
+    fi
+    DODS_FLOAT64=double
+    DODS_FLOAT32=float
+
+    # I'm using the three arg form of AC_DEFINE_UNQUOTED because autoheader
+    # needs the third argument (although I don't quite get the specifics...
+    # 2/15/2001 jhrg
+
+cat >>confdefs.h <<_ACEOF
+#define DINT32 $DODS_INT32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DUINT32 $DODS_UINT32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DINT16 $DODS_INT16
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DUINT16 $DODS_UINT16
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DFLOAT64 $DODS_FLOAT64
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DFLOAT32 $DODS_FLOAT32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define DBYTE $DODS_BYTE
+_ACEOF
+
+
+    # XDR INTEGER TYPES
+    # Unfortunately, there is little commonality about xdr
+
+    # First, we need to see if the xdr routines are in libc, librpc,
+    # or librpcsvc or libnsl
+    dap_xdrlib=
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing xdr_void" >&5
+$as_echo_n "checking for library containing xdr_void... " >&6; }
+if test "${ac_cv_search_xdr_void+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdr_void ();
+int
+main ()
+{
+return xdr_void ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' c rpc nsl rpcsvc; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_xdr_void=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if test "${ac_cv_search_xdr_void+set}" = set; then :
+  break
+fi
+done
+if test "${ac_cv_search_xdr_void+set}" = set; then :
+
+else
+  ac_cv_search_xdr_void=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_xdr_void" >&5
+$as_echo "$ac_cv_search_xdr_void" >&6; }
+ac_res=$ac_cv_search_xdr_void
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+      dap_xdrlib=`echo $ac_res|sed -e 's/^-l//'`
+else
+
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Cannot locate library containing xdr functions." >&5
+$as_echo "$as_me: WARNING: Cannot locate library containing xdr functions." >&2;}
+fi
+
+    # Added for autoconf 2.59 which appears to not use/set $ac_res. jhrg
+    if test -z "$dap_xdrlib" ; then dap_xdrlib=c; fi
+    if test "$dap_xdrlib" = "none required" ; then dap_xdrlib=c; fi
+    # I don't think this is needed for autoconf 2.61 but I have no idea about
+    # 2.59 - it doesn't seem to be hurting anything with 2.61. jhrg
+    if test "$dap_xdrlib" != "c" ; then
+       # Add to library list
+       as_ac_Lib=`$as_echo "ac_cv_lib_$dap_xdrlib''_xdr_void" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdr_void in -l$dap_xdrlib" >&5
+$as_echo_n "checking for xdr_void in -l$dap_xdrlib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$dap_xdrlib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdr_void ();
+int
+main ()
+{
+return xdr_void ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_LIB$dap_xdrlib" | $as_tr_cpp` 1
+_ACEOF
+
+  LIBS="-l$dap_xdrlib $LIBS"
+
+fi
+
+    fi
+    # Now figure out what integer functions to use
+    dap_xdrint=0
+    as_ac_Lib=`$as_echo "ac_cv_lib_$dap_xdrlib''_xdr_uint32_t" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdr_uint32_t in -l$dap_xdrlib" >&5
+$as_echo_n "checking for xdr_uint32_t in -l$dap_xdrlib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$dap_xdrlib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdr_uint32_t ();
+int
+main ()
+{
+return xdr_uint32_t ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  dap_xdrint=1
+else
+
+      as_ac_Lib=`$as_echo "ac_cv_lib_$dap_xdrlib''_xdr_u_int32_t" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdr_u_int32_t in -l$dap_xdrlib" >&5
+$as_echo_n "checking for xdr_u_int32_t in -l$dap_xdrlib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$dap_xdrlib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdr_u_int32_t ();
+int
+main ()
+{
+return xdr_u_int32_t ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  dap_xdrint=2
+else
+
+        as_ac_Lib=`$as_echo "ac_cv_lib_$dap_xdrlib''_xdr_uint" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdr_uint in -l$dap_xdrlib" >&5
+$as_echo_n "checking for xdr_uint in -l$dap_xdrlib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$dap_xdrlib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdr_uint ();
+int
+main ()
+{
+return xdr_uint ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  dap_xdrint=3
+else
+
+          as_ac_Lib=`$as_echo "ac_cv_lib_$dap_xdrlib''_xdr_u_int" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for xdr_u_int in -l$dap_xdrlib" >&5
+$as_echo_n "checking for xdr_u_int in -l$dap_xdrlib... " >&6; }
+if { as_var=$as_ac_Lib; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-l$dap_xdrlib  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char xdr_u_int ();
+int
+main ()
+{
+return xdr_u_int ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  eval "$as_ac_Lib=yes"
+else
+  eval "$as_ac_Lib=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+eval ac_res=\$$as_ac_Lib
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+eval as_val=\$$as_ac_Lib
+   if test "x$as_val" = x""yes; then :
+  dap_xdrint=4
+fi
+
+fi
+
+fi
+
+fi
+
+    case "$dap_xdrint" in
+    1) # uint32_t
+	XDR_INT32=xdr_int32_t
+	XDR_UINT32=xdr_uint32_t
+        XDR_INT16=xdr_int16_t
+        XDR_UINT16=xdr_uint16_t
+        ;;
+    2) # u_int32_t
+	XDR_INT32=xdr_int32_t
+	XDR_UINT32=xdr_u_int32_t
+        XDR_INT16=xdr_int16_t
+        XDR_UINT16=xdr_u_int16_t
+        ;;
+    3) # uint
+	XDR_INT32=xdr_int
+	XDR_UINT32=xdr_uint
+        XDR_INT16=xdr_short
+        XDR_UINT16=xdr_ushort
+        ;;
+    4) # u_int
+	XDR_INT32=xdr_int
+	XDR_UINT32=xdr_u_int
+        XDR_INT16=xdr_short
+        XDR_UINT16=xdr_u_short
+        ;;
+    *)
+	as_fn_error "Cannot determine DODS XDR integer sizes" "$LINENO" 5
+        ;;
+    esac
+    XDR_FLOAT64=xdr_double
+    XDR_FLOAT32=xdr_float
+
+
+cat >>confdefs.h <<_ACEOF
+#define XDR_INT16 $XDR_INT16
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XDR_UINT16 $XDR_UINT16
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XDR_INT32 $XDR_INT32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XDR_UINT32 $XDR_UINT32
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XDR_FLOAT64 $XDR_FLOAT64
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define XDR_FLOAT32 $XDR_FLOAT32
+_ACEOF
+
+
+if test "$CC" = "gcc"
+then
+     if true; then
+  COMPILER_IS_GCC_TRUE=
+  COMPILER_IS_GCC_FALSE='#'
+else
+  COMPILER_IS_GCC_TRUE='#'
+  COMPILER_IS_GCC_FALSE=
+fi
+
+else
+     if false; then
+  COMPILER_IS_GCC_TRUE=
+  COMPILER_IS_GCC_FALSE='#'
+else
+  COMPILER_IS_GCC_TRUE='#'
+  COMPILER_IS_GCC_FALSE=
+fi
+
+fi
+
+# Checks for library functions.
+
+# These, at least some of them, cannot be used along with gnulib without
+# breaking stuff. Since we are not bothering to handle the cases where these
+# functions break, there's not much point in testing for them. However, it
+# might be a good thing to use the gnulib versions since those fix various
+# common problems found in many distributions.
+
+
+for ac_func in alarm atexit bzero dup2 getcwd getpagesize localtime_r memmove memset pow putenv setenv strchr strerror strtol strtoul timegm mktime
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+
+
+
+
+
+
+          LIBC_FATAL_STDERR_=1
+  export LIBC_FATAL_STDERR_
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments.  Useless!
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
+$as_echo_n "checking for working alloca.h... " >&6; }
+if test "${ac_cv_working_alloca_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <alloca.h>
+int
+main ()
+{
+char *p = (char *) alloca (2 * sizeof (int));
+			  if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_working_alloca_h=yes
+else
+  ac_cv_working_alloca_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_working_alloca_h" >&5
+$as_echo "$ac_cv_working_alloca_h" >&6; }
+if test $ac_cv_working_alloca_h = yes; then
+
+$as_echo "#define HAVE_ALLOCA_H 1" >>confdefs.h
+
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca" >&5
+$as_echo_n "checking for alloca... " >&6; }
+if test "${ac_cv_func_alloca_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# ifdef _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# else
+#  ifdef HAVE_ALLOCA_H
+#   include <alloca.h>
+#  else
+#   ifdef _AIX
+ #pragma alloca
+#   else
+#    ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+int
+main ()
+{
+char *p = (char *) alloca (1);
+				    if (p) return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_func_alloca_works=yes
+else
+  ac_cv_func_alloca_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_alloca_works" >&5
+$as_echo "$ac_cv_func_alloca_works" >&6; }
+
+if test $ac_cv_func_alloca_works = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+else
+  # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+# that cause trouble.  Some versions do not even contain alloca or
+# contain a buggy version.  If you still want to use their alloca,
+# use ar to extract alloca.o from them instead of compiling alloca.c.
+
+
+
+
+
+ALLOCA=\${LIBOBJDIR}alloca.$ac_objext
+
+$as_echo "#define C_ALLOCA 1" >>confdefs.h
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether \`alloca.c' needs Cray hooks" >&5
+$as_echo_n "checking whether \`alloca.c' needs Cray hooks... " >&6; }
+if test "${ac_cv_os_cray+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined CRAY && ! defined CRAY2
+webecray
+#else
+wenotbecray
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "webecray" >/dev/null 2>&1; then :
+  ac_cv_os_cray=yes
+else
+  ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_os_cray" >&5
+$as_echo "$ac_cv_os_cray" >&6; }
+if test $ac_cv_os_cray = yes; then
+  for ac_func in _getb67 GETB67 getb67; do
+    as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define CRAY_STACKSEG_END $ac_func
+_ACEOF
+
+    break
+fi
+
+  done
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking stack direction for C alloca" >&5
+$as_echo_n "checking stack direction for C alloca... " >&6; }
+if test "${ac_cv_c_stack_direction+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_c_stack_direction=0
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+find_stack_direction ()
+{
+  static char *addr = 0;
+  auto char dummy;
+  if (addr == 0)
+    {
+      addr = &dummy;
+      return find_stack_direction ();
+    }
+  else
+    return (&dummy > addr) ? 1 : -1;
+}
+
+int
+main ()
+{
+  return find_stack_direction () < 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_c_stack_direction=1
+else
+  ac_cv_c_stack_direction=-1
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_stack_direction" >&5
+$as_echo "$ac_cv_c_stack_direction" >&6; }
+cat >>confdefs.h <<_ACEOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+_ACEOF
+
+
+fi
+
+
+  GNULIB_BTOWC=0;
+  GNULIB_WCTOB=0;
+  GNULIB_MBSINIT=0;
+  GNULIB_MBRTOWC=0;
+  GNULIB_MBRLEN=0;
+  GNULIB_MBSRTOWCS=0;
+  GNULIB_MBSNRTOWCS=0;
+  GNULIB_WCRTOMB=0;
+  GNULIB_WCSRTOMBS=0;
+  GNULIB_WCSNRTOMBS=0;
+  GNULIB_WCWIDTH=0;
+    HAVE_BTOWC=1;
+  HAVE_MBSINIT=1;
+  HAVE_MBRTOWC=1;
+  HAVE_MBRLEN=1;
+  HAVE_MBSRTOWCS=1;
+  HAVE_MBSNRTOWCS=1;
+  HAVE_WCRTOMB=1;
+  HAVE_WCSRTOMBS=1;
+  HAVE_WCSNRTOMBS=1;
+  HAVE_DECL_WCTOB=1;
+  HAVE_DECL_WCWIDTH=1;
+  REPLACE_MBSTATE_T=0;
+  REPLACE_BTOWC=0;
+  REPLACE_WCTOB=0;
+  REPLACE_MBSINIT=0;
+  REPLACE_MBRTOWC=0;
+  REPLACE_MBRLEN=0;
+  REPLACE_MBSRTOWCS=0;
+  REPLACE_MBSNRTOWCS=0;
+  REPLACE_WCRTOMB=0;
+  REPLACE_WCSRTOMBS=0;
+  REPLACE_WCSNRTOMBS=0;
+  REPLACE_WCWIDTH=0;
+
+
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether <wchar.h> uses 'inline' correctly" >&5
+$as_echo_n "checking whether <wchar.h> uses 'inline' correctly... " >&6; }
+if test "${gl_cv_header_wchar_h_correct_inline+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gl_cv_header_wchar_h_correct_inline=yes
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+       #define wcstod renamed_wcstod
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+extern int zero (void);
+int main () { return zero(); }
+
+_ACEOF
+     if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+       mv conftest.$ac_objext conftest1.$ac_objext
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+         #define wcstod renamed_wcstod
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int zero (void) { return 0; }
+
+_ACEOF
+       if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+         mv conftest.$ac_objext conftest2.$ac_objext
+         if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&5 2>&1; then
+           :
+         else
+           gl_cv_header_wchar_h_correct_inline=no
+         fi
+       fi
+     fi
+     rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_wchar_h_correct_inline" >&5
+$as_echo "$gl_cv_header_wchar_h_correct_inline" >&6; }
+  if test $gl_cv_header_wchar_h_correct_inline = no; then
+    as_fn_error "<wchar.h> cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS).
+This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in
+C99 mode. You have four options:
+  - Add the flag -fgnu89-inline to CC and reconfigure, or
+  - Fix your include files, using parts of
+    <http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b037a293a48718af30d706c2e18c929d0e69a621>, or
+  - Use a gcc version older than 4.3, or
+  - Don't use the flags -std=c99 or -std=gnu99.
+Configuration aborted." "$LINENO" 5
+  fi
+
+
+
+
+  for ac_func in $ac_func_list
+do :
+  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+eval as_val=\$$as_ac_var
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nl_langinfo and CODESET" >&5
+$as_echo_n "checking for nl_langinfo and CODESET... " >&6; }
+if test "${am_cv_langinfo_codeset+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int
+main ()
+{
+char* cs = nl_langinfo(CODESET); return !cs;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  am_cv_langinfo_codeset=yes
+else
+  am_cv_langinfo_codeset=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_langinfo_codeset" >&5
+$as_echo "$am_cv_langinfo_codeset" >&6; }
+  if test $am_cv_langinfo_codeset = yes; then
+
+$as_echo "#define HAVE_LANGINFO_CODESET 1" >>confdefs.h
+
+  fi
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a traditional french locale" >&5
+$as_echo_n "checking for a traditional french locale... " >&6; }
+if test "${gt_cv_locale_fr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main () {
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.
+     On MirBSD 10, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "UTF-8".  */
+#if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0
+        || strcmp (cs, "UTF-8") == 0)
+      return 1;
+  }
+#endif
+#ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+#endif
+  /* Check whether in the abbreviation of the second month, the second
+     character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is only
+     one byte long. This excludes the UTF-8 encoding.  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1;
+  /* Check whether the decimal separator is a comma.
+     On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point
+     are nl_langinfo(RADIXCHAR) are both ".".  */
+  if (localeconv () ->decimal_point[0] != ',') return 1;
+  return 0;
+}
+
+_ACEOF
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the usual locale name.
+      if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_fr=fr_FR
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_fr=fr_FR.ISO-8859-1
+        else
+          # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name.
+          if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+            gt_cv_locale_fr=fr_FR.ISO8859-1
+          else
+            # Test for the HP-UX locale name.
+            if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+              gt_cv_locale_fr=fr_FR.iso88591
+            else
+              # Test for the Solaris 7 locale name.
+              if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+                gt_cv_locale_fr=fr
+              else
+                # None found.
+                gt_cv_locale_fr=none
+              fi
+            fi
+          fi
+        fi
+      fi
+    fi
+    rm -fr conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_locale_fr" >&5
+$as_echo "$gt_cv_locale_fr" >&6; }
+  LOCALE_FR=$gt_cv_locale_fr
+
+
+
+  GNULIB_NL_LANGINFO=0;
+    HAVE_NL_LANGINFO=1;
+  REPLACE_NL_LANGINFO=0;
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the preprocessor supports include_next" >&5
+$as_echo_n "checking whether the preprocessor supports include_next... " >&6; }
+if test "${gl_cv_have_include_next+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  rm -rf conftestd1a conftestd1b conftestd2
+     mkdir conftestd1a conftestd1b conftestd2
+                                                  cat <<EOF > conftestd1a/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+     cat <<EOF > conftestd1b/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include <stdio.h>
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+     cat <<EOF > conftestd2/conftest.h
+#ifndef DEFINED_IN_CONFTESTD1
+#error "include_next test doesn't work"
+#endif
+#define DEFINED_IN_CONFTESTD2
+EOF
+     gl_save_CPPFLAGS="$CPPFLAGS"
+     CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2"
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <conftest.h>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_have_include_next=yes
+else
+  CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2"
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <conftest.h>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_have_include_next=buggy
+else
+  gl_cv_have_include_next=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+     CPPFLAGS="$gl_save_CPPFLAGS"
+     rm -rf conftestd1a conftestd1b conftestd2
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_have_include_next" >&5
+$as_echo "$gl_cv_have_include_next" >&6; }
+  PRAGMA_SYSTEM_HEADER=
+  if test $gl_cv_have_include_next = yes; then
+    INCLUDE_NEXT=include_next
+    INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+    if test -n "$GCC"; then
+      PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'
+    fi
+  else
+    if test $gl_cv_have_include_next = buggy; then
+      INCLUDE_NEXT=include
+      INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+    else
+      INCLUDE_NEXT=include
+      INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include
+    fi
+  fi
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether system header files limit the line length" >&5
+$as_echo_n "checking whether system header files limit the line length... " >&6; }
+if test "${gl_cv_pragma_columns+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifdef __TANDEM
+choke me
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "choke me" >/dev/null 2>&1; then :
+  gl_cv_pragma_columns=yes
+else
+  gl_cv_pragma_columns=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_pragma_columns" >&5
+$as_echo "$gl_cv_pragma_columns" >&6; }
+  if test $gl_cv_pragma_columns = yes; then
+    PRAGMA_COLUMNS="#pragma COLUMNS 10000"
+  else
+    PRAGMA_COLUMNS=
+  fi
+
+
+
+
+
+  for ac_header in $ac_header_list
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fcntl.h" >&5
+$as_echo_n "checking for working fcntl.h... " >&6; }
+if test "${gl_cv_header_working_fcntl_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  gl_cv_header_working_fcntl_h=cross-compiling
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+           #include <sys/stat.h>
+           #include <unistd.h>
+           #include <fcntl.h>
+           #ifndef O_NOATIME
+            #define O_NOATIME 0
+           #endif
+           #ifndef O_NOFOLLOW
+            #define O_NOFOLLOW 0
+           #endif
+           static int const constants[] =
+            {
+              O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
+              O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
+            };
+
+int
+main ()
+{
+
+            int result = !constants;
+            {
+              static char const sym[] = "conftest.sym";
+              if (symlink (".", sym) != 0)
+                result |= 2;
+              else
+                {
+                  int fd = open (sym, O_RDONLY | O_NOFOLLOW);
+                  if (fd >= 0)
+                    {
+                      close (fd);
+                      result |= 4;
+                    }
+                }
+              unlink (sym);
+            }
+            {
+              static char const file[] = "confdefs.h";
+              int fd = open (file, O_RDONLY | O_NOATIME);
+              if (fd < 0)
+                result |= 8;
+              else
+                {
+                  struct stat st0;
+                  if (fstat (fd, &st0) != 0)
+                    result |= 16;
+                  else
+                    {
+                      char c;
+                      sleep (1);
+                      if (read (fd, &c, 1) != 1)
+                        result |= 24;
+                      else
+                        {
+                          if (close (fd) != 0)
+                            result |= 32;
+                          else
+                            {
+                              struct stat st1;
+                              if (stat (file, &st1) != 0)
+                                result |= 40;
+                              else
+                                if (st0.st_atime != st1.st_atime)
+                                  result |= 64;
+                            }
+                        }
+                    }
+                }
+            }
+            return result;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_header_working_fcntl_h=yes
+else
+  case $? in #(
+        4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
+        64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
+        68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
+         *) gl_cv_header_working_fcntl_h='no';;
+        esac
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_fcntl_h" >&5
+$as_echo "$gl_cv_header_working_fcntl_h" >&6; }
+
+  case $gl_cv_header_working_fcntl_h in #(
+  *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
+  *) ac_val=1;;
+  esac
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_WORKING_O_NOATIME $ac_val
+_ACEOF
+
+
+  case $gl_cv_header_working_fcntl_h in #(
+  *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
+  *) ac_val=1;;
+  esac
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_WORKING_O_NOFOLLOW $ac_val
+_ACEOF
+
+
+ac_fn_c_check_decl "$LINENO" "getc_unlocked" "ac_cv_have_decl_getc_unlocked" "$ac_includes_default"
+if test "x$ac_cv_have_decl_getc_unlocked" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_GETC_UNLOCKED $ac_have_decl
+_ACEOF
+
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C Library >= 2.1 or uClibc" >&5
+$as_echo_n "checking whether we are using the GNU C Library >= 2.1 or uClibc... " >&6; }
+if test "${ac_cv_gnu_library_2_1+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
+  Lucky GNU user
+ #endif
+#endif
+#ifdef __UCLIBC__
+ Lucky user
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "Lucky" >/dev/null 2>&1; then :
+  ac_cv_gnu_library_2_1=yes
+else
+  ac_cv_gnu_library_2_1=no
+fi
+rm -f conftest*
+
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_gnu_library_2_1" >&5
+$as_echo "$ac_cv_gnu_library_2_1" >&6; }
+
+    GLIBC21="$ac_cv_gnu_library_2_1"
+
+
+
+  GNULIB__EXIT=0;
+  GNULIB_ATOLL=0;
+  GNULIB_CALLOC_POSIX=0;
+  GNULIB_CANONICALIZE_FILE_NAME=0;
+  GNULIB_GETLOADAVG=0;
+  GNULIB_GETSUBOPT=0;
+  GNULIB_GRANTPT=0;
+  GNULIB_MALLOC_POSIX=0;
+  GNULIB_MKDTEMP=0;
+  GNULIB_MKOSTEMP=0;
+  GNULIB_MKOSTEMPS=0;
+  GNULIB_MKSTEMP=0;
+  GNULIB_MKSTEMPS=0;
+  GNULIB_PTSNAME=0;
+  GNULIB_PUTENV=0;
+  GNULIB_RANDOM_R=0;
+  GNULIB_REALLOC_POSIX=0;
+  GNULIB_REALPATH=0;
+  GNULIB_RPMATCH=0;
+  GNULIB_SETENV=0;
+  GNULIB_STRTOD=0;
+  GNULIB_STRTOLL=0;
+  GNULIB_STRTOULL=0;
+  GNULIB_SYSTEM_POSIX=0;
+  GNULIB_UNLOCKPT=0;
+  GNULIB_UNSETENV=0;
+    HAVE__EXIT=1;
+  HAVE_ATOLL=1;
+  HAVE_CANONICALIZE_FILE_NAME=1;
+  HAVE_DECL_GETLOADAVG=1;
+  HAVE_GETSUBOPT=1;
+  HAVE_GRANTPT=1;
+  HAVE_MKDTEMP=1;
+  HAVE_MKOSTEMP=1;
+  HAVE_MKOSTEMPS=1;
+  HAVE_MKSTEMP=1;
+  HAVE_MKSTEMPS=1;
+  HAVE_PTSNAME=1;
+  HAVE_RANDOM_R=1;
+  HAVE_REALPATH=1;
+  HAVE_RPMATCH=1;
+  HAVE_SETENV=1;
+  HAVE_DECL_SETENV=1;
+  HAVE_STRTOD=1;
+  HAVE_STRTOLL=1;
+  HAVE_STRTOULL=1;
+  HAVE_STRUCT_RANDOM_DATA=1;
+  HAVE_SYS_LOADAVG_H=0;
+  HAVE_UNLOCKPT=1;
+  HAVE_DECL_UNSETENV=1;
+  REPLACE_CALLOC=0;
+  REPLACE_CANONICALIZE_FILE_NAME=0;
+  REPLACE_MALLOC=0;
+  REPLACE_MKSTEMP=0;
+  REPLACE_PUTENV=0;
+  REPLACE_REALLOC=0;
+  REPLACE_REALPATH=0;
+  REPLACE_SETENV=0;
+  REPLACE_STRTOD=0;
+  REPLACE_UNSETENV=0;
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether malloc, realloc, calloc are POSIX compliant" >&5
+$as_echo_n "checking whether malloc, realloc, calloc are POSIX compliant... " >&6; }
+if test "${gl_cv_func_malloc_posix+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+             choke me
+             #endif
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_func_malloc_posix=yes
+else
+  gl_cv_func_malloc_posix=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_malloc_posix" >&5
+$as_echo "$gl_cv_func_malloc_posix" >&6; }
+
+
+
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mbstate_t" >&5
+$as_echo_n "checking for mbstate_t... " >&6; }
+if test "${ac_cv_type_mbstate_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int
+main ()
+{
+mbstate_t x; return sizeof x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_type_mbstate_t=yes
+else
+  ac_cv_type_mbstate_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_mbstate_t" >&5
+$as_echo "$ac_cv_type_mbstate_t" >&6; }
+   if test $ac_cv_type_mbstate_t = yes; then
+
+$as_echo "#define HAVE_MBSTATE_T 1" >>confdefs.h
+
+   else
+
+$as_echo "#define mbstate_t int" >>confdefs.h
+
+   fi
+
+
+
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a traditional japanese locale" >&5
+$as_echo_n "checking for a traditional japanese locale... " >&6; }
+if test "${gt_cv_locale_ja+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main ()
+{
+  const char *p;
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.
+     On MirBSD 10, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "UTF-8".  */
+#if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0
+        || strcmp (cs, "UTF-8") == 0)
+      return 1;
+  }
+#endif
+#ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+#endif
+  /* Check whether MB_CUR_MAX is > 1.  This excludes the dysfunctional locales
+     on Cygwin 1.5.x.  */
+  if (MB_CUR_MAX == 1)
+    return 1;
+  /* Check whether in a month name, no byte in the range 0x80..0x9F occurs.
+     This excludes the UTF-8 encoding (except on MirBSD).  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1;
+  for (p = buf; *p != '\0'; p++)
+    if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0)
+      return 1;
+  return 0;
+}
+
+_ACEOF
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the AIX locale name.
+      if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_ja=ja_JP
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_ja=ja_JP.EUC-JP
+        else
+          # Test for the HP-UX, OSF/1, NetBSD locale name.
+          if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+            gt_cv_locale_ja=ja_JP.eucJP
+          else
+            # Test for the IRIX, FreeBSD locale name.
+            if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+              gt_cv_locale_ja=ja_JP.EUC
+            else
+              # Test for the Solaris 7 locale name.
+              if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+                gt_cv_locale_ja=ja
+              else
+                # Special test for NetBSD 1.6.
+                if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then
+                  gt_cv_locale_ja=ja_JP.eucJP
+                else
+                  # None found.
+                  gt_cv_locale_ja=none
+                fi
+              fi
+            fi
+          fi
+        fi
+      fi
+    fi
+    rm -fr conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_locale_ja" >&5
+$as_echo "$gt_cv_locale_ja" >&6; }
+  LOCALE_JA=$gt_cv_locale_ja
+
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a transitional chinese locale" >&5
+$as_echo_n "checking for a transitional chinese locale... " >&6; }
+if test "${gt_cv_locale_zh_CN+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main ()
+{
+  const char *p;
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.
+     On MirBSD 10, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "UTF-8".  */
+#if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0
+        || strcmp (cs, "UTF-8") == 0)
+      return 1;
+  }
+#endif
+#ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+#endif
+  /* Check whether in a month name, no byte in the range 0x80..0x9F occurs.
+     This excludes the UTF-8 encoding (except on MirBSD).  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1;
+  for (p = buf; *p != '\0'; p++)
+    if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0)
+      return 1;
+  /* Check whether a typical GB18030 multibyte sequence is recognized as a
+     single wide character.  This excludes the GB2312 and GBK encodings.  */
+  if (mblen ("\203\062\332\066", 5) != 4)
+    return 1;
+  return 0;
+}
+
+_ACEOF
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the locale name without encoding suffix.
+      if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_zh_CN=zh_CN
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_zh_CN=zh_CN.GB18030
+        else
+          # None found.
+          gt_cv_locale_zh_CN=none
+        fi
+      fi
+    else
+      # If there was a link error, due to mblen(), the system is so old that
+      # it certainly doesn't have a chinese locale.
+      gt_cv_locale_zh_CN=none
+    fi
+    rm -fr conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_locale_zh_CN" >&5
+$as_echo "$gt_cv_locale_zh_CN" >&6; }
+  LOCALE_ZH_CN=$gt_cv_locale_zh_CN
+
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a french Unicode locale" >&5
+$as_echo_n "checking for a french Unicode locale... " >&6; }
+if test "${gt_cv_locale_fr_utf8+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main () {
+  /* On BeOS and Haiku, locales are not implemented in libc.  Rather, libintl
+     imitates locale dependent behaviour by looking at the environment
+     variables, and all locales use the UTF-8 encoding.  */
+#if !(defined __BEOS__ || defined __HAIKU__)
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.  */
+# if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0)
+      return 1;
+  }
+# endif
+# ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+# endif
+  /* Check whether in the abbreviation of the second month, the second
+     character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is
+     two bytes long, with UTF-8 encoding.  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%b", &t) < 4
+      || buf[1] != (char) 0xc3 || buf[2] != (char) 0xa9 || buf[3] != 'v')
+    return 1;
+#endif
+  /* Check whether the decimal separator is a comma.
+     On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point
+     are nl_langinfo(RADIXCHAR) are both ".".  */
+  if (localeconv () ->decimal_point[0] != ',') return 1;
+  return 0;
+}
+
+_ACEOF
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the usual locale name.
+      if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_fr_utf8=fr_FR
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_fr_utf8=fr_FR.UTF-8
+        else
+          # Test for the Solaris 7 locale name.
+          if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+            gt_cv_locale_fr_utf8=fr.UTF-8
+          else
+            # None found.
+            gt_cv_locale_fr_utf8=none
+          fi
+        fi
+      fi
+    fi
+    rm -fr conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_locale_fr_utf8" >&5
+$as_echo "$gt_cv_locale_fr_utf8" >&6; }
+  LOCALE_FR_UTF8=$gt_cv_locale_fr_utf8
+
+
+
+    gl_cv_c_multiarch=no
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#ifndef __APPLE_CC__
+         not a universal capable compiler
+        #endif
+        typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+               arch=
+     prev=
+     for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do
+       if test -n "$prev"; then
+         case $word in
+           i?86 | x86_64 | ppc | ppc64)
+             if test -z "$arch" || test "$arch" = "$word"; then
+               arch="$word"
+             else
+               gl_cv_c_multiarch=yes
+             fi
+             ;;
+         esac
+         prev=
+       else
+         if test "x$word" = "x-arch"; then
+           prev=arch
+         fi
+       fi
+     done
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+  if test $gl_cv_c_multiarch = yes; then
+    APPLE_UNIVERSAL_BUILD=1
+  else
+    APPLE_UNIVERSAL_BUILD=0
+  fi
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C/C++ restrict keyword" >&5
+$as_echo_n "checking for C/C++ restrict keyword... " >&6; }
+if test "${ac_cv_c_restrict+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_c_restrict=no
+   # The order here caters to the fact that C++ does not require restrict.
+   for ac_kw in __restrict __restrict__ _Restrict restrict; do
+     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+typedef int * int_ptr;
+	int foo (int_ptr $ac_kw ip) {
+	return ip[0];
+       }
+int
+main ()
+{
+int s[1];
+	int * $ac_kw t = s;
+	t[0] = 0;
+	return foo(t)
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_c_restrict=$ac_kw
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+     test "$ac_cv_c_restrict" != no && break
+   done
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_restrict" >&5
+$as_echo "$ac_cv_c_restrict" >&6; }
+
+ case $ac_cv_c_restrict in
+   restrict) ;;
+   no) $as_echo "#define restrict /**/" >>confdefs.h
+ ;;
+   *)  cat >>confdefs.h <<_ACEOF
+#define restrict $ac_cv_c_restrict
+_ACEOF
+ ;;
+ esac
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for stdbool.h that conforms to C99" >&5
+$as_echo_n "checking for stdbool.h that conforms to C99... " >&6; }
+if test "${ac_cv_header_stdbool_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+             #include <stdbool.h>
+             #ifndef bool
+              "error: bool is not defined"
+             #endif
+             #ifndef false
+              "error: false is not defined"
+             #endif
+             #if false
+              "error: false is not 0"
+             #endif
+             #ifndef true
+              "error: true is not defined"
+             #endif
+             #if true != 1
+              "error: true is not 1"
+             #endif
+             #ifndef __bool_true_false_are_defined
+              "error: __bool_true_false_are_defined is not defined"
+             #endif
+
+             struct s { _Bool s: 1; _Bool t; } s;
+
+             char a[true == 1 ? 1 : -1];
+             char b[false == 0 ? 1 : -1];
+             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+             char d[(bool) 0.5 == true ? 1 : -1];
+             /* See body of main program for 'e'.  */
+             char f[(_Bool) 0.0 == false ? 1 : -1];
+             char g[true];
+             char h[sizeof (_Bool)];
+             char i[sizeof s.t];
+             enum { j = false, k = true, l = false * true, m = true * 256 };
+             /* The following fails for
+                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+             _Bool n[m];
+             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+             /* Catch a bug in an HP-UX C compiler.  See
+                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+              */
+             _Bool q = true;
+             _Bool *pq = &q;
+
+int
+main ()
+{
+
+             bool e = &s;
+             *pq |= q;
+             *pq |= ! q;
+             /* Refer to every declared value, to avoid compiler optimizations.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+                     + !m + !n + !o + !p + !q + !pq);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv_header_stdbool_h=yes
+else
+  ac_cv_header_stdbool_h=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdbool_h" >&5
+$as_echo "$ac_cv_header_stdbool_h" >&6; }
+   ac_fn_c_check_type "$LINENO" "_Bool" "ac_cv_type__Bool" "$ac_includes_default"
+if test "x$ac_cv_type__Bool" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE__BOOL 1
+_ACEOF
+
+
+fi
+
+   if test $ac_cv_header_stdbool_h = yes; then
+
+$as_echo "#define HAVE_STDBOOL_H 1" >>confdefs.h
+
+   fi
+
+    REPLACE_NULL=0;
+  HAVE_WCHAR_T=1;
+  STDDEF_H='';
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wchar_t" >&5
+$as_echo_n "checking for wchar_t... " >&6; }
+if test "${gt_cv_c_wchar_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stddef.h>
+            wchar_t foo = (wchar_t)'\0';
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gt_cv_c_wchar_t=yes
+else
+  gt_cv_c_wchar_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wchar_t" >&5
+$as_echo "$gt_cv_c_wchar_t" >&6; }
+  if test $gt_cv_c_wchar_t = yes; then
+
+$as_echo "#define HAVE_WCHAR_T 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
+$as_echo_n "checking for long long int... " >&6; }
+if test "${ac_cv_type_long_long_int+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  /* For now, do not test the preprocessor; as of 2007 there are too many
+         implementations with broken preprocessors.  Perhaps this can
+         be revisited in 2012.  In the meantime, code should not expect
+         #if to work with literals wider than 32 bits.  */
+      /* Test literals.  */
+      long long int ll = 9223372036854775807ll;
+      long long int nll = -9223372036854775807LL;
+      unsigned long long int ull = 18446744073709551615ULL;
+      /* Test constant expressions.   */
+      typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+                     ? 1 : -1)];
+      typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+                     ? 1 : -1)];
+      int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division.  */
+      long long int llmax = 9223372036854775807ll;
+      unsigned long long int ullmax = 18446744073709551615ull;
+      return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+              | (llmax / ll) | (llmax % ll)
+              | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+              | (ullmax / ull) | (ullmax % ull));
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+                          if test "$cross_compiling" = yes; then :
+  ac_cv_type_long_long_int=yes
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+               #ifndef LLONG_MAX
+               # define HALF \
+                        (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+               # define LLONG_MAX (HALF - 1 + HALF)
+               #endif
+int
+main ()
+{
+long long int n = 1;
+               int i;
+               for (i = 0; ; i++)
+                 {
+                   long long int m = n << i;
+                   if (m >> i != n)
+                     return 1;
+                   if (LLONG_MAX / 2 < m)
+                     break;
+                 }
+               return 0;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_type_long_long_int=yes
+else
+  ac_cv_type_long_long_int=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+else
+  ac_cv_type_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
+$as_echo "$ac_cv_type_long_long_int" >&6; }
+  if test $ac_cv_type_long_long_int = yes; then
+
+$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
+
+  fi
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
+$as_echo_n "checking for unsigned long long int... " >&6; }
+if test "${ac_cv_type_unsigned_long_long_int+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  /* For now, do not test the preprocessor; as of 2007 there are too many
+         implementations with broken preprocessors.  Perhaps this can
+         be revisited in 2012.  In the meantime, code should not expect
+         #if to work with literals wider than 32 bits.  */
+      /* Test literals.  */
+      long long int ll = 9223372036854775807ll;
+      long long int nll = -9223372036854775807LL;
+      unsigned long long int ull = 18446744073709551615ULL;
+      /* Test constant expressions.   */
+      typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+                     ? 1 : -1)];
+      typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+                     ? 1 : -1)];
+      int i = 63;
+int
+main ()
+{
+/* Test availability of runtime routines for shift and division.  */
+      long long int llmax = 9223372036854775807ll;
+      unsigned long long int ullmax = 18446744073709551615ull;
+      return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+              | (llmax / ll) | (llmax % ll)
+              | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+              | (ullmax / ull) | (ullmax % ull));
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_type_unsigned_long_long_int=yes
+else
+  ac_cv_type_unsigned_long_long_int=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
+$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+
+$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
+
+  fi
+
+
+
+
+
+
+  GNULIB_CHOWN=0;
+  GNULIB_CLOSE=0;
+  GNULIB_DUP2=0;
+  GNULIB_DUP3=0;
+  GNULIB_ENVIRON=0;
+  GNULIB_EUIDACCESS=0;
+  GNULIB_FACCESSAT=0;
+  GNULIB_FCHDIR=0;
+  GNULIB_FCHOWNAT=0;
+  GNULIB_FSYNC=0;
+  GNULIB_FTRUNCATE=0;
+  GNULIB_GETCWD=0;
+  GNULIB_GETDOMAINNAME=0;
+  GNULIB_GETDTABLESIZE=0;
+  GNULIB_GETGROUPS=0;
+  GNULIB_GETHOSTNAME=0;
+  GNULIB_GETLOGIN=0;
+  GNULIB_GETLOGIN_R=0;
+  GNULIB_GETPAGESIZE=0;
+  GNULIB_GETUSERSHELL=0;
+  GNULIB_LCHOWN=0;
+  GNULIB_LINK=0;
+  GNULIB_LINKAT=0;
+  GNULIB_LSEEK=0;
+  GNULIB_PIPE=0;
+  GNULIB_PIPE2=0;
+  GNULIB_PREAD=0;
+  GNULIB_PWRITE=0;
+  GNULIB_READLINK=0;
+  GNULIB_READLINKAT=0;
+  GNULIB_RMDIR=0;
+  GNULIB_SLEEP=0;
+  GNULIB_SYMLINK=0;
+  GNULIB_SYMLINKAT=0;
+  GNULIB_TTYNAME_R=0;
+  GNULIB_UNISTD_H_GETOPT=0;
+  GNULIB_UNISTD_H_SIGPIPE=0;
+  GNULIB_UNLINK=0;
+  GNULIB_UNLINKAT=0;
+  GNULIB_USLEEP=0;
+  GNULIB_WRITE=0;
+    HAVE_CHOWN=1;
+  HAVE_DUP2=1;
+  HAVE_DUP3=1;
+  HAVE_EUIDACCESS=1;
+  HAVE_FACCESSAT=1;
+  HAVE_FCHDIR=1;
+  HAVE_FCHOWNAT=1;
+  HAVE_FSYNC=1;
+  HAVE_FTRUNCATE=1;
+  HAVE_GETDTABLESIZE=1;
+  HAVE_GETGROUPS=1;
+  HAVE_GETHOSTNAME=1;
+  HAVE_GETLOGIN=1;
+  HAVE_GETPAGESIZE=1;
+  HAVE_LCHOWN=1;
+  HAVE_LINK=1;
+  HAVE_LINKAT=1;
+  HAVE_PIPE=1;
+  HAVE_PIPE2=1;
+  HAVE_PREAD=1;
+  HAVE_PWRITE=1;
+  HAVE_READLINK=1;
+  HAVE_READLINKAT=1;
+  HAVE_SLEEP=1;
+  HAVE_SYMLINK=1;
+  HAVE_SYMLINKAT=1;
+  HAVE_UNLINKAT=1;
+  HAVE_USLEEP=1;
+  HAVE_DECL_ENVIRON=1;
+  HAVE_DECL_FCHDIR=1;
+  HAVE_DECL_GETDOMAINNAME=1;
+  HAVE_DECL_GETLOGIN_R=1;
+  HAVE_DECL_GETPAGESIZE=1;
+  HAVE_DECL_GETUSERSHELL=1;
+  HAVE_DECL_TTYNAME_R=1;
+  HAVE_OS_H=0;
+  HAVE_SYS_PARAM_H=0;
+  REPLACE_CHOWN=0;
+  REPLACE_CLOSE=0;
+  REPLACE_DUP=0;
+  REPLACE_DUP2=0;
+  REPLACE_FCHOWNAT=0;
+  REPLACE_GETCWD=0;
+  REPLACE_GETDOMAINNAME=0;
+  REPLACE_GETLOGIN_R=0;
+  REPLACE_GETGROUPS=0;
+  REPLACE_GETPAGESIZE=0;
+  REPLACE_LCHOWN=0;
+  REPLACE_LINK=0;
+  REPLACE_LINKAT=0;
+  REPLACE_LSEEK=0;
+  REPLACE_PREAD=0;
+  REPLACE_PWRITE=0;
+  REPLACE_READLINK=0;
+  REPLACE_RMDIR=0;
+  REPLACE_SLEEP=0;
+  REPLACE_SYMLINK=0;
+  REPLACE_TTYNAME_R=0;
+  REPLACE_UNLINK=0;
+  REPLACE_UNLINKAT=0;
+  REPLACE_USLEEP=0;
+  REPLACE_WRITE=0;
+  UNISTD_H_HAVE_WINSOCK2_H=0;
+  UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;
+
+
+
+
+
+
+
+
+  if test $ac_cv_header_features_h = yes; then
+    HAVE_FEATURES_H=1
+  else
+    HAVE_FEATURES_H=0
+  fi
+
+
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for wint_t" >&5
+$as_echo_n "checking for wint_t... " >&6; }
+if test "${gt_cv_c_wint_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
+   before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+            wint_t foo = (wchar_t)'\0';
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gt_cv_c_wint_t=yes
+else
+  gt_cv_c_wint_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_c_wint_t" >&5
+$as_echo "$gt_cv_c_wint_t" >&6; }
+  if test $gt_cv_c_wint_t = yes; then
+
+$as_echo "#define HAVE_WINT_T 1" >>confdefs.h
+
+  fi
+
+
+
+
+
+
+
+ac_fn_c_check_decl "$LINENO" "iswblank" "ac_cv_have_decl_iswblank" "$ac_includes_default"
+if test "x$ac_cv_have_decl_iswblank" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ISWBLANK $ac_have_decl
+_ACEOF
+
+
+
+
+   if true; then
+  GL_COND_LIBTOOL_TRUE=
+  GL_COND_LIBTOOL_FALSE='#'
+else
+  GL_COND_LIBTOOL_TRUE='#'
+  GL_COND_LIBTOOL_FALSE=
+fi
+
+  gl_cond_libtool=true
+  gl_m4_base='gl/m4'
+
+
+
+
+
+
+
+
+
+  gl_source_base='gl'
+  # Code from module alloca-opt:
+
+
+  if test $ac_cv_func_alloca_works = no; then
+    :
+  fi
+
+  # Define an additional variable used in the Makefile substitution.
+  if test $ac_cv_working_alloca_h = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for alloca as a compiler built-in" >&5
+$as_echo_n "checking for alloca as a compiler built-in... " >&6; }
+if test "${gl_cv_rpl_alloca+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#if defined __GNUC__ || defined _AIX || defined _MSC_VER
+        Need own alloca
+#endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "Need own alloca" >/dev/null 2>&1; then :
+  gl_cv_rpl_alloca=yes
+else
+  gl_cv_rpl_alloca=no
+fi
+rm -f conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_rpl_alloca" >&5
+$as_echo "$gl_cv_rpl_alloca" >&6; }
+    if test $gl_cv_rpl_alloca = yes; then
+
+$as_echo "#define HAVE_ALLOCA 1" >>confdefs.h
+
+      ALLOCA_H=alloca.h
+    else
+                  ALLOCA_H=
+    fi
+  else
+    ALLOCA_H=alloca.h
+  fi
+
+
+  # Code from module arg-nonnull:
+  # Code from module btowc:
+
+
+
+
+
+
+  if test $ac_cv_func_btowc = no; then
+    HAVE_BTOWC=0
+  else
+
+
+
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether btowc(0) is correct" >&5
+$as_echo_n "checking whether btowc(0) is correct... " >&6; }
+if test "${gl_cv_func_btowc_nul+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+        if test "$cross_compiling" = yes; then :
+
+           case "$host_os" in
+                      # Guess no on Cygwin.
+             cygwin*) gl_cv_func_btowc_nul="guessing no" ;;
+                      # Guess yes otherwise.
+             *)       gl_cv_func_btowc_nul="guessing yes" ;;
+           esac
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (btowc ('\0') != 0)
+    return 1;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_btowc_nul=yes
+else
+  gl_cv_func_btowc_nul=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_btowc_nul" >&5
+$as_echo "$gl_cv_func_btowc_nul" >&6; }
+
+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether btowc(EOF) is correct" >&5
+$as_echo_n "checking whether btowc(EOF) is correct... " >&6; }
+if test "${gl_cv_func_btowc_eof+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                        case "$host_os" in
+                 # Guess no on IRIX.
+          irix*) gl_cv_func_btowc_eof="guessing no" ;;
+                 # Guess yes otherwise.
+          *)     gl_cv_func_btowc_eof="guessing yes" ;;
+        esac
+        if test $LOCALE_FR != none; then
+          if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_FR") != NULL)
+    {
+      if (btowc (EOF) != WEOF)
+        return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_btowc_eof=yes
+else
+  gl_cv_func_btowc_eof=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+        fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_btowc_eof" >&5
+$as_echo "$gl_cv_func_btowc_eof" >&6; }
+
+    case "$gl_cv_func_btowc_nul" in
+      *yes) ;;
+      *) REPLACE_BTOWC=1 ;;
+    esac
+    case "$gl_cv_func_btowc_eof" in
+      *yes) ;;
+      *) REPLACE_BTOWC=1 ;;
+    esac
+  fi
+  if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
+
+    :
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS btowc.$ac_objext"
+
+
+  :
+
+  fi
+
+
+
+
+  GNULIB_BTOWC=1
+
+
+
+$as_echo "#define GNULIB_TEST_BTOWC 1" >>confdefs.h
+
+
+
+  # Code from module c++defs:
+  # Code from module configmake:
+
+          if test "x$datarootdir" = x; then
+    datarootdir='${datadir}'
+
+  fi
+    if test "x$docdir" = x; then
+    docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+
+  fi
+    if test "x$htmldir" = x; then
+    htmldir='${docdir}'
+
+  fi
+  if test "x$dvidir" = x; then
+    dvidir='${docdir}'
+
+  fi
+  if test "x$pdfdir" = x; then
+    pdfdir='${docdir}'
+
+  fi
+  if test "x$psdir" = x; then
+    psdir='${docdir}'
+
+  fi
+  if test "x$lispdir" = x; then
+    lispdir='${datarootdir}/emacs/site-lisp'
+
+  fi
+  if test "x$localedir" = x; then
+    localedir='${datarootdir}/locale'
+
+  fi
+
+      pkglibexecdir='${libexecdir}/${PACKAGE}'
+
+
+  # Code from module extensions:
+  # Code from module gettext-h:
+
+
+  # Code from module include_next:
+  # Code from module langinfo:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_langinfo_h='<'langinfo.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <langinfo.h>" >&5
+$as_echo_n "checking absolute name of <langinfo.h>... " >&6; }
+if test "${gl_cv_next_langinfo_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+             if test $ac_cv_header_langinfo_h = yes; then
+
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_langinfo_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/langinfo.h#{
+                    s#.*"\(.*/langinfo.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+          else
+               gl_cv_next_langinfo_h='<'langinfo.h'>'
+             fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_langinfo_h" >&5
+$as_echo "$gl_cv_next_langinfo_h" >&6; }
+     fi
+     NEXT_LANGINFO_H=$gl_cv_next_langinfo_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'langinfo.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_langinfo_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H=$gl_next_as_first_directive
+
+
+
+
+
+    HAVE_LANGINFO_CODESET=0
+  HAVE_LANGINFO_T_FMT_AMPM=0
+  HAVE_LANGINFO_ERA=0
+  HAVE_LANGINFO_YESEXPR=0
+
+  if test $ac_cv_header_langinfo_h = yes; then
+    HAVE_LANGINFO_H=1
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether langinfo.h defines CODESET" >&5
+$as_echo_n "checking whether langinfo.h defines CODESET... " >&6; }
+if test "${gl_cv_header_langinfo_codeset+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int a = CODESET;
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_header_langinfo_codeset=yes
+else
+  gl_cv_header_langinfo_codeset=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_langinfo_codeset" >&5
+$as_echo "$gl_cv_header_langinfo_codeset" >&6; }
+    if test $gl_cv_header_langinfo_codeset = yes; then
+      HAVE_LANGINFO_CODESET=1
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether langinfo.h defines T_FMT_AMPM" >&5
+$as_echo_n "checking whether langinfo.h defines T_FMT_AMPM... " >&6; }
+if test "${gl_cv_header_langinfo_t_fmt_ampm+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int a = T_FMT_AMPM;
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_header_langinfo_t_fmt_ampm=yes
+else
+  gl_cv_header_langinfo_t_fmt_ampm=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_langinfo_t_fmt_ampm" >&5
+$as_echo "$gl_cv_header_langinfo_t_fmt_ampm" >&6; }
+    if test $gl_cv_header_langinfo_t_fmt_ampm = yes; then
+      HAVE_LANGINFO_T_FMT_AMPM=1
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether langinfo.h defines ERA" >&5
+$as_echo_n "checking whether langinfo.h defines ERA... " >&6; }
+if test "${gl_cv_header_langinfo_era+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int a = ERA;
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_header_langinfo_era=yes
+else
+  gl_cv_header_langinfo_era=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_langinfo_era" >&5
+$as_echo "$gl_cv_header_langinfo_era" >&6; }
+    if test $gl_cv_header_langinfo_era = yes; then
+      HAVE_LANGINFO_ERA=1
+    fi
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether langinfo.h defines YESEXPR" >&5
+$as_echo_n "checking whether langinfo.h defines YESEXPR... " >&6; }
+if test "${gl_cv_header_langinfo_yesexpr+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+int a = YESEXPR;
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_header_langinfo_yesexpr=yes
+else
+  gl_cv_header_langinfo_yesexpr=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_langinfo_yesexpr" >&5
+$as_echo "$gl_cv_header_langinfo_yesexpr" >&6; }
+    if test $gl_cv_header_langinfo_yesexpr = yes; then
+      HAVE_LANGINFO_YESEXPR=1
+    fi
+  else
+    HAVE_LANGINFO_H=0
+  fi
+
+
+
+
+
+
+
+    for gl_func in nl_langinfo; do
+    as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5
+$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; }
+if { as_var=$as_gl_Symbol; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+
+int
+main ()
+{
+#undef $gl_func
+  (void) $gl_func;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_gl_Symbol=yes"
+else
+  eval "$as_gl_Symbol=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_gl_Symbol
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+     eval as_val=\$$as_gl_Symbol
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1
+_ACEOF
+
+                     eval ac_cv_have_decl_$gl_func=yes
+fi
+      done
+
+
+  # Code from module localcharset:
+
+
+
+
+
+
+
+
+  LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\""
+
+  # Code from module malloc-gnu:
+
+
+    for ac_header in stdlib.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_STDLIB_H 1
+_ACEOF
+
+fi
+
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5
+$as_echo_n "checking for GNU libc compatible malloc... " >&6; }
+if test "${ac_cv_func_malloc_0_nonnull+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+  ac_cv_func_malloc_0_nonnull=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined STDC_HEADERS || defined HAVE_STDLIB_H
+# include <stdlib.h>
+#else
+char *malloc ();
+#endif
+
+int
+main ()
+{
+return ! malloc (0);
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  ac_cv_func_malloc_0_nonnull=yes
+else
+  ac_cv_func_malloc_0_nonnull=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5
+$as_echo "$ac_cv_func_malloc_0_nonnull" >&6; }
+if test $ac_cv_func_malloc_0_nonnull = yes; then :
+
+$as_echo "#define HAVE_MALLOC_GNU 1" >>confdefs.h
+
+else
+  $as_echo "#define HAVE_MALLOC_GNU 0" >>confdefs.h
+
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS malloc.$ac_objext"
+
+  REPLACE_MALLOC=1
+
+
+fi
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define GNULIB_MALLOC_GNU 1
+_ACEOF
+
+
+  # Code from module malloc-posix:
+
+
+
+  if test $gl_cv_func_malloc_posix = yes; then
+
+$as_echo "#define HAVE_MALLOC_POSIX 1" >>confdefs.h
+
+  else
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS malloc.$ac_objext"
+
+  REPLACE_MALLOC=1
+
+  fi
+
+
+
+
+  GNULIB_MALLOC_POSIX=1
+
+
+
+$as_echo "#define GNULIB_TEST_MALLOC_POSIX 1" >>confdefs.h
+
+
+
+  # Code from module mbrtowc:
+
+
+
+
+
+
+
+
+
+
+  if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc handles incomplete characters" >&5
+$as_echo_n "checking whether mbrtowc handles incomplete characters... " >&6; }
+if test "${gl_cv_func_mbrtowc_incomplete_state+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                     # Guess no on AIX and OSF/1.
+        aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
+                     # Guess yes otherwise.
+        *)           gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
+      esac
+      if test $LOCALE_JA != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        if (mbsinit (&state))
+          return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_incomplete_state=yes
+else
+  gl_cv_func_mbrtowc_incomplete_state=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_incomplete_state" >&5
+$as_echo "$gl_cv_func_mbrtowc_incomplete_state" >&6; }
+
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc works as well as mbtowc" >&5
+$as_echo_n "checking whether mbrtowc works as well as mbtowc... " >&6; }
+if test "${gl_cv_func_mbrtowc_sanitycheck+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                    # Guess no on Solaris 8.
+        solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
+                    # Guess yes otherwise.
+        *)          gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
+      esac
+      if test $LOCALE_ZH_CN != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 8:
+     mbrtowc returns 2, and sets wc to 0x00F0.
+     mbtowc returns 4 (correct) and sets wc to 0x5EDC.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 3, 6, &state) != 4
+          && mbtowc (&wc, input + 3, 6) == 4)
+        return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_sanitycheck=yes
+else
+  gl_cv_func_mbrtowc_sanitycheck=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_sanitycheck" >&5
+$as_echo "$gl_cv_func_mbrtowc_sanitycheck" >&6; }
+
+    REPLACE_MBSTATE_T=0
+    case "$gl_cv_func_mbrtowc_incomplete_state" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+    case "$gl_cv_func_mbrtowc_sanitycheck" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+  else
+    REPLACE_MBSTATE_T=1
+  fi
+  if test $REPLACE_MBSTATE_T = 1; then
+
+    :
+
+  fi
+
+
+
+  if test $ac_cv_func_mbrtowc = no; then
+    HAVE_MBRTOWC=0
+  else
+    if test $REPLACE_MBSTATE_T = 1; then
+      REPLACE_MBRTOWC=1
+    else
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc handles a NULL pwc argument" >&5
+$as_echo_n "checking whether mbrtowc handles a NULL pwc argument... " >&6; }
+if test "${gl_cv_func_mbrtowc_null_arg1+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                  # Guess no on Solaris.
+        solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;;
+                  # Guess yes otherwise.
+        *)        gl_cv_func_mbrtowc_null_arg1="guessing yes" ;;
+      esac
+      if test $LOCALE_FR_UTF8 != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  int result = 0;
+
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      char input[] = "\303\237er";
+      mbstate_t state;
+      wchar_t wc;
+      size_t ret;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      wc = (wchar_t) 0xBADFACE;
+      ret = mbrtowc (&wc, input, 5, &state);
+      if (ret != 2)
+        result |= 1;
+      if (!mbsinit (&state))
+        result |= 2;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      ret = mbrtowc (NULL, input, 5, &state);
+      if (ret != 2) /* Solaris 7 fails here: ret is -1.  */
+        result |= 4;
+      if (!mbsinit (&state))
+        result |= 8;
+    }
+  return result;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_null_arg1=yes
+else
+  gl_cv_func_mbrtowc_null_arg1=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_null_arg1" >&5
+$as_echo "$gl_cv_func_mbrtowc_null_arg1" >&6; }
+
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc handles a NULL string argument" >&5
+$as_echo_n "checking whether mbrtowc handles a NULL string argument... " >&6; }
+if test "${gl_cv_func_mbrtowc_null_arg2+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+              # Guess no on OSF/1.
+        osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;;
+              # Guess yes otherwise.
+        *)    gl_cv_func_mbrtowc_null_arg2="guessing yes" ;;
+      esac
+      if test $LOCALE_FR_UTF8 != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      mbstate_t state;
+      wchar_t wc;
+      int ret;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      wc = (wchar_t) 0xBADFACE;
+      mbrtowc (&wc, NULL, 5, &state);
+      /* Check that wc was not modified.  */
+      if (wc != (wchar_t) 0xBADFACE)
+        return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_null_arg2=yes
+else
+  gl_cv_func_mbrtowc_null_arg2=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_null_arg2" >&5
+$as_echo "$gl_cv_func_mbrtowc_null_arg2" >&6; }
+
+
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc has a correct return value" >&5
+$as_echo_n "checking whether mbrtowc has a correct return value... " >&6; }
+if test "${gl_cv_func_mbrtowc_retval+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                          # Guess no on HP-UX and Solaris.
+        hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;;
+                          # Guess yes otherwise.
+        *)                gl_cv_func_mbrtowc_retval="guessing yes" ;;
+      esac
+      if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  int result = 0;
+  /* This fails on Solaris.  */
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      char input[] = "B\303\274\303\237er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        {
+          input[1] = '\0';
+          if (mbrtowc (&wc, input + 2, 5, &state) != 1)
+            result |= 1;
+        }
+    }
+  /* This fails on HP-UX 11.11.  */
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        {
+          input[1] = '\0';
+          if (mbrtowc (&wc, input + 2, 5, &state) != 2)
+            result |= 2;
+        }
+    }
+  return result;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_retval=yes
+else
+  gl_cv_func_mbrtowc_retval=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_retval" >&5
+$as_echo "$gl_cv_func_mbrtowc_retval" >&6; }
+
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc returns 0 when parsing a NUL character" >&5
+$as_echo_n "checking whether mbrtowc returns 0 when parsing a NUL character... " >&6; }
+if test "${gl_cv_func_mbrtowc_nul_retval+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                       # Guess no on Solaris 8 and 9.
+        solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
+                       # Guess yes otherwise.
+        *)             gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
+      esac
+      if test $LOCALE_ZH_CN != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 8 and 9.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, "", 1, &state) != 0)
+        return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_nul_retval=yes
+else
+  gl_cv_func_mbrtowc_nul_retval=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_nul_retval" >&5
+$as_echo "$gl_cv_func_mbrtowc_nul_retval" >&6; }
+
+      case "$gl_cv_func_mbrtowc_null_arg1" in
+        *yes) ;;
+        *)
+$as_echo "#define MBRTOWC_NULL_ARG1_BUG 1" >>confdefs.h
+
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+      case "$gl_cv_func_mbrtowc_null_arg2" in
+        *yes) ;;
+        *)
+$as_echo "#define MBRTOWC_NULL_ARG2_BUG 1" >>confdefs.h
+
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+      case "$gl_cv_func_mbrtowc_retval" in
+        *yes) ;;
+        *)
+$as_echo "#define MBRTOWC_RETVAL_BUG 1" >>confdefs.h
+
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+      case "$gl_cv_func_mbrtowc_nul_retval" in
+        *yes) ;;
+        *)
+$as_echo "#define MBRTOWC_NUL_RETVAL_BUG 1" >>confdefs.h
+
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+    fi
+  fi
+  if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
+
+    :
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS mbrtowc.$ac_objext"
+
+
+  :
+
+  fi
+
+
+
+
+  GNULIB_MBRTOWC=1
+
+
+
+$as_echo "#define GNULIB_TEST_MBRTOWC 1" >>confdefs.h
+
+
+
+  # Code from module mbsinit:
+
+
+
+
+
+
+
+
+
+
+  if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc handles incomplete characters" >&5
+$as_echo_n "checking whether mbrtowc handles incomplete characters... " >&6; }
+if test "${gl_cv_func_mbrtowc_incomplete_state+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                     # Guess no on AIX and OSF/1.
+        aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
+                     # Guess yes otherwise.
+        *)           gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
+      esac
+      if test $LOCALE_JA != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        if (mbsinit (&state))
+          return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_incomplete_state=yes
+else
+  gl_cv_func_mbrtowc_incomplete_state=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_incomplete_state" >&5
+$as_echo "$gl_cv_func_mbrtowc_incomplete_state" >&6; }
+
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc works as well as mbtowc" >&5
+$as_echo_n "checking whether mbrtowc works as well as mbtowc... " >&6; }
+if test "${gl_cv_func_mbrtowc_sanitycheck+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                    # Guess no on Solaris 8.
+        solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
+                    # Guess yes otherwise.
+        *)          gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
+      esac
+      if test $LOCALE_ZH_CN != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 8:
+     mbrtowc returns 2, and sets wc to 0x00F0.
+     mbtowc returns 4 (correct) and sets wc to 0x5EDC.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 3, 6, &state) != 4
+          && mbtowc (&wc, input + 3, 6) == 4)
+        return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_sanitycheck=yes
+else
+  gl_cv_func_mbrtowc_sanitycheck=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_sanitycheck" >&5
+$as_echo "$gl_cv_func_mbrtowc_sanitycheck" >&6; }
+
+    REPLACE_MBSTATE_T=0
+    case "$gl_cv_func_mbrtowc_incomplete_state" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+    case "$gl_cv_func_mbrtowc_sanitycheck" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+  else
+    REPLACE_MBSTATE_T=1
+  fi
+  if test $REPLACE_MBSTATE_T = 1; then
+
+    :
+
+  fi
+
+
+
+  if test $ac_cv_func_mbsinit = no; then
+    HAVE_MBSINIT=0
+  else
+    if test $REPLACE_MBSTATE_T = 1; then
+      REPLACE_MBSINIT=1
+    fi
+  fi
+  if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
+
+    :
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS mbsinit.$ac_objext"
+
+
+  :
+
+  fi
+
+
+
+
+  GNULIB_MBSINIT=1
+
+
+
+$as_echo "#define GNULIB_TEST_MBSINIT 1" >>confdefs.h
+
+
+
+  # Code from module multiarch:
+
+  # Code from module nl_langinfo:
+
+
+
+
+     if test $ac_cv_func_nl_langinfo = yes; then
+    # On Irix 6.5, YESEXPR is defined, but nl_langinfo(YESEXPR) is broken.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether YESEXPR works" >&5
+$as_echo_n "checking whether YESEXPR works... " >&6; }
+if test "${gl_cv_func_nl_langinfo_yesexpr_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+
+         case "$host_os" in
+                   # Guess no on irix systems.
+           irix*)  gl_cv_func_nl_langinfo_yesexpr_works="guessing no";;
+                   # Guess yes elsewhere.
+           *)      gl_cv_func_nl_langinfo_yesexpr_works="guessing yes";;
+         esac
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <langinfo.h>
+
+int
+main ()
+{
+return !*nl_langinfo(YESEXPR);
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_nl_langinfo_yesexpr_works=yes
+else
+  gl_cv_func_nl_langinfo_yesexpr_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_nl_langinfo_yesexpr_works" >&5
+$as_echo "$gl_cv_func_nl_langinfo_yesexpr_works" >&6; }
+    case $gl_cv_func_nl_langinfo_yesexpr_works in
+      *yes) FUNC_NL_LANGINFO_YESEXPR_WORKS=1 ;;
+      *)    FUNC_NL_LANGINFO_YESEXPR_WORKS=0 ;;
+    esac
+
+cat >>confdefs.h <<_ACEOF
+#define FUNC_NL_LANGINFO_YESEXPR_WORKS $FUNC_NL_LANGINFO_YESEXPR_WORKS
+_ACEOF
+
+    if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1 \
+        && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1; then
+      :
+    else
+      REPLACE_NL_LANGINFO=1
+
+$as_echo "#define REPLACE_NL_LANGINFO 1" >>confdefs.h
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS nl_langinfo.$ac_objext"
+
+    fi
+  else
+    HAVE_NL_LANGINFO=0
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS nl_langinfo.$ac_objext"
+
+  fi
+
+
+
+
+  GNULIB_NL_LANGINFO=1
+
+
+
+$as_echo "#define GNULIB_TEST_NL_LANGINFO 1" >>confdefs.h
+
+
+
+  # Code from module regex:
+
+
+# Check whether --with-included-regex was given.
+if test "${with_included_regex+set}" = set; then :
+  withval=$with_included_regex;
+fi
+
+
+  case $with_included_regex in #(
+  yes|no) ac_use_included_regex=$with_included_regex
+        ;;
+  '')
+    # If the system regex support is good enough that it passes the
+    # following run test, then default to *not* using the included regex.c.
+    # If cross compiling, assume the test would fail and use the included
+    # regex.c.
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for working re_compile_pattern" >&5
+$as_echo_n "checking for working re_compile_pattern... " >&6; }
+if test "${gl_cv_func_re_compile_pattern_working+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$cross_compiling" = yes; then :
+         gl_cv_func_re_compile_pattern_working=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+           #include <locale.h>
+           #include <limits.h>
+           #include <regex.h>
+
+int
+main ()
+{
+int result = 0;
+            static struct re_pattern_buffer regex;
+            unsigned char folded_chars[UCHAR_MAX + 1];
+            int i;
+            const char *s;
+            struct re_registers regs;
+
+            /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html
+               This test needs valgrind to catch the bug on Debian
+               GNU/Linux 3.1 x86, but it might catch the bug better
+               on other platforms and it shouldn't hurt to try the
+               test here.  */
+            if (setlocale (LC_ALL, "en_US.UTF-8"))
+              {
+                static char const pat[] = "insert into";
+                static char const data[] =
+                  "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK";
+                re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE
+                               | RE_ICASE);
+                memset (&regex, 0, sizeof regex);
+                s = re_compile_pattern (pat, sizeof pat - 1, &regex);
+                if (s)
+                  result |= 1;
+                else if (re_search (&regex, data, sizeof data - 1,
+                                    0, sizeof data - 1, &regs)
+                         != -1)
+                  result |= 1;
+                if (! setlocale (LC_ALL, "C"))
+                  return 1;
+              }
+
+            /* This test is from glibc bug 3957, reported by Andrew Mackey.  */
+            re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("a[^x]b", 6, &regex);
+            if (s)
+              result |= 2;
+            /* This should fail, but succeeds for glibc-2.5.  */
+            else if (re_search (&regex, "a\nb", 3, 0, 3, &regs) != -1)
+              result |= 2;
+
+            /* This regular expression is from Spencer ere test number 75
+               in grep-2.3.  */
+            re_set_syntax (RE_SYNTAX_POSIX_EGREP);
+            memset (&regex, 0, sizeof regex);
+            for (i = 0; i <= UCHAR_MAX; i++)
+              folded_chars[i] = i;
+            regex.translate = folded_chars;
+            s = re_compile_pattern ("a[[:]:]]b\n", 11, &regex);
+            /* This should fail with _Invalid character class name_ error.  */
+            if (!s)
+              result |= 4;
+
+            /* Ensure that [b-a] is diagnosed as invalid, when
+               using RE_NO_EMPTY_RANGES. */
+            re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("a[b-a]", 6, &regex);
+            if (s == 0)
+              result |= 8;
+
+            /* This should succeed, but does not for glibc-2.1.3.  */
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("{1", 2, &regex);
+            if (s)
+              result |= 8;
+
+            /* The following example is derived from a problem report
+               against gawk from Jorge Stolfi <stolfi at ic.unicamp.br>.  */
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("[an\371]*n", 7, &regex);
+            if (s)
+              result |= 8;
+            /* This should match, but does not for glibc-2.2.1.  */
+            else if (re_match (&regex, "an", 2, 0, &regs) != 2)
+              result |= 8;
+
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("x", 1, &regex);
+            if (s)
+              result |= 8;
+            /* glibc-2.2.93 does not work with a negative RANGE argument.  */
+            else if (re_search (&regex, "wxy", 3, 2, -2, &regs) != 1)
+              result |= 8;
+
+            /* The version of regex.c in older versions of gnulib
+               ignored RE_ICASE.  Detect that problem too.  */
+            re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("x", 1, &regex);
+            if (s)
+              result |= 16;
+            else if (re_search (&regex, "WXY", 3, 0, 3, &regs) < 0)
+              result |= 16;
+
+            /* Catch a bug reported by Vin Shelton in
+               http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html
+               */
+            re_set_syntax (RE_SYNTAX_POSIX_BASIC
+                           & ~RE_CONTEXT_INVALID_DUP
+                           & ~RE_NO_EMPTY_RANGES);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, &regex);
+            if (s)
+              result |= 32;
+
+            /* REG_STARTEND was added to glibc on 2004-01-15.
+               Reject older versions.  */
+            if (! REG_STARTEND)
+              result |= 64;
+
+#if 0
+            /* It would be nice to reject hosts whose regoff_t values are too
+               narrow (including glibc on hosts with 64-bit ptrdiff_t and
+               32-bit int), but we should wait until glibc implements this
+               feature.  Otherwise, support for equivalence classes and
+               multibyte collation symbols would always be broken except
+               when compiling --without-included-regex.   */
+            if (sizeof (regoff_t) < sizeof (ptrdiff_t)
+                || sizeof (regoff_t) < sizeof (ssize_t))
+              result |= 64;
+#endif
+
+            return result;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_re_compile_pattern_working=yes
+else
+  gl_cv_func_re_compile_pattern_working=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_re_compile_pattern_working" >&5
+$as_echo "$gl_cv_func_re_compile_pattern_working" >&6; }
+    case $gl_cv_func_re_compile_pattern_working in #(
+    yes) ac_use_included_regex=no;; #(
+    no) ac_use_included_regex=yes;;
+    esac
+    ;;
+  *) as_fn_error "Invalid value for --with-included-regex: $with_included_regex" "$LINENO" 5
+    ;;
+  esac
+
+  if test $ac_use_included_regex = yes; then
+
+$as_echo "#define _REGEX_LARGE_OFFSETS 1" >>confdefs.h
+
+
+$as_echo "#define re_syntax_options rpl_re_syntax_options" >>confdefs.h
+
+
+$as_echo "#define re_set_syntax rpl_re_set_syntax" >>confdefs.h
+
+
+$as_echo "#define re_compile_pattern rpl_re_compile_pattern" >>confdefs.h
+
+
+$as_echo "#define re_compile_fastmap rpl_re_compile_fastmap" >>confdefs.h
+
+
+$as_echo "#define re_search rpl_re_search" >>confdefs.h
+
+
+$as_echo "#define re_search_2 rpl_re_search_2" >>confdefs.h
+
+
+$as_echo "#define re_match rpl_re_match" >>confdefs.h
+
+
+$as_echo "#define re_match_2 rpl_re_match_2" >>confdefs.h
+
+
+$as_echo "#define re_set_registers rpl_re_set_registers" >>confdefs.h
+
+
+$as_echo "#define re_comp rpl_re_comp" >>confdefs.h
+
+
+$as_echo "#define re_exec rpl_re_exec" >>confdefs.h
+
+
+$as_echo "#define regcomp rpl_regcomp" >>confdefs.h
+
+
+$as_echo "#define regexec rpl_regexec" >>confdefs.h
+
+
+$as_echo "#define regerror rpl_regerror" >>confdefs.h
+
+
+$as_echo "#define regfree rpl_regfree" >>confdefs.h
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS regex.$ac_objext"
+
+
+
+
+
+
+  for ac_header in libintl.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "libintl.h" "ac_cv_header_libintl_h" "$ac_includes_default"
+if test "x$ac_cv_header_libintl_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBINTL_H 1
+_ACEOF
+
+fi
+
+done
+
+
+  ac_fn_c_check_decl "$LINENO" "isblank" "ac_cv_have_decl_isblank" "#include <ctype.h>
+"
+if test "x$ac_cv_have_decl_isblank" = x""yes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_ISBLANK $ac_have_decl
+_ACEOF
+
+
+  fi
+
+  # Code from module ssize_t:
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ssize_t" >&5
+$as_echo_n "checking for ssize_t... " >&6; }
+if test "${gt_cv_ssize_t+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+int x = sizeof (ssize_t *) + sizeof (ssize_t);
+            return !x;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gt_cv_ssize_t=yes
+else
+  gt_cv_ssize_t=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gt_cv_ssize_t" >&5
+$as_echo "$gt_cv_ssize_t" >&6; }
+  if test $gt_cv_ssize_t = no; then
+
+$as_echo "#define ssize_t int" >>confdefs.h
+
+  fi
+
+  # Code from module stdbool:
+
+
+
+  # Define two additional variables used in the Makefile substitution.
+
+  if test "$ac_cv_header_stdbool_h" = yes; then
+    STDBOOL_H=''
+  else
+    STDBOOL_H='stdbool.h'
+  fi
+
+
+  if test "$ac_cv_type__Bool" = yes; then
+    HAVE__BOOL=1
+  else
+    HAVE__BOOL=0
+  fi
+
+
+  # Code from module stddef:
+
+
+
+  if test $gt_cv_c_wchar_t = no; then
+    HAVE_WCHAR_T=0
+    STDDEF_H=stddef.h
+  fi
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NULL can be used in arbitrary expressions" >&5
+$as_echo_n "checking whether NULL can be used in arbitrary expressions... " >&6; }
+if test "${gl_cv_decl_null_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stddef.h>
+      int test[2 * (sizeof NULL == sizeof (void *)) -1];
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_decl_null_works=yes
+else
+  gl_cv_decl_null_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_decl_null_works" >&5
+$as_echo "$gl_cv_decl_null_works" >&6; }
+  if test $gl_cv_decl_null_works = no; then
+    REPLACE_NULL=1
+    STDDEF_H=stddef.h
+  fi
+  if test -n "$STDDEF_H"; then
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_stddef_h='<'stddef.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <stddef.h>" >&5
+$as_echo_n "checking absolute name of <stddef.h>... " >&6; }
+if test "${gl_cv_next_stddef_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stddef.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_stddef_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/stddef.h#{
+                    s#.*"\(.*/stddef.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_stddef_h" >&5
+$as_echo "$gl_cv_next_stddef_h" >&6; }
+     fi
+     NEXT_STDDEF_H=$gl_cv_next_stddef_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'stddef.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_stddef_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_STDDEF_H=$gl_next_as_first_directive
+
+
+
+
+  fi
+
+  # Code from module stdint:
+
+
+
+  if test $ac_cv_type_long_long_int = yes; then
+    HAVE_LONG_LONG_INT=1
+  else
+    HAVE_LONG_LONG_INT=0
+  fi
+
+
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+    HAVE_UNSIGNED_LONG_LONG_INT=1
+  else
+    HAVE_UNSIGNED_LONG_LONG_INT=0
+  fi
+
+
+      if test $ac_cv_header_inttypes_h = yes; then
+    HAVE_INTTYPES_H=1
+  else
+    HAVE_INTTYPES_H=0
+  fi
+
+
+      if test $ac_cv_header_sys_types_h = yes; then
+    HAVE_SYS_TYPES_H=1
+  else
+    HAVE_SYS_TYPES_H=0
+  fi
+
+
+
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_stdint_h='<'stdint.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <stdint.h>" >&5
+$as_echo_n "checking absolute name of <stdint.h>... " >&6; }
+if test "${gl_cv_next_stdint_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+             if test $ac_cv_header_stdint_h = yes; then
+
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdint.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_stdint_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/stdint.h#{
+                    s#.*"\(.*/stdint.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+          else
+               gl_cv_next_stdint_h='<'stdint.h'>'
+             fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_stdint_h" >&5
+$as_echo "$gl_cv_next_stdint_h" >&6; }
+     fi
+     NEXT_STDINT_H=$gl_cv_next_stdint_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'stdint.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_stdint_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_STDINT_H=$gl_next_as_first_directive
+
+
+
+
+  if test $ac_cv_header_stdint_h = yes; then
+    HAVE_STDINT_H=1
+  else
+    HAVE_STDINT_H=0
+  fi
+
+
+    if test $ac_cv_header_stdint_h = yes; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stdint.h conforms to C99" >&5
+$as_echo_n "checking whether stdint.h conforms to C99... " >&6; }
+if test "${gl_cv_header_working_stdint_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  gl_cv_header_working_stdint_h=no
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in <wchar.h>.  */
+#if !(defined WCHAR_MIN && defined WCHAR_MAX)
+#error "WCHAR_MIN, WCHAR_MAX not defined in <stdint.h>"
+#endif
+
+
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+
+#ifdef INT8_MAX
+int8_t a1 = INT8_MAX;
+int8_t a1min = INT8_MIN;
+#endif
+#ifdef INT16_MAX
+int16_t a2 = INT16_MAX;
+int16_t a2min = INT16_MIN;
+#endif
+#ifdef INT32_MAX
+int32_t a3 = INT32_MAX;
+int32_t a3min = INT32_MIN;
+#endif
+#ifdef INT64_MAX
+int64_t a4 = INT64_MAX;
+int64_t a4min = INT64_MIN;
+#endif
+#ifdef UINT8_MAX
+uint8_t b1 = UINT8_MAX;
+#else
+typedef int b1[(unsigned char) -1 != 255 ? 1 : -1];
+#endif
+#ifdef UINT16_MAX
+uint16_t b2 = UINT16_MAX;
+#endif
+#ifdef UINT32_MAX
+uint32_t b3 = UINT32_MAX;
+#endif
+#ifdef UINT64_MAX
+uint64_t b4 = UINT64_MAX;
+#endif
+int_least8_t c1 = INT8_C (0x7f);
+int_least8_t c1max = INT_LEAST8_MAX;
+int_least8_t c1min = INT_LEAST8_MIN;
+int_least16_t c2 = INT16_C (0x7fff);
+int_least16_t c2max = INT_LEAST16_MAX;
+int_least16_t c2min = INT_LEAST16_MIN;
+int_least32_t c3 = INT32_C (0x7fffffff);
+int_least32_t c3max = INT_LEAST32_MAX;
+int_least32_t c3min = INT_LEAST32_MIN;
+int_least64_t c4 = INT64_C (0x7fffffffffffffff);
+int_least64_t c4max = INT_LEAST64_MAX;
+int_least64_t c4min = INT_LEAST64_MIN;
+uint_least8_t d1 = UINT8_C (0xff);
+uint_least8_t d1max = UINT_LEAST8_MAX;
+uint_least16_t d2 = UINT16_C (0xffff);
+uint_least16_t d2max = UINT_LEAST16_MAX;
+uint_least32_t d3 = UINT32_C (0xffffffff);
+uint_least32_t d3max = UINT_LEAST32_MAX;
+uint_least64_t d4 = UINT64_C (0xffffffffffffffff);
+uint_least64_t d4max = UINT_LEAST64_MAX;
+int_fast8_t e1 = INT_FAST8_MAX;
+int_fast8_t e1min = INT_FAST8_MIN;
+int_fast16_t e2 = INT_FAST16_MAX;
+int_fast16_t e2min = INT_FAST16_MIN;
+int_fast32_t e3 = INT_FAST32_MAX;
+int_fast32_t e3min = INT_FAST32_MIN;
+int_fast64_t e4 = INT_FAST64_MAX;
+int_fast64_t e4min = INT_FAST64_MIN;
+uint_fast8_t f1 = UINT_FAST8_MAX;
+uint_fast16_t f2 = UINT_FAST16_MAX;
+uint_fast32_t f3 = UINT_FAST32_MAX;
+uint_fast64_t f4 = UINT_FAST64_MAX;
+#ifdef INTPTR_MAX
+intptr_t g = INTPTR_MAX;
+intptr_t gmin = INTPTR_MIN;
+#endif
+#ifdef UINTPTR_MAX
+uintptr_t h = UINTPTR_MAX;
+#endif
+intmax_t i = INTMAX_MAX;
+uintmax_t j = UINTMAX_MAX;
+
+#include <limits.h> /* for CHAR_BIT */
+#define TYPE_MINIMUM(t) \
+  ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t)))
+#define TYPE_MAXIMUM(t) \
+  ((t) ((t) 0 < (t) -1 \
+        ? (t) -1 \
+        : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+struct s {
+  int check_PTRDIFF:
+      PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)
+      && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)
+      ? 1 : -1;
+  /* Detect bug in FreeBSD 6.0 / ia64.  */
+  int check_SIG_ATOMIC:
+      SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)
+      && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)
+      ? 1 : -1;
+  int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1;
+  int check_WCHAR:
+      WCHAR_MIN == TYPE_MINIMUM (wchar_t)
+      && WCHAR_MAX == TYPE_MAXIMUM (wchar_t)
+      ? 1 : -1;
+  /* Detect bug in mingw.  */
+  int check_WINT:
+      WINT_MIN == TYPE_MINIMUM (wint_t)
+      && WINT_MAX == TYPE_MAXIMUM (wint_t)
+      ? 1 : -1;
+
+  /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others.  */
+  int check_UINT8_C:
+        (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1;
+  int check_UINT16_C:
+        (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1;
+
+  /* Detect bugs in OpenBSD 3.9 stdint.h.  */
+#ifdef UINT8_MAX
+  int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1;
+#endif
+#ifdef UINT16_MAX
+  int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1;
+#endif
+#ifdef UINT32_MAX
+  int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1;
+#endif
+#ifdef UINT64_MAX
+  int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1;
+#endif
+  int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1;
+  int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1;
+  int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1;
+  int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1;
+  int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1;
+  int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1;
+  int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1;
+  int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1;
+  int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1;
+  int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1;
+  int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1;
+};
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+                                                    if test "$cross_compiling" = yes; then :
+                 gl_cv_header_working_stdint_h=yes
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+
+
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+
+#include <stdio.h>
+#include <string.h>
+#define MVAL(macro) MVAL1(macro)
+#define MVAL1(expression) #expression
+static const char *macro_values[] =
+  {
+#ifdef INT8_MAX
+    MVAL (INT8_MAX),
+#endif
+#ifdef INT16_MAX
+    MVAL (INT16_MAX),
+#endif
+#ifdef INT32_MAX
+    MVAL (INT32_MAX),
+#endif
+#ifdef INT64_MAX
+    MVAL (INT64_MAX),
+#endif
+#ifdef UINT8_MAX
+    MVAL (UINT8_MAX),
+#endif
+#ifdef UINT16_MAX
+    MVAL (UINT16_MAX),
+#endif
+#ifdef UINT32_MAX
+    MVAL (UINT32_MAX),
+#endif
+#ifdef UINT64_MAX
+    MVAL (UINT64_MAX),
+#endif
+    NULL
+  };
+
+int
+main ()
+{
+
+  const char **mv;
+  for (mv = macro_values; *mv != NULL; mv++)
+    {
+      const char *value = *mv;
+      /* Test whether it looks like a cast expression.  */
+      if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0
+          || strncmp (value, "((unsigned short)"/*)*/, 17) == 0
+          || strncmp (value, "((unsigned char)"/*)*/, 16) == 0
+          || strncmp (value, "((int)"/*)*/, 6) == 0
+          || strncmp (value, "((signed short)"/*)*/, 15) == 0
+          || strncmp (value, "((signed char)"/*)*/, 14) == 0)
+        return mv - macro_values + 1;
+    }
+  return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_header_working_stdint_h=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_header_working_stdint_h" >&5
+$as_echo "$gl_cv_header_working_stdint_h" >&6; }
+  fi
+  if test "$gl_cv_header_working_stdint_h" = yes; then
+    STDINT_H=
+  else
+            for ac_header in sys/inttypes.h sys/bitypes.h
+do :
+  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
+eval as_val=\$$as_ac_Header
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+    if test $ac_cv_header_sys_inttypes_h = yes; then
+      HAVE_SYS_INTTYPES_H=1
+    else
+      HAVE_SYS_INTTYPES_H=0
+    fi
+
+    if test $ac_cv_header_sys_bitypes_h = yes; then
+      HAVE_SYS_BITYPES_H=1
+    else
+      HAVE_SYS_BITYPES_H=0
+    fi
+
+
+
+
+
+
+  if test $APPLE_UNIVERSAL_BUILD = 0; then
+
+
+  for gltype in ptrdiff_t size_t ; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bit size of $gltype" >&5
+$as_echo_n "checking for bit size of $gltype... " >&6; }
+if { as_var=gl_cv_bitsizeof_${gltype}; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "sizeof ($gltype) * CHAR_BIT" "result"        "
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+#include <limits.h>"; then :
+
+else
+  result=unknown
+fi
+
+       eval gl_cv_bitsizeof_${gltype}=\$result
+
+fi
+eval ac_res=\$gl_cv_bitsizeof_${gltype}
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+    eval result=\$gl_cv_bitsizeof_${gltype}
+    if test $result = unknown; then
+                                                result=0
+    fi
+    GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    cat >>confdefs.h <<_ACEOF
+#define BITSIZEOF_${GLTYPE} $result
+_ACEOF
+
+    eval BITSIZEOF_${GLTYPE}=\$result
+  done
+
+
+  fi
+
+
+  for gltype in sig_atomic_t wchar_t wint_t ; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for bit size of $gltype" >&5
+$as_echo_n "checking for bit size of $gltype... " >&6; }
+if { as_var=gl_cv_bitsizeof_${gltype}; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  if ac_fn_c_compute_int "$LINENO" "sizeof ($gltype) * CHAR_BIT" "result"        "
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+#include <limits.h>"; then :
+
+else
+  result=unknown
+fi
+
+       eval gl_cv_bitsizeof_${gltype}=\$result
+
+fi
+eval ac_res=\$gl_cv_bitsizeof_${gltype}
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+    eval result=\$gl_cv_bitsizeof_${gltype}
+    if test $result = unknown; then
+                                                result=0
+    fi
+    GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    cat >>confdefs.h <<_ACEOF
+#define BITSIZEOF_${GLTYPE} $result
+_ACEOF
+
+    eval BITSIZEOF_${GLTYPE}=\$result
+  done
+
+
+
+
+  for gltype in sig_atomic_t wchar_t wint_t ; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gltype is signed" >&5
+$as_echo_n "checking whether $gltype is signed... " >&6; }
+if { as_var=gl_cv_type_${gltype}_signed; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+            int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  result=yes
+else
+  result=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       eval gl_cv_type_${gltype}_signed=\$result
+
+fi
+eval ac_res=\$gl_cv_type_${gltype}_signed
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+    eval result=\$gl_cv_type_${gltype}_signed
+    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    if test "$result" = yes; then
+      cat >>confdefs.h <<_ACEOF
+#define HAVE_SIGNED_${GLTYPE} 1
+_ACEOF
+
+      eval HAVE_SIGNED_${GLTYPE}=1
+    else
+      eval HAVE_SIGNED_${GLTYPE}=0
+    fi
+  done
+
+
+  gl_cv_type_ptrdiff_t_signed=yes
+  gl_cv_type_size_t_signed=no
+  if test $APPLE_UNIVERSAL_BUILD = 0; then
+
+
+  for gltype in ptrdiff_t size_t ; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $gltype integer literal suffix" >&5
+$as_echo_n "checking for $gltype integer literal suffix... " >&6; }
+if { as_var=gl_cv_type_${gltype}_suffix; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval gl_cv_type_${gltype}_suffix=no
+       eval result=\$gl_cv_type_${gltype}_signed
+       if test "$result" = yes; then
+         glsufu=
+       else
+         glsufu=u
+       fi
+       for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do
+         case $glsuf in
+           '')  gltype1='int';;
+           l)   gltype1='long int';;
+           ll)  gltype1='long long int';;
+           i64) gltype1='__int64';;
+           u)   gltype1='unsigned int';;
+           ul)  gltype1='unsigned long int';;
+           ull) gltype1='unsigned long long int';;
+           ui64)gltype1='unsigned __int64';;
+         esac
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+              extern $gltype foo;
+              extern $gltype1 foo;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval gl_cv_type_${gltype}_suffix=\$glsuf
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+         eval result=\$gl_cv_type_${gltype}_suffix
+         test "$result" != no && break
+       done
+fi
+eval ac_res=\$gl_cv_type_${gltype}_suffix
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    eval result=\$gl_cv_type_${gltype}_suffix
+    test "$result" = no && result=
+    eval ${GLTYPE}_SUFFIX=\$result
+    cat >>confdefs.h <<_ACEOF
+#define ${GLTYPE}_SUFFIX $result
+_ACEOF
+
+  done
+
+
+  fi
+
+
+  for gltype in sig_atomic_t wchar_t wint_t ; do
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $gltype integer literal suffix" >&5
+$as_echo_n "checking for $gltype integer literal suffix... " >&6; }
+if { as_var=gl_cv_type_${gltype}_suffix; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval gl_cv_type_${gltype}_suffix=no
+       eval result=\$gl_cv_type_${gltype}_signed
+       if test "$result" = yes; then
+         glsufu=
+       else
+         glsufu=u
+       fi
+       for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do
+         case $glsuf in
+           '')  gltype1='int';;
+           l)   gltype1='long int';;
+           ll)  gltype1='long long int';;
+           i64) gltype1='__int64';;
+           u)   gltype1='unsigned int';;
+           ul)  gltype1='unsigned long int';;
+           ull) gltype1='unsigned long long int';;
+           ui64)gltype1='unsigned __int64';;
+         esac
+         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+
+              extern $gltype foo;
+              extern $gltype1 foo;
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval gl_cv_type_${gltype}_suffix=\$glsuf
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+         eval result=\$gl_cv_type_${gltype}_suffix
+         test "$result" != no && break
+       done
+fi
+eval ac_res=\$gl_cv_type_${gltype}_suffix
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    eval result=\$gl_cv_type_${gltype}_suffix
+    test "$result" = no && result=
+    eval ${GLTYPE}_SUFFIX=\$result
+    cat >>confdefs.h <<_ACEOF
+#define ${GLTYPE}_SUFFIX $result
+_ACEOF
+
+  done
+
+
+
+    STDINT_H=stdint.h
+  fi
+
+
+  # Code from module stdlib:
+
+
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_stdlib_h='<'stdlib.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <stdlib.h>" >&5
+$as_echo_n "checking absolute name of <stdlib.h>... " >&6; }
+if test "${gl_cv_next_stdlib_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_stdlib_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/stdlib.h#{
+                    s#.*"\(.*/stdlib.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_stdlib_h" >&5
+$as_echo "$gl_cv_next_stdlib_h" >&6; }
+     fi
+     NEXT_STDLIB_H=$gl_cv_next_stdlib_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'stdlib.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_stdlib_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_STDLIB_H=$gl_next_as_first_directive
+
+
+
+
+  for ac_header in random.h
+do :
+  ac_fn_c_check_header_compile "$LINENO" "random.h" "ac_cv_header_random_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_random_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_RANDOM_H 1
+_ACEOF
+
+fi
+
+done
+
+  if test $ac_cv_header_random_h = yes; then
+    HAVE_RANDOM_H=1
+  else
+    HAVE_RANDOM_H=0
+  fi
+
+  ac_fn_c_check_type "$LINENO" "struct random_data" "ac_cv_type_struct_random_data" "#include <stdlib.h>
+      #if HAVE_RANDOM_H
+      # include <random.h>
+      #endif
+
+"
+if test "x$ac_cv_type_struct_random_data" = x""yes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_RANDOM_DATA 1
+_ACEOF
+
+
+else
+  HAVE_STRUCT_RANDOM_DATA=0
+fi
+
+
+
+    for gl_func in _Exit atoll canonicalize_file_name getloadavg getsubopt grantpt mkdtemp     mkostemp mkostemps mkstemp mkstemps ptsname random_r initstat_r srandom_r     setstate_r realpath rpmatch setenv strtod strtoll strtoull unlockpt     unsetenv; do
+    as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5
+$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; }
+if { as_var=$as_gl_Symbol; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+#if HAVE_SYS_LOADAVG_H
+# include <sys/loadavg.h>
+#endif
+#if HAVE_RANDOM_H
+# include <random.h>
+#endif
+
+int
+main ()
+{
+#undef $gl_func
+  (void) $gl_func;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_gl_Symbol=yes"
+else
+  eval "$as_gl_Symbol=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_gl_Symbol
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+     eval as_val=\$$as_gl_Symbol
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1
+_ACEOF
+
+                     eval ac_cv_have_decl_$gl_func=yes
+fi
+      done
+
+
+  # Code from module streq:
+  # Code from module unistd:
+
+
+
+
+
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_unistd_h='<'unistd.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <unistd.h>" >&5
+$as_echo_n "checking absolute name of <unistd.h>... " >&6; }
+if test "${gl_cv_next_unistd_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+             if test $ac_cv_header_unistd_h = yes; then
+
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <unistd.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_unistd_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/unistd.h#{
+                    s#.*"\(.*/unistd.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+          else
+               gl_cv_next_unistd_h='<'unistd.h'>'
+             fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_unistd_h" >&5
+$as_echo "$gl_cv_next_unistd_h" >&6; }
+     fi
+     NEXT_UNISTD_H=$gl_cv_next_unistd_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'unistd.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_unistd_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_UNISTD_H=$gl_next_as_first_directive
+
+
+
+
+  if test $ac_cv_header_unistd_h = yes; then
+    HAVE_UNISTD_H=1
+  else
+    HAVE_UNISTD_H=0
+  fi
+
+
+
+    for gl_func in chown dup2 dup3 environ euidaccess faccessat fchdir fchownat     fsync ftruncate getcwd getdomainname getdtablesize getgroups     gethostname getlogin getlogin_r getpagesize getusershell setusershell     endusershell lchown link linkat lseek pipe pipe2 pread pwrite readlink     readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat     usleep; do
+    as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5
+$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; }
+if { as_var=$as_gl_Symbol; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <unistd.h>
+/* Some systems declare various items in the wrong headers.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <fcntl.h>
+# include <stdio.h>
+# include <stdlib.h>
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+
+int
+main ()
+{
+#undef $gl_func
+  (void) $gl_func;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_gl_Symbol=yes"
+else
+  eval "$as_gl_Symbol=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_gl_Symbol
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+     eval as_val=\$$as_gl_Symbol
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1
+_ACEOF
+
+                     eval ac_cv_have_decl_$gl_func=yes
+fi
+      done
+
+
+  # Code from module verify:
+  # Code from module warn-on-use:
+  # Code from module wchar:
+
+
+
+
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_wchar_h='<'wchar.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <wchar.h>" >&5
+$as_echo_n "checking absolute name of <wchar.h>... " >&6; }
+if test "${gl_cv_next_wchar_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+             if test $ac_cv_header_wchar_h = yes; then
+
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <wchar.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_wchar_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/wchar.h#{
+                    s#.*"\(.*/wchar.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+          else
+               gl_cv_next_wchar_h='<'wchar.h'>'
+             fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_wchar_h" >&5
+$as_echo "$gl_cv_next_wchar_h" >&6; }
+     fi
+     NEXT_WCHAR_H=$gl_cv_next_wchar_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'wchar.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_wchar_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_WCHAR_H=$gl_next_as_first_directive
+
+
+
+
+  if test $ac_cv_header_wchar_h = yes; then
+    HAVE_WCHAR_H=1
+  else
+    HAVE_WCHAR_H=0
+  fi
+
+
+
+
+
+  if test $gt_cv_c_wint_t = yes; then
+    HAVE_WINT_T=1
+  else
+    HAVE_WINT_T=0
+  fi
+
+
+
+    for gl_func in btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb     wcsrtombs wcsnrtombs wcwidth; do
+    as_gl_Symbol=`$as_echo "gl_cv_have_raw_decl_$gl_func" | $as_tr_sh`
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $gl_func is declared without a macro" >&5
+$as_echo_n "checking whether $gl_func is declared without a macro... " >&6; }
+if { as_var=$as_gl_Symbol; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <stddef.h>
+# include <stdio.h>
+# include <time.h>
+#endif
+#include <wchar.h>
+
+int
+main ()
+{
+#undef $gl_func
+  (void) $gl_func;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  eval "$as_gl_Symbol=yes"
+else
+  eval "$as_gl_Symbol=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_gl_Symbol
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+     eval as_val=\$$as_gl_Symbol
+   if test "x$as_val" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_RAW_DECL_$gl_func" | $as_tr_cpp` 1
+_ACEOF
+
+                     eval ac_cv_have_decl_$gl_func=yes
+fi
+      done
+
+
+  # Code from module wcrtomb:
+
+
+
+
+
+
+
+
+
+
+  if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc handles incomplete characters" >&5
+$as_echo_n "checking whether mbrtowc handles incomplete characters... " >&6; }
+if test "${gl_cv_func_mbrtowc_incomplete_state+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                     # Guess no on AIX and OSF/1.
+        aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
+                     # Guess yes otherwise.
+        *)           gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
+      esac
+      if test $LOCALE_JA != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        if (mbsinit (&state))
+          return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_incomplete_state=yes
+else
+  gl_cv_func_mbrtowc_incomplete_state=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_incomplete_state" >&5
+$as_echo "$gl_cv_func_mbrtowc_incomplete_state" >&6; }
+
+
+
+
+     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbrtowc works as well as mbtowc" >&5
+$as_echo_n "checking whether mbrtowc works as well as mbtowc... " >&6; }
+if test "${gl_cv_func_mbrtowc_sanitycheck+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                  case "$host_os" in
+                    # Guess no on Solaris 8.
+        solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
+                    # Guess yes otherwise.
+        *)          gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
+      esac
+      if test $LOCALE_ZH_CN != none; then
+        if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 8:
+     mbrtowc returns 2, and sets wc to 0x00F0.
+     mbtowc returns 4 (correct) and sets wc to 0x5EDC.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 3, 6, &state) != 4
+          && mbtowc (&wc, input + 3, 6) == 4)
+        return 1;
+    }
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_mbrtowc_sanitycheck=yes
+else
+  gl_cv_func_mbrtowc_sanitycheck=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+      fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_mbrtowc_sanitycheck" >&5
+$as_echo "$gl_cv_func_mbrtowc_sanitycheck" >&6; }
+
+    REPLACE_MBSTATE_T=0
+    case "$gl_cv_func_mbrtowc_incomplete_state" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+    case "$gl_cv_func_mbrtowc_sanitycheck" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+  else
+    REPLACE_MBSTATE_T=1
+  fi
+  if test $REPLACE_MBSTATE_T = 1; then
+
+    :
+
+  fi
+
+
+
+  if test $ac_cv_func_wcrtomb = no; then
+    HAVE_WCRTOMB=0
+  else
+    if test $REPLACE_MBSTATE_T = 1; then
+      REPLACE_WCRTOMB=1
+    else
+
+
+
+
+
+             { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether wcrtomb return value is correct" >&5
+$as_echo_n "checking whether wcrtomb return value is correct... " >&6; }
+if test "${gl_cv_func_wcrtomb_retval+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+                              case "$host_os" in
+                                     # Guess no on AIX 4, OSF/1 and Solaris.
+            aix4* | osf* | solaris*) gl_cv_func_wcrtomb_retval="guessing no" ;;
+                                     # Guess yes otherwise.
+            *)                       gl_cv_func_wcrtomb_retval="guessing yes" ;;
+          esac
+          if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then
+            if test "$cross_compiling" = yes; then :
+  :
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  int result = 0;
+  if (setlocale (LC_ALL, "$LOCALE_FR") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 1;
+    }
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 2;
+    }
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 4;
+    }
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 8;
+    }
+  return result;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_wcrtomb_retval=yes
+else
+  gl_cv_func_wcrtomb_retval=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+          fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_wcrtomb_retval" >&5
+$as_echo "$gl_cv_func_wcrtomb_retval" >&6; }
+      case "$gl_cv_func_wcrtomb_retval" in
+        *yes) ;;
+        *) REPLACE_WCRTOMB=1 ;;
+      esac
+    fi
+  fi
+  if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
+
+    :
+
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS wcrtomb.$ac_objext"
+
+
+  :
+
+  fi
+
+
+
+
+  GNULIB_WCRTOMB=1
+
+
+
+$as_echo "#define GNULIB_TEST_WCRTOMB 1" >>confdefs.h
+
+
+
+  # Code from module wctype:
+
+
+
+
+  if test $ac_cv_func_iswcntrl = yes; then
+    HAVE_ISWCNTRL=1
+  else
+    HAVE_ISWCNTRL=0
+  fi
+
+
+
+  if test $ac_cv_func_iswblank = yes; then
+    HAVE_ISWBLANK=1
+    REPLACE_ISWBLANK=0
+  else
+    HAVE_ISWBLANK=0
+    if test $ac_cv_have_decl_iswblank = yes; then
+      REPLACE_ISWBLANK=1
+    else
+      REPLACE_ISWBLANK=0
+    fi
+  fi
+
+
+
+
+
+
+  if test $gt_cv_c_wint_t = yes; then
+    HAVE_WINT_T=1
+  else
+    HAVE_WINT_T=0
+  fi
+
+
+
+
+
+
+
+
+
+
+
+     if test $gl_cv_have_include_next = yes; then
+       gl_cv_next_wctype_h='<'wctype.h'>'
+     else
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking absolute name of <wctype.h>" >&5
+$as_echo_n "checking absolute name of <wctype.h>... " >&6; }
+if test "${gl_cv_next_wctype_h+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+             if test $ac_cv_header_wctype_h = yes; then
+
+
+               cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <wctype.h>
+
+_ACEOF
+                                                                                                                        case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+                                                            gl_cv_next_wctype_h='"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&5 |
+                  sed -n '\#/wctype.h#{
+                    s#.*"\(.*/wctype.h\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'
+          else
+               gl_cv_next_wctype_h='<'wctype.h'>'
+             fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_next_wctype_h" >&5
+$as_echo "$gl_cv_next_wctype_h" >&6; }
+     fi
+     NEXT_WCTYPE_H=$gl_cv_next_wctype_h
+
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'wctype.h'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=$gl_cv_next_wctype_h
+     fi
+     NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H=$gl_next_as_first_directive
+
+
+
+
+  if test $ac_cv_header_wctype_h = yes; then
+    if test $ac_cv_func_iswcntrl = yes; then
+                  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether iswcntrl works" >&5
+$as_echo_n "checking whether iswcntrl works... " >&6; }
+if test "${gl_cv_func_iswcntrl_works+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+
+          if test "$cross_compiling" = yes; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdlib.h>
+                          #if __GNU_LIBRARY__ == 1
+                          Linux libc5 i18n is broken.
+                          #endif
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gl_cv_func_iswcntrl_works=yes
+else
+  gl_cv_func_iswcntrl_works=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+               /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be
+                  included before <wchar.h>.
+                  BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h>
+                  must be included before <wchar.h>.  */
+               #include <stddef.h>
+               #include <stdio.h>
+               #include <time.h>
+               #include <wchar.h>
+               #include <wctype.h>
+               int main () { return iswprint ('x') == 0; }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gl_cv_func_iswcntrl_works=yes
+else
+  gl_cv_func_iswcntrl_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_func_iswcntrl_works" >&5
+$as_echo "$gl_cv_func_iswcntrl_works" >&6; }
+    fi
+    HAVE_WCTYPE_H=1
+  else
+    HAVE_WCTYPE_H=0
+  fi
+
+
+  if test "$gl_cv_func_iswcntrl_works" = no; then
+    REPLACE_ISWCNTRL=1
+  else
+    REPLACE_ISWCNTRL=0
+  fi
+
+
+  if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then
+        :
+  else
+    if test $HAVE_ISWBLANK = 0 || test $REPLACE_ISWBLANK = 1; then
+
+
+
+
+
+
+
+
+  gl_LIBOBJS="$gl_LIBOBJS iswblank.$ac_objext"
+
+    fi
+  fi
+
+  # End of code from modules
+
+
+
+
+
+
+
+
+
+  gltests_libdeps=
+  gltests_ltlibdeps=
+
+
+
+
+
+
+
+
+
+  gl_source_base='tests'
+  gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS
+
+  gl_module_indicator_condition=$gltests_WITNESS
+
+
+
+
+
+
+
+
+
+
+
+
+curlprivatereq=
+curlprivatelibs=
+libdap_pkgconfig_libcurl=yes
+libdap_libcurl_module='libcurl >= 7.10.6'
+
+
+if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
+	if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+$as_echo "$PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_ac_pt_PKG_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+$as_echo "$ac_pt_PKG_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
+else
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+fi
+
+fi
+if test -n "$PKG_CONFIG"; then
+	_pkg_min_version=0.9.0
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5
+$as_echo_n "checking pkg-config is at least version $_pkg_min_version... " >&6; }
+	if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	else
+		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+		PKG_CONFIG=""
+	fi
+
+fi
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for CURL" >&5
+$as_echo_n "checking for CURL... " >&6; }
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$CURL_CFLAGS"; then
+        pkg_cv_CURL_CFLAGS="$CURL_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$libdap_libcurl_module\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "$libdap_libcurl_module") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_CURL_CFLAGS=`$PKG_CONFIG --cflags "$libdap_libcurl_module" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$CURL_LIBS"; then
+        pkg_cv_CURL_LIBS="$CURL_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$libdap_libcurl_module\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "$libdap_libcurl_module") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_CURL_LIBS=`$PKG_CONFIG --libs "$libdap_libcurl_module" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        CURL_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$libdap_libcurl_module"`
+        else
+	        CURL_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$libdap_libcurl_module"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$CURL_PKG_ERRORS" >&5
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                libdap_pkgconfig_libcurl=no
+elif test $pkg_failed = untried; then
+	libdap_pkgconfig_libcurl=no
+else
+	CURL_CFLAGS=$pkg_cv_CURL_CFLAGS
+	CURL_LIBS=$pkg_cv_CURL_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	:
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libcurl" >&5
+$as_echo_n "checking for libcurl... " >&6; }
+if test $libdap_pkgconfig_libcurl = 'yes'
+then
+	curlprivatereq=$libdap_libcurl_module
+	CURL_STATIC_LIBS="`$PKG_CONFIG --static --libs libcurl`"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; used pkg-config" >&5
+$as_echo "yes; used pkg-config" >&6; }
+elif curl-config --version > /dev/null 2>&1
+then
+	version_libcurl=`curl-config --version | sed 's at libcurl \(.*\)@\1@'`
+
+	version_M=`echo $version_libcurl | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\1@'`
+	version_m=`echo $version_libcurl | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\2@'`
+	version_m_m=`echo $version_libcurl | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\3@'`
+
+
+
+	if test $version_M -gt 7
+	then
+		libcurl_ok='yes'
+	elif test $version_M -eq 7 && test $version_m -gt 10
+	then
+		libcurl_ok='yes'
+	elif test $version_M -eq 7 && test $version_m -eq 10 && test $version_m_m -gt 5
+	then
+		libcurl_ok='yes'
+	else
+		libcurl_ok='no'
+	fi
+
+		if test $libcurl_ok = "no"
+	then
+		as_fn_error "must have libcurl 7.10.6 or greater, found $version_libcurl" "$LINENO" 5
+	fi
+
+	CURL_LIBS="`curl-config --libs`"
+	CURL_STATIC_LIBS=$CURL_LIBS
+	curlprivatelibs="`curl-config --libs`"
+	CURL_CFLAGS="`curl-config --cflags`"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; used curl-config" >&5
+$as_echo "yes; used curl-config" >&6; }
+else
+	as_fn_error "I could not find libcurl" "$LINENO" 5
+fi
+
+
+
+
+
+
+xmlprivatereq=
+xmlprivatelibs=
+libdap_pkgconfig_libxml2=yes
+libdap_libxml2_module='libxml-2.0 >= 2.6.16'
+
+pkg_failed=no
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for XML2" >&5
+$as_echo_n "checking for XML2... " >&6; }
+
+if test -n "$PKG_CONFIG"; then
+    if test -n "$XML2_CFLAGS"; then
+        pkg_cv_XML2_CFLAGS="$XML2_CFLAGS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$libdap_libxml2_module\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "$libdap_libxml2_module") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_XML2_CFLAGS=`$PKG_CONFIG --cflags "$libdap_libxml2_module" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+if test -n "$PKG_CONFIG"; then
+    if test -n "$XML2_LIBS"; then
+        pkg_cv_XML2_LIBS="$XML2_LIBS"
+    else
+        if test -n "$PKG_CONFIG" && \
+    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"\$libdap_libxml2_module\""; } >&5
+  ($PKG_CONFIG --exists --print-errors "$libdap_libxml2_module") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+  pkg_cv_XML2_LIBS=`$PKG_CONFIG --libs "$libdap_libxml2_module" 2>/dev/null`
+else
+  pkg_failed=yes
+fi
+    fi
+else
+	pkg_failed=untried
+fi
+
+
+
+if test $pkg_failed = yes; then
+
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+        _pkg_short_errors_supported=yes
+else
+        _pkg_short_errors_supported=no
+fi
+        if test $_pkg_short_errors_supported = yes; then
+	        XML2_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$libdap_libxml2_module"`
+        else
+	        XML2_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$libdap_libxml2_module"`
+        fi
+	# Put the nasty error message in config.log where it belongs
+	echo "$XML2_PKG_ERRORS" >&5
+
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+                libdap_pkgconfig_libxml2=no
+elif test $pkg_failed = untried; then
+	libdap_pkgconfig_libxml2=no
+else
+	XML2_CFLAGS=$pkg_cv_XML2_CFLAGS
+	XML2_LIBS=$pkg_cv_XML2_LIBS
+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+	:
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for libxml2" >&5
+$as_echo_n "checking for libxml2... " >&6; }
+if test $libdap_pkgconfig_libxml2 = 'yes'
+then
+	xmlprivatereq=$libdap_libxml2_module
+	XML2_STATIC_LIBS="`$PKG_CONFIG --static --libs libxml-2.0`"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; used pkg-config" >&5
+$as_echo "yes; used pkg-config" >&6; }
+elif xml2-config --version > /dev/null 2>&1
+then
+	version_libxml2=`xml2-config --version`
+	version_M=`echo $version_libxml2 | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\1@'`
+	version_m=`echo $version_libxml2 | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\2@'`
+	version_m_m=`echo $version_libxml2 | sed 's@^\([0-9]\)*\.\([0-9]*\)\.\([0-9]*\)$@\3@'`
+
+	if test $version_M -gt 2
+	then
+		libxml2_ok='yes'
+	elif test $version_M -eq 2 && test $version_m -eq 6 && test $version_m_m -ge 16
+	then
+                libxml2_ok='yes'
+	fi
+
+	XML2_LIBS="`xml2-config --libs`"
+	XML2_STATIC_LIBS=$XML2_LIBS
+	XML2_CFLAGS="`xml2-config --cflags`"
+	xmlprivatelibs="`xml2-config --libs`"
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes; used xml2-config" >&5
+$as_echo "yes; used xml2-config" >&6; }
+else
+	as_fn_error "I could not find libxml2 2.6.16 or newer" "$LINENO" 5
+fi
+
+
+
+
+
+
+#
+# Handle user hints
+#
+
+
+# Check whether --with-zlib was given.
+if test "${with_zlib+set}" = set; then :
+  withval=$with_zlib; if test "$withval" != no ; then
+  if test -d "$withval"
+  then
+    ZLIB_HOME="$withval"
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Sorry, $withval does not exist, checking usual places" >&5
+$as_echo "$as_me: WARNING: Sorry, $withval does not exist, checking usual places" >&2;}
+  fi
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: zlib is required for deflate, not disabled" >&5
+$as_echo "$as_me: WARNING: zlib is required for deflate, not disabled" >&2;}
+fi
+fi
+
+
+ZLIB_OLD_LDFLAGS=$LDFLAGS
+ZLIB_OLD_CPPFLAGS=$CPPFLAGS
+
+#
+# Locate zlib, if wanted
+#
+if test -n "${ZLIB_HOME}"
+then
+        LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
+        CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
+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
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inflateEnd in -lz" >&5
+$as_echo_n "checking for inflateEnd in -lz... " >&6; }
+if test "${ac_cv_lib_z_inflateEnd+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lz  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inflateEnd ();
+int
+main ()
+{
+return inflateEnd ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_z_inflateEnd=yes
+else
+  ac_cv_lib_z_inflateEnd=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_inflateEnd" >&5
+$as_echo "$ac_cv_lib_z_inflateEnd" >&6; }
+if test "x$ac_cv_lib_z_inflateEnd" = x""yes; then :
+  zlib_cv_libz=yes
+else
+  zlib_cv_libz=no
+fi
+
+ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = x""yes; then :
+  zlib_cv_zlib_h=yes
+else
+  zlib_cv_zlib_h=no
+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
+
+
+if test "$zlib_cv_libz" = "yes" -a "$zlib_cv_zlib_h" = "yes"
+then
+        #
+        # If both library and header were found, use them
+        #
+        ZLIB_LIBS="-lz"
+else
+        #
+        # If either header or library was not found, revert and bomb
+        #
+        as_fn_error "zlib is required for deflate, specify a valid zlib installation with --with-zlib=DIR" "$LINENO" 5
+fi
+
+LDFLAGS="$ZLIB_OLD_LDFLAGS"
+CPPFLAGS="$ZLIB_OLD_CPPFLAGS"
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_kill in -lpthread" >&5
+$as_echo_n "checking for pthread_kill in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_kill+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_kill ();
+int
+main ()
+{
+return pthread_kill ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_pthread_pthread_kill=yes
+else
+  ac_cv_lib_pthread_pthread_kill=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_kill" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_kill" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_kill" = x""yes; then :
+  PTHREAD_LIBS="-lpthread"
+else
+  as_fn_error "I could not find pthreads" "$LINENO" 5
+fi
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uuid_generate in -luuid" >&5
+$as_echo_n "checking for uuid_generate in -luuid... " >&6; }
+if test "${ac_cv_lib_uuid_uuid_generate+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-luuid  $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char uuid_generate ();
+int
+main ()
+{
+return uuid_generate ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_uuid_uuid_generate=yes
+else
+  ac_cv_lib_uuid_uuid_generate=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_uuid_uuid_generate" >&5
+$as_echo "$ac_cv_lib_uuid_uuid_generate" >&6; }
+if test "x$ac_cv_lib_uuid_uuid_generate" = x""yes; then :
+  UUID_LIBS="-luuid"
+else
+  UUID_LIBS=""
+fi
+
+
+
+
+
+
+# Check whether --with-cppunit-prefix was given.
+if test "${with_cppunit_prefix+set}" = set; then :
+  withval=$with_cppunit_prefix; cppunit_config_prefix="$withval"
+else
+  cppunit_config_prefix=""
+fi
+
+
+# Check whether --with-cppunit-exec-prefix was given.
+if test "${with_cppunit_exec_prefix+set}" = set; then :
+  withval=$with_cppunit_exec_prefix; cppunit_config_exec_prefix="$withval"
+else
+  cppunit_config_exec_prefix=""
+fi
+
+
+  if test x$cppunit_config_exec_prefix != x ; then
+     cppunit_config_args="$cppunit_config_args --exec-prefix=$cppunit_config_exec_prefix"
+     if test x${CPPUNIT_CONFIG+set} != xset ; then
+        CPPUNIT_CONFIG=$cppunit_config_exec_prefix/bin/cppunit-config
+     fi
+  fi
+  if test x$cppunit_config_prefix != x ; then
+     cppunit_config_args="$cppunit_config_args --prefix=$cppunit_config_prefix"
+     if test x${CPPUNIT_CONFIG+set} != xset ; then
+        CPPUNIT_CONFIG=$cppunit_config_prefix/bin/cppunit-config
+     fi
+  fi
+
+  # Extract the first word of "cppunit-config", so it can be a program name with args.
+set dummy cppunit-config; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_CPPUNIT_CONFIG+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $CPPUNIT_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_CPPUNIT_CONFIG="$CPPUNIT_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_CPPUNIT_CONFIG="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_CPPUNIT_CONFIG" && ac_cv_path_CPPUNIT_CONFIG="no"
+  ;;
+esac
+fi
+CPPUNIT_CONFIG=$ac_cv_path_CPPUNIT_CONFIG
+if test -n "$CPPUNIT_CONFIG"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPPUNIT_CONFIG" >&5
+$as_echo "$CPPUNIT_CONFIG" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+  cppunit_version_min=1.12.0
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cppunit - version >= $cppunit_version_min" >&5
+$as_echo_n "checking for Cppunit - version >= $cppunit_version_min... " >&6; }
+  no_cppunit=""
+  if test "$CPPUNIT_CONFIG" = "no" ; then
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+    no_cppunit=yes
+  else
+    CPPUNIT_CFLAGS=`$CPPUNIT_CONFIG --cflags`
+    CPPUNIT_LIBS=`$CPPUNIT_CONFIG --libs`
+    cppunit_version=`$CPPUNIT_CONFIG --version`
+
+    cppunit_major_version=`echo $cppunit_version | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+    cppunit_minor_version=`echo $cppunit_version | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
+    cppunit_micro_version=`echo $cppunit_version | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+
+    cppunit_major_min=`echo $cppunit_version_min | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'`
+    if test "x${cppunit_major_min}" = "x" ; then
+       cppunit_major_min=0
+    fi
+
+    cppunit_minor_min=`echo $cppunit_version_min | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'`
+    if test "x${cppunit_minor_min}" = "x" ; then
+       cppunit_minor_min=0
+    fi
+
+    cppunit_micro_min=`echo $cppunit_version_min | \
+           sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'`
+    if test "x${cppunit_micro_min}" = "x" ; then
+       cppunit_micro_min=0
+    fi
+
+    cppunit_version_proper=`expr \
+        $cppunit_major_version \> $cppunit_major_min \| \
+        $cppunit_major_version \= $cppunit_major_min \& \
+        $cppunit_minor_version \> $cppunit_minor_min \| \
+        $cppunit_major_version \= $cppunit_major_min \& \
+        $cppunit_minor_version \= $cppunit_minor_min \& \
+        $cppunit_micro_version \>= $cppunit_micro_min `
+
+    if test "$cppunit_version_proper" = "1" ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version" >&5
+$as_echo "$cppunit_major_version.$cppunit_minor_version.$cppunit_micro_version" >&6; }
+    else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+      no_cppunit=yes
+    fi
+  fi
+
+  if test "x$no_cppunit" = x ; then
+      if true; then
+  CPPUNIT_TRUE=
+  CPPUNIT_FALSE='#'
+else
+  CPPUNIT_TRUE='#'
+  CPPUNIT_FALSE=
+fi
+
+  else
+     CPPUNIT_CFLAGS=""
+     CPPUNIT_LIBS=""
+      if false; then
+  CPPUNIT_TRUE=
+  CPPUNIT_FALSE='#'
+else
+  CPPUNIT_TRUE='#'
+  CPPUNIT_FALSE=
+fi
+
+  fi
+
+
+
+
+
+    # Check whether --enable-debug was given.
+if test "${enable_debug+set}" = set; then :
+  enableval=$enable_debug; DEBUG=$enableval
+else
+  DEBUG=no
+fi
+
+
+    case "$DEBUG" in
+    no)
+      ;;
+    1)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: Setting debugging to level 1" >&5
+$as_echo "Setting debugging to level 1" >&6; }
+      $as_echo "#define DODS_DEBUG 1" >>confdefs.h
+
+      ;;
+    2)
+      { $as_echo "$as_me:${as_lineno-$LINENO}: result: Setting debugging to level 2" >&5
+$as_echo "Setting debugging to level 2" >&6; }
+
+$as_echo "#define DODS_DEBUG /**/" >>confdefs.h
+
+
+$as_echo "#define DODS_DEBUG2 /**/" >>confdefs.h
+
+      ;;
+    *)
+      as_fn_error "Bad debug value" "$LINENO" 5
+      ;;
+    esac
+
+if test "$prefix" = "NONE"
+then
+
+$as_echo "#define LIBDAP_ROOT \"/usr/local\"" >>confdefs.h
+
+else
+
+cat >>confdefs.h <<_ACEOF
+#define LIBDAP_ROOT "$prefix"
+_ACEOF
+
+fi
+
+
+
+
+
+
+ac_config_files="$ac_config_files Makefile libdap.pc libdapclient.pc libdapserver.pc gl/Makefile tests/Makefile tests/atlocal unit-tests/Makefile unit-tests/cache-testsuite/Makefile"
+
+ac_config_files="$ac_config_files dap-config"
+
+
+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, we kill variables containing newlines.
+# 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.
+(
+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+    eval ac_val=\$$ac_var
+    case $ac_val in #(
+    *${as_nl}*)
+      case $ac_var in #(
+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      esac
+      case $ac_var in #(
+      _ | IFS | as_nl) ;; #(
+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+      *) { eval $ac_var=; unset $ac_var;} ;;
+      esac ;;
+    esac
+  done
+
+  (set) 2>&1 |
+    case $as_nl`(ac_space=' '; set) 2>&1` in #(
+    *${as_nl}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 "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+      ;;
+    esac |
+    sort
+) |
+  sed '
+     /^ac_cv_env_/b end
+     t clear
+     :clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     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" &&
+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+    cat confcache >$cache_file
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+  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}'
+
+DEFS=-DHAVE_CONFIG_H
+
+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_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
+  #    will be set to the directory where LIBOBJS objects are built.
+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+  am__EXEEXT_TRUE=
+  am__EXEEXT_FALSE='#'
+else
+  am__EXEEXT_TRUE='#'
+  am__EXEEXT_FALSE=
+fi
+
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+  as_fn_error "conditional \"AMDEP\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
+  as_fn_error "conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${USE_C99_TYPES_TRUE}" && test -z "${USE_C99_TYPES_FALSE}"; then
+  as_fn_error "conditional \"USE_C99_TYPES\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${COMPILER_IS_GCC_TRUE}" && test -z "${COMPILER_IS_GCC_FALSE}"; then
+  as_fn_error "conditional \"COMPILER_IS_GCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${COMPILER_IS_GCC_TRUE}" && test -z "${COMPILER_IS_GCC_FALSE}"; then
+  as_fn_error "conditional \"COMPILER_IS_GCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${GL_COND_LIBTOOL_TRUE}" && test -z "${GL_COND_LIBTOOL_FALSE}"; then
+  as_fn_error "conditional \"GL_COND_LIBTOOL\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+    gl_libobjs=
+    gl_ltlibobjs=
+    if test -n "$gl_LIBOBJS"; then
+      # Remove the extension.
+      sed_drop_objext='s/\.o$//;s/\.obj$//'
+      for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+        gl_libobjs="$gl_libobjs $i.$ac_objext"
+        gl_ltlibobjs="$gl_ltlibobjs $i.lo"
+      done
+    fi
+    gl_LIBOBJS=$gl_libobjs
+
+    gl_LTLIBOBJS=$gl_ltlibobjs
+
+
+
+    gltests_libobjs=
+    gltests_ltlibobjs=
+    if test -n "$gltests_LIBOBJS"; then
+      # Remove the extension.
+      sed_drop_objext='s/\.o$//;s/\.obj$//'
+      for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+        gltests_libobjs="$gltests_libobjs $i.$ac_objext"
+        gltests_ltlibobjs="$gltests_ltlibobjs $i.lo"
+      done
+    fi
+    gltests_LIBOBJS=$gltests_libobjs
+
+    gltests_LTLIBOBJS=$gltests_ltlibobjs
+
+
+if test -z "${CPPUNIT_TRUE}" && test -z "${CPPUNIT_FALSE}"; then
+  as_fn_error "conditional \"CPPUNIT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+if test -z "${CPPUNIT_TRUE}" && test -z "${CPPUNIT_FALSE}"; then
+  as_fn_error "conditional \"CPPUNIT\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $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}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+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
+IFS=$as_save_IFS
+
+     ;;
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+# 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
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# 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'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by libdap $as_me 3.11.1, which was
+generated by GNU Autoconf 2.65.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+case $ac_config_headers in *"
+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
+esac
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_headers="$ac_config_headers"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration.  Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
+  -q, --quiet, --silent
+                   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
+      --header=FILE[:TEMPLATE]
+                   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Configuration commands:
+$config_commands
+
+Report bugs to <opendap-tech at opendap.org>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_version="\\
+libdap config.status 3.11.1
+configured by $0, generated by GNU Autoconf 2.65,
+  with options \\"\$ac_cs_config\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+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
+    ;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+    $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
+  --debug | --debu | --deb | --de | --d | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_FILES " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    case $ac_optarg in
+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"
+    ac_need_defaults=false;;
+  --he | --h)
+    # Conflict between --help and --header
+    as_fn_error "ambiguous option: \`$1'
+Try \`$0 --help' for more information.";;
+  --help | --hel | -h )
+    $as_echo "$ac_cs_usage"; exit ;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+  *) as_fn_append ac_config_targets " $1"
+     ac_need_defaults=false ;;
+
+  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 || ac_write_fail=1
+if \$ac_cs_recheck; then
+  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  shift
+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  CONFIG_SHELL='$SHELL'
+  export CONFIG_SHELL
+  exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+  $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
+
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
+enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
+host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
+host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
+host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
+build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
+build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
+build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
+SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
+Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
+GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
+EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
+FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
+LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
+NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
+LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
+exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
+AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
+compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
+GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
+SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
+ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
+need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
+LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
+libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
+need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
+version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
+striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`'
+predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`'
+postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# Quote evaled strings.
+for var in SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+SHELL \
+ECHO \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_flag_spec_ld_CXX \
+hardcode_libdir_separator_CXX \
+fix_srcfile_path_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX; do
+    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    *[\\\\\\\`\\"\\\$]*)
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      ;;
+    *)
+      eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+      ;;
+    esac
+done
+
+# Fix-up fallback echo if it was mangled by the above quoting rules.
+case \$lt_ECHO in
+*'\\\$0 --fallback-echo"')  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
+  ;;
+esac
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+   setopt NO_GLOB_SUBST
+fi
+
+
+    PACKAGE='$PACKAGE'
+    VERSION='$VERSION'
+    TIMESTAMP='$TIMESTAMP'
+    RM='$RM'
+    ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+for ac_config_target in $ac_config_targets
+do
+  case $ac_config_target in
+    "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+    "dods-datatypes-config.h") CONFIG_HEADERS="$CONFIG_HEADERS dods-datatypes-config.h" ;;
+    "xdr-datatypes-config.h") CONFIG_HEADERS="$CONFIG_HEADERS xdr-datatypes-config.h" ;;
+    "tests/atconfig") CONFIG_COMMANDS="$CONFIG_COMMANDS tests/atconfig" ;;
+    "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+    "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+    "libdap.pc") CONFIG_FILES="$CONFIG_FILES libdap.pc" ;;
+    "libdapclient.pc") CONFIG_FILES="$CONFIG_FILES libdapclient.pc" ;;
+    "libdapserver.pc") CONFIG_FILES="$CONFIG_FILES libdapserver.pc" ;;
+    "gl/Makefile") CONFIG_FILES="$CONFIG_FILES gl/Makefile" ;;
+    "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+    "tests/atlocal") CONFIG_FILES="$CONFIG_FILES tests/atlocal" ;;
+    "unit-tests/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/Makefile" ;;
+    "unit-tests/cache-testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES unit-tests/cache-testsuite/Makefile" ;;
+    "dap-config") CONFIG_FILES="$CONFIG_FILES dap-config" ;;
+
+  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  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
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+  tmp=
+  trap 'exit_status=$?
+  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+  trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./conf$$-$RANDOM
+  (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+  eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+  ac_cs_awk_cr='\r'
+else
+  ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+  echo "cat >conf$$subs.awk <<_ACEOF" &&
+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+  echo "_ACEOF"
+} >conf$$subs.sh ||
+  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  . ./conf$$subs.sh ||
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+  if test $ac_delim_n = $ac_delim_num; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+  N
+  s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+  for (key in S) S_is_set[key] = 1
+  FS = ""
+
+}
+{
+  line = $ 0
+  nfields = split(line, field, "@")
+  substed = 0
+  len = length(field[1])
+  for (i = 2; i < nfields; i++) {
+    key = field[i]
+    keylen = length(key)
+    if (S_is_set[key]) {
+      value = S[key]
+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+      len += length(value) + length(field[++i])
+      substed = 1
+    } else
+      len += 1 + keylen
+  }
+
+  print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+  cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# 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
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+# Set up the scripts for CONFIG_HEADERS section.
+# No need to generate them if there are no CONFIG_HEADERS.
+# This happens for instance with `./config.status Makefile'.
+if test -n "$CONFIG_HEADERS"; then
+cat >"$tmp/defines.awk" <<\_ACAWK ||
+BEGIN {
+_ACEOF
+
+# Transform confdefs.h into an awk script `defines.awk', embedded as
+# here-document in config.status, that substitutes the proper values into
+# config.h.in to produce config.h.
+
+# Create a delimiter string that does not exist in confdefs.h, to ease
+# handling of long lines.
+ac_delim='%!_!# '
+for ac_last_try in false false :; do
+  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_t"; then
+    break
+  elif $ac_last_try; then
+    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+# For the awk script, D is an array of macro values keyed by name,
+# likewise P contains macro parameters if any.  Preserve backslash
+# newline sequences.
+
+ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
+sed -n '
+s/.\{148\}/&'"$ac_delim"'/g
+t rset
+:rset
+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /
+t def
+d
+:def
+s/\\$//
+t bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3"/p
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p
+d
+:bsnl
+s/["\\]/\\&/g
+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\
+D["\1"]=" \3\\\\\\n"\\/p
+t cont
+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
+t cont
+d
+:cont
+n
+s/.\{148\}/&'"$ac_delim"'/g
+t clear
+:clear
+s/\\$//
+t bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/"/p
+d
+:bsnlc
+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
+b cont
+' <confdefs.h | sed '
+s/'"$ac_delim"'/"\\\
+"/g' >>$CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  for (key in D) D_is_set[key] = 1
+  FS = ""
+}
+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
+  line = \$ 0
+  split(line, arg, " ")
+  if (arg[1] == "#") {
+    defundef = arg[2]
+    mac1 = arg[3]
+  } else {
+    defundef = substr(arg[1], 2)
+    mac1 = arg[2]
+  }
+  split(mac1, mac2, "(") #)
+  macro = mac2[1]
+  prefix = substr(line, 1, index(line, defundef) - 1)
+  if (D_is_set[macro]) {
+    # Preserve the white space surrounding the "#".
+    print prefix "define", macro P[macro] D[macro]
+    next
+  } else {
+    # Replace #undef with comments.  This is necessary, for example,
+    # in the case of _POSIX_SOURCE, which is predefined and required
+    # on some systems where configure will not decide to define it.
+    if (defundef == "undef") {
+      print "/*", prefix defundef, macro, "*/"
+      next
+    }
+  }
+}
+{ print }
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+fi # test -n "$CONFIG_HEADERS"
+
+
+eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+  case $ac_tag in
+  :[FHLC]) ac_mode=$ac_tag; continue;;
+  esac
+  case $ac_mode$ac_tag in
+  :[FHL]*:*);;
+  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :[FH]-) ac_tag=-:-;;
+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+  esac
+  ac_save_IFS=$IFS
+  IFS=:
+  set x $ac_tag
+  IFS=$ac_save_IFS
+  shift
+  ac_file=$1
+  shift
+
+  case $ac_mode in
+  :L) ac_source=$1;;
+  :[FH])
+    ac_file_inputs=
+    for ac_f
+    do
+      case $ac_f in
+      -) ac_f="$tmp/stdin";;
+      *) # Look for the file first in the build tree, then in the source tree
+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,
+	 # because $ac_f cannot contain `:'.
+	 test -f "$ac_f" ||
+	   case $ac_f in
+	   [\\/$]*) false;;
+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+	   esac ||
+	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+      esac
+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      as_fn_append ac_file_inputs " '$ac_f'"
+    done
+
+    # 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.  */
+    configure_input='Generated from '`
+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	`' by configure.'
+    if test x"$ac_file" != x-; then
+      configure_input="$ac_file.  $configure_input"
+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+    fi
+    # Neutralize special characters interpreted by sed in replacement strings.
+    case $configure_input in #(
+    *\&* | *\|* | *\\* )
+       ac_sed_conf_input=`$as_echo "$configure_input" |
+       sed 's/[\\\\&|]/\\\\&/g'`;; #(
+    *) ac_sed_conf_input=$configure_input;;
+    esac
+
+    case $ac_tag in
+    *:-:* | *:-) cat >"$tmp/stdin" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    esac
+    ;;
+  esac
+
+  ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+  as_dir="$ac_dir"; as_fn_mkdir_p
+  ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  # A ".." for each directory in $ac_dir_suffix.
+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  case $ac_top_builddir_sub in
+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+  esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+  .)  # We are building in place.
+    ac_srcdir=.
+    ac_top_srcdir=$ac_top_builddir_sub
+    ac_abs_top_srcdir=$ac_pwd ;;
+  [\\/]* | ?:[\\/]* )  # Absolute name.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir
+    ac_abs_top_srcdir=$srcdir ;;
+  *) # Relative name.
+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_build_prefix$srcdir
+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+  case $ac_mode in
+  :F)
+  #
+  # CONFIG_FILE
+  #
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+  esac
+  ac_MKDIR_P=$MKDIR_P
+  case $MKDIR_P in
+  [\\/$]* | ?:[\\/]* ) ;;
+  */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+  esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+  p
+  q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+  ac_datarootdir_hack='
+  s&@datadir@&$datadir&g
+  s&@docdir@&$docdir&g
+  s&@infodir@&$infodir&g
+  s&@localedir@&$localedir&g
+  s&@mandir@&$mandir&g
+  s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;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&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined.  Please make sure it is defined." >&2;}
+
+  rm -f "$tmp/stdin"
+  case $ac_file in
+  -) cat "$tmp/out" && rm -f "$tmp/out";;
+  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  esac \
+  || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+  :H)
+  #
+  # CONFIG_HEADER
+  #
+  if test x"$ac_file" != x-; then
+    {
+      $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
+    } >"$tmp/config.h" \
+      || as_fn_error "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+$as_echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      rm -f "$ac_file"
+      mv "$tmp/config.h" "$ac_file" \
+	|| as_fn_error "could not create $ac_file" "$LINENO" 5
+    fi
+  else
+    $as_echo "/* $configure_input  */" \
+      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error "could not create -" "$LINENO" 5
+  fi
+# Compute "$ac_file"'s index in $config_headers.
+_am_arg="$ac_file"
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+  case $_am_header in
+    $_am_arg | $_am_arg:* )
+      break ;;
+    * )
+      _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+  esac
+done
+echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
+$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$_am_arg" : 'X\(//\)[^/]' \| \
+	 X"$_am_arg" : 'X\(//\)$' \| \
+	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$_am_arg" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/stamp-h$_am_stamp_count
+ ;;
+
+  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+  esac
+
+
+  case $ac_file$ac_mode in
+    "tests/atconfig":C) cat >tests/atconfig <<ATEOF
+# Configurable variable values for building test suites.
+# Generated by $0.
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# The test suite will define top_srcdir=$at_top_srcdir/../.. etc.
+at_testdir='tests'
+abs_builddir='$ac_abs_builddir'
+at_srcdir='$ac_srcdir'
+abs_srcdir='$ac_abs_srcdir'
+at_top_srcdir='$ac_top_srcdir'
+abs_top_srcdir='$ac_abs_top_srcdir'
+at_top_build_prefix='$ac_top_build_prefix'
+abs_top_builddir='$ac_abs_top_builddir'
+
+# Backward compatibility with Autotest <= 2.59b:
+at_top_builddir=\$at_top_build_prefix
+
+AUTOTEST_PATH='.'
+
+SHELL=\${CONFIG_SHELL-'$SHELL'}
+ATEOF
+ ;;
+    "depfiles":C) test x"$AMDEP_TRUE" != x"" || {
+  # Autoconf 2.62 quotes --file arguments for eval, but not when files
+  # are listed without --file.  Let's play safe and only enable the eval
+  # if we detect the quoting.
+  case $CONFIG_FILES in
+  *\'*) eval set x "$CONFIG_FILES" ;;
+  *)   set x $CONFIG_FILES ;;
+  esac
+  shift
+  for mf
+  do
+    # Strip MF so we end up with the name of the file.
+    mf=`echo "$mf" | sed -e 's/:.*$//'`
+    # Check whether this is an Automake generated Makefile or not.
+    # We used to match only the files named `Makefile.in', but
+    # some people rename them; so instead we look at the file content.
+    # Grep'ing the first line is not enough: some people post-process
+    # each Makefile.in and add a new line on top of each file to say so.
+    # Grep'ing the whole file is not good either: AIX grep has a line
+    # limit of 2048, but all sed's we know have understand at least 4000.
+    if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+      dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$mf" : 'X\(//\)[^/]' \| \
+	 X"$mf" : 'X\(//\)$' \| \
+	 X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+    else
+      continue
+    fi
+    # Extract the definition of DEPDIR, am__include, and am__quote
+    # from the Makefile without running `make'.
+    DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+    test -z "$DEPDIR" && continue
+    am__include=`sed -n 's/^am__include = //p' < "$mf"`
+    test -z "am__include" && continue
+    am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+    # When using ansi2knr, U may be empty or an underscore; expand it
+    U=`sed -n 's/^U = //p' < "$mf"`
+    # Find all dependency output files, they are included files with
+    # $(DEPDIR) in their names.  We invoke sed twice because it is the
+    # simplest approach to changing $(DEPDIR) to its actual value in the
+    # expansion.
+    for file in `sed -n "
+      s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+	 sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+      # Make sure the directory exists.
+      test -f "$dirpart/$file" && continue
+      fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$file" : 'X\(//\)[^/]' \| \
+	 X"$file" : 'X\(//\)$' \| \
+	 X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      as_dir=$dirpart/$fdir; as_fn_mkdir_p
+      # echo "creating $dirpart/$file"
+      echo '# dummy' > "$dirpart/$file"
+    done
+  done
+}
+ ;;
+    "libtool":C)
+
+    # See if we are running on zsh, and set the options which allow our
+    # commands through without removal of \ escapes.
+    if test -n "${ZSH_VERSION+set}" ; then
+      setopt NO_GLOB_SUBST
+    fi
+
+    cfgfile="${ofile}T"
+    trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+    $RM "$cfgfile"
+
+    cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+#   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#   Written by Gordon Matzigkeit, 1996
+#
+#   This file is part of GNU Libtool.
+#
+# GNU Libtool 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.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING.  If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that does not interpret backslashes.
+ECHO=$lt_ECHO
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names.  First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+  case $host_os in
+  aix3*)
+    cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program.  For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+  COLLECT_NAMES=
+  export COLLECT_NAMES
+fi
+_LT_EOF
+    ;;
+  esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+  # We use sed instead of cat because bash on DJGPP gets confused if
+  # if finds mixed CR/LF and LF-only lines.  Since sed operates in
+  # text mode, it properly converts lines to CR/LF.  This bash problem
+  # is reportedly fixed, but why not run on old versions too?
+  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  case $xsi_shell in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+#   dirname:  Compute the dirname of FILE.  If nonempty,
+#             add APPEND to the result, otherwise set result
+#             to NONDIR_REPLACEMENT.
+#             value returned in "$func_dirname_result"
+#   basename: Compute filename of FILE.
+#             value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+  case ${1} in
+    */*) func_dirname_result="${1%/*}${2}" ;;
+    *  ) func_dirname_result="${3}" ;;
+  esac
+  func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+  # positional parameters, so assign one to ordinary parameter first.
+  func_stripname_result=${3}
+  func_stripname_result=${func_stripname_result#"${1}"}
+  func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=${1%%=*}
+  func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  case ${1} in
+    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+    *)    func_lo2o_result=${1} ;;
+  esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=${#1}
+}
+
+_LT_EOF
+    ;;
+  *) # Bourne compatible functions.
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+  # Extract subdirectory from the argument.
+  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
+  if test "X$func_dirname_result" = "X${1}"; then
+    func_dirname_result="${3}"
+  else
+    func_dirname_result="$func_dirname_result${2}"
+  fi
+}
+
+# func_basename file
+func_basename ()
+{
+  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+  case ${2} in
+    .*) func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
+    *)  func_stripname_result=`$ECHO "X${3}" \
+           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
+  esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
+  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+  func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+  yes)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1+=\$2"
+}
+_LT_EOF
+    ;;
+  *)
+    cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+  eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+    ;;
+  esac
+
+
+  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+    || (rm -f "$cfgfile"; exit 1)
+
+  mv -f "$cfgfile" "$ofile" ||
+    (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+  chmod +x "$ofile"
+
+
+    cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking.  This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+    "dap-config":F) chmod +x dap-config ;;
+
+  esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# 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 || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..ed97b02
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,309 @@
+
+dnl -*- autoconf -*-
+dnl Process this file with autoconf to produce a configure script.
+
+AC_PREREQ(2.62)
+dnl Update version here and below at LIB_CURRENT, ..., if needed.
+AC_INIT(libdap, 3.11.1, opendap-tech at opendap.org)
+AC_DEFINE(DAP_PROTOCOL_VERSION, ["3.4"], [Highest DAP version implemented?])
+AC_SUBST(DAP_PROTOCOL_VERSION)
+
+AC_CONFIG_SRCDIR([Connect.cc])
+AC_CONFIG_AUX_DIR(conf)
+AM_CONFIG_HEADER([config.h dods-datatypes-config.h xdr-datatypes-config.h])
+AC_CONFIG_MACRO_DIR([conf])
+
+AM_INIT_AUTOMAKE
+AC_CONFIG_TESTDIR(tests, [.])
+
+dnl AC_DEFINE([FILE_METHODS], [1], [Define this to activate the old FILE * methods.])
+
+AC_DEFINE(CNAME, "libdap", [What sort of HTTP client is this?])
+AC_DEFINE_UNQUOTED(CVER, "$PACKAGE_VERSION", [Client version number])
+AC_DEFINE_UNQUOTED(DVR, "libdap/$PACKAGE_VERSION", [Client name and version combined])
+AC_SUBST(DVR)
+
+
+PACKAGE_MAJOR_VERSION=`echo $PACKAGE_VERSION | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\1@'`
+PACKAGE_MINOR_VERSION=`echo $PACKAGE_VERSION | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\2@'`
+PACKAGE_SUBMINOR_VERSION=`echo $PACKAGE_VERSION | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\3@'`
+AC_MSG_NOTICE(Package Major Version:     $PACKAGE_MAJOR_VERSION)
+AC_MSG_NOTICE(Package Minor Version:     $PACKAGE_MINOR_VERSION)
+AC_MSG_NOTICE(Package SubMinor Version:  $PACKAGE_SUBMINOR_VERSION)
+AC_SUBST(PACKAGE_MAJOR_VERSION)
+AC_SUBST(PACKAGE_MINOR_VERSION)
+AC_SUBST(PACKAGE_SUBMINOR_VERSION)
+
+
+
+AC_DEFINE(EVAL, 1, [Should all the classes run ConstraintEvaluator::eval()?])
+AC_SUBST(EVAL)
+
+dnl flags for the compilers and linkers - set these before locating the
+dnl actual tools since some of the AC_PROG macros set these `flag variables'
+dnl to default values otherwise.
+
+AC_CANONICAL_HOST
+AC_SUBST(host)
+
+dnl library version: Update these when the interface changes. Generally,
+dnl assume that the interface tracks the major and minor release numbers.
+DAPLIB_CURRENT=14
+DAPLIB_AGE=3
+DAPLIB_REVISION=0
+AC_SUBST(DAPLIB_CURRENT)
+AC_SUBST(DAPLIB_AGE)
+AC_SUBST(DAPLIB_REVISION)
+
+LIBDAP_VERSION="$DAPLIB_CURRENT:$DAPLIB_REVISION:$DAPLIB_AGE"
+AC_SUBST(LIBDAP_VERSION)
+
+CLIENTLIB_CURRENT=4
+CLIENTLIB_AGE=1
+CLIENTLIB_REVISION=0
+AC_SUBST(CLIENTLIB_CURRENT)
+AC_SUBST(CLIENTLIB_AGE)
+AC_SUBST(CLIENTLIB_REVISION)
+
+CLIENTLIB_VERSION="$CLIENTLIB_CURRENT:$CLIENTLIB_REVISION:$CLIENTLIB_AGE"
+AC_SUBST(CLIENTLIB_VERSION)
+
+SERVERLIB_CURRENT=9
+SERVERLIB_AGE=2
+SERVERLIB_REVISION=0
+AC_SUBST(SERVERLIB_CURRENT)
+AC_SUBST(SERVERLIB_AGE)
+AC_SUBST(SERVERLIB_REVISION)
+
+SERVERLIB_VERSION="$SERVERLIB_CURRENT:$SERVERLIB_REVISION:$SERVERLIB_AGE"
+AC_SUBST(SERVERLIB_VERSION)
+
+dnl Checks for programs.
+AC_PROG_AWK
+AC_PROG_CXX
+AC_PROG_CC
+
+dnl Call this gnulib macro right after a working C Compiler is found
+gl_EARLY
+
+AM_PROG_LEX
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+AC_PROG_LIBTOOL
+
+dnl We really need bison and not yacc. If you use AC_PROG_YACC, the resulting 
+dnl Makefile will call bison -y which doesn't know how to make the parsers 
+dnl we require. jhrg 6/15/05
+AC_CHECK_PROG(YACC,[bison],[bison])
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS([fcntl.h malloc.h memory.h netinet/in.h stddef.h stdlib.h string.h strings.h sys/param.h sys/time.h unistd.h])
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_C_INLINE
+AC_TYPE_SIZE_T
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+AC_HEADER_TIME
+AC_STRUCT_TM
+AC_C_VOLATILE
+DODS_CHECK_SIZES
+
+dnl echo "CC = $CC"
+if test "$CC" = "gcc"
+then
+    AM_CONDITIONAL([COMPILER_IS_GCC],[true])
+else
+    AM_CONDITIONAL([COMPILER_IS_GCC],[false])
+fi
+
+# Checks for library functions.
+
+# These, at least some of them, cannot be used along with gnulib without
+# breaking stuff. Since we are not bothering to handle the cases where these
+# functions break, there's not much point in testing for them. However, it
+# might be a good thing to use the gnulib versions since those fix various
+# common problems found in many distributions.
+
+dnl AC_FUNC_CLOSEDIR_VOID
+dnl AC_FUNC_FORK
+dnl AC_FUNC_STRFTIME
+dnl AC_HEADER_STDBOOL
+dnl AC_FUNC_ALLOCA
+dnl AC_FUNC_ERROR_AT_LINE
+dnl AC_FUNC_MALLOC
+dnl AC_FUNC_MEMCMP
+dnl AC_FUNC_REALLOC
+dnl AC_FUNC_STAT
+dnl AC_FUNC_STRTOD
+
+dnl using AC_CHECK_FUNCS does not run macros from gnulib.
+AC_CHECK_FUNCS([alarm atexit bzero dup2 getcwd getpagesize localtime_r memmove memset pow putenv setenv strchr strerror strtol strtoul timegm mktime])
+
+gl_SOURCE_BASE(gl)
+gl_M4_BASE(gl/m4)
+gl_MODULES(regex)
+
+gl_INIT
+
+dnl I wrote these checks because we need the *-config scripts to build, so 
+dnl the AC_CHECK_LIB macro is not needed.
+
+curlprivatereq=
+curlprivatelibs=
+libdap_pkgconfig_libcurl=yes
+libdap_libcurl_module='libcurl >= 7.10.6'
+PKG_CHECK_MODULES([CURL],[$libdap_libcurl_module],,
+  [libdap_pkgconfig_libcurl=no])
+AC_MSG_CHECKING([for libcurl])
+if test $libdap_pkgconfig_libcurl = 'yes'
+then
+	curlprivatereq=$libdap_libcurl_module
+	CURL_STATIC_LIBS="`$PKG_CONFIG --static --libs libcurl`"
+	AC_MSG_RESULT([yes; used pkg-config])
+elif curl-config --version > /dev/null 2>&1
+then
+	version_libcurl=`curl-config --version | sed 's at libcurl \(.*\)@\1@'`
+
+	version_M=`echo $version_libcurl | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\1@'`
+	version_m=`echo $version_libcurl | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\2@'`
+	version_m_m=`echo $version_libcurl | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\3@'`
+	
+	dnl echo "version_M: $version_M"
+	dnl echo "version_m: $version_m"
+	dnl echo "version_m_m: $version_m_m"
+
+	dnl Test for several different versions of libcurl. We can use 7.10.6
+	dnl or newer.
+	
+	if test $version_M -gt 7
+	then
+		libcurl_ok='yes'
+	elif test $version_M -eq 7 && test $version_m -gt 10
+	then
+		libcurl_ok='yes'
+	elif test $version_M -eq 7 && test $version_m -eq 10 && test $version_m_m -gt 5
+	then
+		libcurl_ok='yes'
+	else
+		libcurl_ok='no'
+	fi
+
+	dnl First test the minimum
+	if test $libcurl_ok = "no"
+	then
+		AC_MSG_ERROR([must have libcurl 7.10.6 or greater, found $version_libcurl])
+	fi
+
+	CURL_LIBS="`curl-config --libs`"
+	CURL_STATIC_LIBS=$CURL_LIBS
+	curlprivatelibs="`curl-config --libs`"
+	CURL_CFLAGS="`curl-config --cflags`"
+	AC_MSG_RESULT([yes; used curl-config])
+else
+	AC_MSG_ERROR([I could not find libcurl])
+fi
+AC_SUBST([curlprivatereq])
+AC_SUBST([curlprivatelibs])
+AC_SUBST([CURL_LIBS])
+AC_SUBST([CURL_STATIC_LIBS])
+AC_SUBST([CURL_CFLAGS])
+
+xmlprivatereq=
+xmlprivatelibs=
+libdap_pkgconfig_libxml2=yes
+libdap_libxml2_module='libxml-2.0 >= 2.6.16'
+PKG_CHECK_MODULES([XML2],[$libdap_libxml2_module],,
+  [libdap_pkgconfig_libxml2=no])
+AC_MSG_CHECKING([for libxml2])
+if test $libdap_pkgconfig_libxml2 = 'yes'
+then
+	xmlprivatereq=$libdap_libxml2_module
+	XML2_STATIC_LIBS="`$PKG_CONFIG --static --libs libxml-2.0`"
+	AC_MSG_RESULT([yes; used pkg-config])
+elif xml2-config --version > /dev/null 2>&1
+then
+	version_libxml2=`xml2-config --version`
+	version_M=`echo $version_libxml2 | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\1@'`
+	version_m=`echo $version_libxml2 | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\2@'`
+	version_m_m=`echo $version_libxml2 | sed 's@^\([[0-9]]\)*\.\([[0-9]]*\)\.\([[0-9]]*\)$@\3@'`
+	
+	if test $version_M -gt 2
+	then
+		libxml2_ok='yes'
+	elif test $version_M -eq 2 && test $version_m -eq 6 && test $version_m_m -ge 16
+	then
+                libxml2_ok='yes'
+	fi
+
+	XML2_LIBS="`xml2-config --libs`"
+	XML2_STATIC_LIBS=$XML2_LIBS
+	XML2_CFLAGS="`xml2-config --cflags`"
+	xmlprivatelibs="`xml2-config --libs`"
+	AC_MSG_RESULT([yes; used xml2-config])
+else
+	AC_MSG_ERROR([I could not find libxml2 2.6.16 or newer])
+fi
+AC_SUBST([xmlprivatereq])
+AC_SUBST([xmlprivatelibs])
+AC_SUBST([XML2_LIBS])
+AC_SUBST([XML2_STATIC_LIBS])
+AC_SUBST([XML2_CFLAGS])
+
+DAP_CHECK_ZLIB
+
+AC_CHECK_LIB([pthread], [pthread_kill], 
+	[PTHREAD_LIBS="-lpthread"],
+	[AC_MSG_ERROR([I could not find pthreads])])
+AC_SUBST([PTHREAD_LIBS])
+
+AC_CHECK_LIB([uuid], [uuid_generate], 
+	[UUID_LIBS="-luuid"],
+	[UUID_LIBS=""])
+AC_SUBST([UUID_LIBS])
+
+AM_PATH_CPPUNIT(1.12.0,
+	[AM_CONDITIONAL([CPPUNIT], [true])],
+	[AM_CONDITIONAL([CPPUNIT], [false])])
+
+DODS_DEBUG_OPTION
+
+dnl Temporary hack; find a home for the deflate program; set it to
+dnl prefix/etc/deflate. See util.cc:dods_root()
+if test "$prefix" = "NONE"
+then
+AC_DEFINE([LIBDAP_ROOT], ["/usr/local"], [Set to the prefix directory])
+else
+AC_DEFINE_UNQUOTED([LIBDAP_ROOT], ["$prefix"], [Set to the prefix directory])
+fi
+
+dnl autoheader macros; tack some text at the top and bottom of config_dap.h.in
+
+AH_TOP([#ifndef _config_h
+#define _config_h])
+
+AH_BOTTOM([/* Shorthand for gcc's unused attribute feature */
+#if defined(__GNUG__) || defined(__GNUC__)
+#define not_used __attribute__ ((unused))
+#else
+#define not_used 
+#endif /* __GNUG__ || __GNUC__ */
+
+#endif /* _config_h */])
+
+AC_CONFIG_FILES([Makefile
+                 libdap.pc
+                 libdapclient.pc
+                 libdapserver.pc
+                 gl/Makefile
+                 tests/Makefile
+                 tests/atlocal
+                 unit-tests/Makefile
+                 unit-tests/cache-testsuite/Makefile])
+AC_CONFIG_FILES([dap-config], [chmod +x dap-config]) 
+		 
+AC_OUTPUT
diff --git a/dap-config-pkgconfig b/dap-config-pkgconfig
new file mode 100644
index 0000000..a3efb58
--- /dev/null
+++ b/dap-config-pkgconfig
@@ -0,0 +1,86 @@
+#! /bin/sh
+#
+# Borrowed the idea for this script (and some code) from libcurl.
+#
+
+usage()
+{
+    cat <<EOF
+Usage: dap-config [OPTION]
+
+Available values for OPTION include:
+
+  --help      	display this help message and exit
+  --cc        	C compiler
+  --cxx       	C++ compiler
+  --cflags    	pre-processor and compiler flags
+  --libs      	library linking information for libdap (both clients and servers)
+  --server-libs libraries for servers
+  --client-libs libraries for clients
+  --prefix    	OPeNDAP install prefix
+  --version   	Library version
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+while test $# -gt 0; do
+    case "$1" in
+    # this deals with options in the style
+    # --option=value and extracts the value part
+    # [not currently used]
+    -*=*) value=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+    *) value= ;;
+    esac
+
+    case "$1" in
+    --help)
+	usage 0
+	;;
+
+    --cc)
+	pkg-config --variable ccompiler libdap
+	;;
+
+    --cxx)
+	pkg-config --variable cppcompiler libdap
+	;;
+
+    --cflags)
+	pkg-config --cflags libdap
+	;;
+
+    --libs)
+       	pkg-config --libs libdapclient libdapserver
+       	;;
+
+    --server-libs)
+       	pkg-config --libs libdapserver
+       	;;
+
+    --client-libs)
+       	pkg-config --libs libdapclient
+       	;;
+
+    --prefix)
+       	pkg-config --variable prefix libdap
+       	;;
+
+    --version)
+	echo "libdap `pkg-config --modversion libdap`"
+	;;
+
+    *)
+        echo "unknown option: $1"
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+
+exit 0
diff --git a/dap-config.in b/dap-config.in
new file mode 100644
index 0000000..c4d579c
--- /dev/null
+++ b/dap-config.in
@@ -0,0 +1,90 @@
+#! /bin/sh
+#
+# Borrowed the idea for this script (and some code) from libcurl.
+#
+prefix=@prefix@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+includedir=${prefix}/include
+
+usage()
+{
+    cat <<EOF
+Usage: dap-config [OPTION]
+
+Available values for OPTION include:
+
+  --help      	display this help message and exit
+  --cc        	C compiler
+  --cxx       	C++ compiler
+  --cflags    	pre-processor and compiler flags
+  --libs      	library linking information for libdap (both clients and servers)
+  --server-libs libraries for servers
+  --client-libs libraries for clients
+  --prefix    	OPeNDAP install prefix
+  --version   	Library version
+EOF
+
+    exit $1
+}
+
+if test $# -eq 0; then
+    usage 1
+fi
+
+while test $# -gt 0; do
+    case "$1" in
+    # this deals with options in the style
+    # --option=value and extracts the value part
+    # [not currently used]
+    -*=*) value=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+    *) value= ;;
+    esac
+
+    case "$1" in
+    --help)
+	usage 0
+	;;
+
+    --cc)
+	echo "@CC@"
+	;;
+
+    --cxx)
+	echo "@CXX@"
+	;;
+
+    --cflags)
+	echo "-I${includedir}/libdap"
+	;;
+
+    --libs)
+       	echo "-L${libdir} -ldap -ldapserver -ldapclient @CURL_STATIC_LIBS@ @XML2_STATIC_LIBS@ @PTHREAD_LIBS@ @UUID_LIBS@ @LIBS@"
+       	;;
+
+    --server-libs)
+       	echo "-L${libdir} -ldap -ldapserver @XML2_STATIC_LIBS@ @PTHREAD_LIBS@ @UUID_LIBS@ @LIBS@"
+       	;;
+
+    --client-libs)
+       	echo "-L${libdir} -ldap -ldapclient @CURL_STATIC_LIBS@ @XML2_STATIC_LIBS@ @PTHREAD_LIBS@ @UUID_LIBS@ @LIBS@"
+       	;;
+
+    --prefix)
+       	echo "${prefix}"
+       	;;
+
+    --version)
+	echo "libdap @PACKAGE_VERSION@"
+	;;
+
+    *)
+        echo "unknown option: $1"
+	usage
+	exit 1
+	;;
+    esac
+    shift
+done
+
+exit 0
diff --git a/das.lex b/das.lex
new file mode 100644
index 0000000..2167470
--- /dev/null
+++ b/das.lex
@@ -0,0 +1,220 @@
+
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-2000
+*/ 
+
+/*
+   Scanner for the DAS. This file works with gnu's flex scanner generator. It
+   returns either ATTR, ID, VAL, TYPE or one of the single character tokens
+   `{', `}', `;', `,' or `\n' as integers. In the case of an ID or VAL, the
+   scanner stores a pointer to the lexeme in yylval (whose type is char *).
+
+   The scanner discards all comment text.
+
+   The scanner returns quoted strings as VALs. Any characters may appear in a
+   quoted string except backslash (\) and quote("). To include these escape
+   them with a backslash.
+   
+   The scanner is not reentrant, but can share name spaces with other
+   scanners.
+   
+   Note:
+   1) The `defines' file das.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `daslex'.
+   3) When bison builds the das.tab.h file, it uses `das' instead of `yy' for
+   variable name prefixes (e.g., yylval --> daslval).
+   4) The quote stuff is very complicated because we want backslash (\)
+   escapes to work and because we want line counts to work too. In order to
+   properly scan a quoted string two C functions are used: one to remove the
+   escape characters from escape sequences and one to remove the trailing
+   quote on the end of the string. 
+
+   jhrg 7/12/94 
+
+   NB: We don't remove the \'s or ending quotes any more -- that way the
+   printed das can be re-parsed. 9/28/94. 
+*/
+
+%{
+#include "config_dap.h"
+
+#include <cstdio>
+
+static char rcsid[] not_used ={"$Id: das.lex 21577 2009-10-02 16:12:17Z jimg $"};
+
+#ifndef _MSC_VER
+#include <string.h>
+#else
+#include <string>
+#endif
+
+using namespace std;
+
+#include "debug.h"
+#include "parser.h"
+
+using namespace libdap ;
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+/* These defines must precede the das.tab.h include. */
+#define YYSTYPE char *
+#define YY_DECL int daslex YY_PROTO(( void ))
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning DAS object text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+#include "das.tab.hh"
+
+int das_line_num = 1;
+static int start_line;		/* used in quote and comment error handlers */
+
+%}
+    
+%option noyywrap
+%option prefix="das"
+%option outfile="lex.das.cc"
+ 
+%x quote
+%x comment
+%x xml
+
+ATTR 	attributes|Attributes|ATTRIBUTES
+
+ALIAS   ALIAS|Alias|alias
+BYTE	BYTE|Byte|byte
+INT16	INT16|Int16|int16
+UINT16	UINT16|UInt16|Uint16|uint16
+INT32	INT32|Int32|int32
+UINT32	UINT32|UInt32|Uint32|uint32
+FLOAT32 FLOAT32|Float32|float32
+FLOAT64 FLOAT64|Float64|float64
+STRING  STRING|String|string
+URL	URL|Url|url
+XML     OTHERXML|OtherXML|OtherXml|otherxml
+
+/* Comment chars (#) are treated specially. Lets hope nobody wants to start
+   A variable name with one... Note that the DAS allows Identifiers to have 
+   parens and colons while the DDS and expr scanners don't. It's too hard to
+   disambiguate functions when IDs have parens in them and adding colons
+   makes parsing the array projections hard. 10/31/2001 jhrg */
+
+WORD    [-+a-zA-Z0-9_/%.:\\()*][-+a-zA-Z0-9_/%.:\\()#*]*
+
+NEVER   [^\-+a-zA-Z0-9_/%.:\\()#{};,[\]]
+
+%%
+
+{ATTR}	    	    	daslval = yytext; return SCAN_ATTR;
+
+{ALIAS}                 daslval = yytext; return SCAN_ALIAS;
+{BYTE}                  daslval = yytext; return SCAN_BYTE;
+{INT16}                 daslval = yytext; return SCAN_INT16;
+{UINT16}                daslval = yytext; return SCAN_UINT16;
+{INT32}                 daslval = yytext; return SCAN_INT32;
+{UINT32}                daslval = yytext; return SCAN_UINT32;
+{FLOAT32}               daslval = yytext; return SCAN_FLOAT32;
+{FLOAT64}               daslval = yytext; return SCAN_FLOAT64;
+{STRING}                daslval = yytext; return SCAN_STRING;
+{URL}                   daslval = yytext; return SCAN_URL;
+{XML}                   daslval = yytext; return SCAN_XML;
+
+{WORD}	    	    	{
+			    daslval = yytext; 
+			    DBG(cerr << "WORD: " << yytext << endl); 
+			    return SCAN_WORD;
+			}
+
+"{" 	    	    	return (int)*yytext;
+"}" 	    	    	return (int)*yytext;
+";" 	    	    	return (int)*yytext;
+","                     return (int)*yytext;
+
+[ \t\r]+
+\n	    	    	++das_line_num;
+<INITIAL><<EOF>>    	yy_init = 1; das_line_num = 1; yyterminate();
+
+"#"	    	    	BEGIN(comment);
+<comment>[^\r\n]*
+<comment>\n		++das_line_num; BEGIN(INITIAL);
+<comment>\r\n		++das_line_num; BEGIN(INITIAL);
+<comment><<EOF>>        yy_init = 1; das_line_num = 1; yyterminate();
+
+\"                      BEGIN(quote); start_line = das_line_num; yymore();
+<quote>[^"\r\n\\]*      yymore();
+<quote>[^"\r\n\\]*\n    yymore(); ++das_line_num;
+<quote>[^"\r\n\\]*\r\n  yymore(); ++das_line_num;
+<quote>\\.              yymore();
+<quote>\"               { 
+                          BEGIN(INITIAL); 
+
+                          daslval = yytext;
+
+                          return SCAN_WORD;
+                        }
+<quote><<EOF>>          {
+                          char msg[256];
+                          sprintf(msg,
+                                  "Unterminated quote (starts on line %d)\n",
+                                  start_line);
+                          YY_FATAL_ERROR(msg);
+                        }
+
+{NEVER}                 {
+                          if (yytext) {
+                            fprintf(stderr, "Character '%c' (%d) is not",
+                            	    *yytext, *yytext);
+                            fprintf(stderr, " allowed.");
+			  }
+			}
+%%
+
+// These three glue routines enable DDS to reclaim the memory used to parse a
+// DDS off the wire. They are here because this file can see the YY_*
+// symbols; the file DDS.cc cannot.
+
+void *
+das_buffer(FILE *fp)
+{
+    return (void *)das_create_buffer(fp, YY_BUF_SIZE);
+}
+
+void
+das_switch_to_buffer(void *buf)
+{
+    das_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+das_delete_buffer(void *buf)
+{
+    das_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
diff --git a/das.tab.cc b/das.tab.cc
new file mode 100644
index 0000000..3eb7970
--- /dev/null
+++ b/das.tab.cc
@@ -0,0 +1,2201 @@
+/* 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 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse dasparse
+#define yylex   daslex
+#define yyerror daserror
+#define yylval  daslval
+#define yychar  daschar
+#define yydebug dasdebug
+#define yynerrs dasnerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_ATTR = 258,
+     SCAN_WORD = 259,
+     SCAN_ALIAS = 260,
+     SCAN_BYTE = 261,
+     SCAN_INT16 = 262,
+     SCAN_UINT16 = 263,
+     SCAN_INT32 = 264,
+     SCAN_UINT32 = 265,
+     SCAN_FLOAT32 = 266,
+     SCAN_FLOAT64 = 267,
+     SCAN_STRING = 268,
+     SCAN_URL = 269,
+     SCAN_XML = 270
+   };
+#endif
+/* Tokens.  */
+#define SCAN_ATTR 258
+#define SCAN_WORD 259
+#define SCAN_ALIAS 260
+#define SCAN_BYTE 261
+#define SCAN_INT16 262
+#define SCAN_UINT16 263
+#define SCAN_INT32 264
+#define SCAN_UINT32 265
+#define SCAN_FLOAT32 266
+#define SCAN_FLOAT64 267
+#define SCAN_STRING 268
+#define SCAN_URL 269
+#define SCAN_XML 270
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 40 "das.y"
+
+
+#define YYSTYPE char *
+#define ATTR_STRING_QUOTE_FIX
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: das.y 21577 2009-10-02 16:12:17Z jimg $"};
+
+#include <string>
+
+#include <vector>
+
+#include "DAS.h"
+#include "Error.h"
+#include "util.h"
+#include "escaping.h"
+#include "debug.h"
+#include "parser.h"
+#include "util.h"
+#include "das.tab.hh"
+
+#ifdef TRACE_NEW
+#include "trace_new.h"
+#endif
+
+#define yylex daslex
+#define yyerror daserror 
+
+using namespace std;
+using namespace libdap ;
+
+// These macros are used to access the `arguments' passed to the parser. A
+// pointer to an error object and a pointer to an integer status variable are
+// passed in to the parser within a structure (which itself is passed as a
+// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *. 
+// The parser now throws an exception when it encounters an error. 5/23/2002
+// jhrg 
+
+#define DAS_OBJ(arg) ((DAS *)((parser_arg *)(arg))->_object)
+
+#define YYPARSE_PARAM arg
+
+extern int das_line_num;	/* defined in das.lex */
+
+// No global static objects. We go through this every so often, I guess I
+// should learn... 1/24/2000 jhrg
+static string *name;	/* holds name in attr_pair rule */
+static string *type;	/* holds type in attr_pair rule */
+
+static vector<AttrTable *> *attr_tab_stack;
+
+// I use a vector of AttrTable pointers for a stack
+
+#define TOP_OF_STACK (attr_tab_stack->back())
+#define PUSH(x) (attr_tab_stack->push_back((x)))
+#define POP (attr_tab_stack->pop_back())
+#define STACK_LENGTH (attr_tab_stack->size())
+#define OUTER_TABLE_ONLY (attr_tab_stack->size() == 1)
+#define STACK_EMPTY (attr_tab_stack->empty())
+
+#define TYPE_NAME_VALUE(x) *type << " " << *name << " " << (x)
+
+static const char *ATTR_TUPLE_MSG = 
+"Expected an attribute type (Byte, Int16, UInt16, Int32, UInt32, Float32,\n\
+Float64, String or Url) followed by a name and value.";
+static const char *NO_DAS_MSG =
+"The attribute object returned from the dataset was null\n\
+Check that the URL is correct.";
+
+typedef int checker(const char *);
+
+int daslex(void);
+static void daserror(char *s);
+static void add_attribute(const string &type, const string &name, 
+			  const string &value, checker *chk) throw (Error);
+static void add_alias(AttrTable *das, AttrTable *current, const string &name, 
+		      const string &src) throw (Error);
+static void add_bad_attribute(AttrTable *attr, const string &type,
+			      const string &name, const string &value,
+			      const string &msg);
+
+
+
+/* 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 int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 228 "das.tab.cc"
+
+#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__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# 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 YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* 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)) \
+      + 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  3
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   118
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  20
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  47
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  84
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  134
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   270
+
+#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,     2,    19,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,    18,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    16,     2,    17,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     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
+};
+
+#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,    12,    17,    19,    20,
+      22,    25,    27,    28,    29,    36,    37,    38,    45,    46,
+      47,    54,    55,    56,    63,    64,    65,    72,    73,    74,
+      81,    82,    83,    90,    91,    92,    99,   100,   101,   108,
+     109,   110,   117,   118,   119,   126,   127,   131,   133,   137,
+     139,   143,   145,   149,   151,   155,   157,   161,   163,   167,
+     169,   173,   175,   179,   181,   185,   187,   189,   191,   193,
+     195,   197,   199,   201,   203,   205,   207,   209,   211,   213,
+     215,   217,   219,   220,   221
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      21,     0,    -1,    -1,    22,    23,    -1,    24,    -1,    23,
+      24,    -1,     3,    16,    25,    17,    -1,     1,    -1,    -1,
+      26,    -1,    25,    26,    -1,    64,    -1,    -1,    -1,     6,
+      27,    63,    28,    50,    18,    -1,    -1,    -1,     7,    29,
+      63,    30,    51,    18,    -1,    -1,    -1,     8,    31,    63,
+      32,    52,    18,    -1,    -1,    -1,     9,    33,    63,    34,
+      53,    18,    -1,    -1,    -1,    10,    35,    63,    36,    54,
+      18,    -1,    -1,    -1,    11,    37,    63,    38,    55,    18,
+      -1,    -1,    -1,    12,    39,    63,    40,    56,    18,    -1,
+      -1,    -1,    13,    41,    63,    42,    57,    18,    -1,    -1,
+      -1,    14,    43,    63,    44,    58,    18,    -1,    -1,    -1,
+      15,    45,    63,    46,    59,    18,    -1,    -1,    -1,     4,
+      47,    16,    25,    48,    17,    -1,    -1,     1,    49,    18,
+      -1,     4,    -1,    50,    19,     4,    -1,     4,    -1,    51,
+      19,     4,    -1,     4,    -1,    52,    19,     4,    -1,     4,
+      -1,    53,    19,     4,    -1,     4,    -1,    54,    19,     4,
+      -1,    62,    -1,    55,    19,    62,    -1,    62,    -1,    56,
+      19,    62,    -1,    61,    -1,    57,    19,    61,    -1,    60,
+      -1,    58,    19,    60,    -1,     4,    -1,     4,    -1,     4,
+      -1,     4,    -1,     4,    -1,     3,    -1,     5,    -1,     6,
+      -1,     7,    -1,     8,    -1,     9,    -1,    10,    -1,    11,
+      -1,    12,    -1,    13,    -1,    14,    -1,    15,    -1,    -1,
+      -1,     5,     4,    65,     4,    66,    18,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   185,   185,   185,   202,   203,   207,   208,   214,   215,
+     216,   219,   221,   222,   221,   225,   226,   225,   229,   230,
+     229,   233,   234,   233,   237,   238,   237,   241,   242,   241,
+     245,   246,   245,   249,   250,   249,   253,   254,   253,   257,
+     258,   257,   262,   282,   261,   290,   289,   295,   299,   305,
+     309,   315,   319,   325,   329,   335,   339,   345,   349,   355,
+     359,   365,   370,   377,   381,   387,   403,   406,   409,   412,
+     412,   412,   412,   412,   413,   413,   413,   413,   414,   414,
+     414,   414,   418,   422,   417
+};
+#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", "SCAN_ATTR", "SCAN_WORD", "SCAN_ALIAS",
+  "SCAN_BYTE", "SCAN_INT16", "SCAN_UINT16", "SCAN_INT32", "SCAN_UINT32",
+  "SCAN_FLOAT32", "SCAN_FLOAT64", "SCAN_STRING", "SCAN_URL", "SCAN_XML",
+  "'{'", "'}'", "';'", "','", "$accept", "attr_start", "@1", "attributes",
+  "attribute", "attr_list", "attr_tuple", "@2", "@3", "@4", "@5", "@6",
+  "@7", "@8", "@9", "@10", "@11", "@12", "@13", "@14", "@15", "@16", "@17",
+  "@18", "@19", "@20", "@21", "@22", "@23", "@24", "bytes", "int16",
+  "uint16", "int32", "uint32", "float32", "float64", "strs", "urls", "xml",
+  "url", "str_or_id", "float_or_int", "name", "alias", "@25", "@26", 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,   123,   125,    59,    44
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    20,    22,    21,    23,    23,    24,    24,    25,    25,
+      25,    26,    27,    28,    26,    29,    30,    26,    31,    32,
+      26,    33,    34,    26,    35,    36,    26,    37,    38,    26,
+      39,    40,    26,    41,    42,    26,    43,    44,    26,    45,
+      46,    26,    47,    48,    26,    49,    26,    50,    50,    51,
+      51,    52,    52,    53,    53,    54,    54,    55,    55,    56,
+      56,    57,    57,    58,    58,    59,    60,    61,    62,    63,
+      63,    63,    63,    63,    63,    63,    63,    63,    63,    63,
+      63,    63,    65,    66,    64
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     2,     4,     1,     0,     1,
+       2,     1,     0,     0,     6,     0,     0,     6,     0,     0,
+       6,     0,     0,     6,     0,     0,     6,     0,     0,     6,
+       0,     0,     6,     0,     0,     6,     0,     0,     6,     0,
+       0,     6,     0,     0,     6,     0,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     3,     1,     3,     1,
+       3,     1,     3,     1,     3,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     0,     0,     6
+};
+
+/* 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,     0,     1,     7,     0,     0,     4,     0,     5,
+      45,    42,     0,    12,    15,    18,    21,    24,    27,    30,
+      33,    36,    39,     0,     9,    11,     0,     0,    82,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     6,
+      10,    46,     0,     0,    70,    69,    71,    72,    73,    74,
+      75,    76,    77,    78,    79,    80,    81,    13,    16,    19,
+      22,    25,    28,    31,    34,    37,    40,     0,    83,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,    47,     0,    49,     0,    51,     0,    53,     0,    55,
+       0,    68,     0,    57,     0,    59,    67,     0,    61,    66,
+       0,    63,    65,     0,    44,    84,    14,     0,    17,     0,
+      20,     0,    23,     0,    26,     0,    29,     0,    32,     0,
+      35,     0,    38,     0,    41,    48,    50,    52,    54,    56,
+      58,    60,    62,    64
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     1,     2,     6,     7,    23,    24,    29,    69,    30,
+      70,    31,    71,    32,    72,    33,    73,    34,    74,    35,
+      75,    36,    76,    37,    77,    38,    78,    27,    79,    26,
+      82,    84,    86,    88,    90,    92,    94,    97,   100,   103,
+     101,    98,    93,    57,    25,    43,    80
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -76
+static const yytype_int8 yypact[] =
+{
+     -76,    19,    35,   -76,   -76,    25,    34,   -76,     1,   -76,
+     -76,   -76,    28,   -76,   -76,   -76,   -76,   -76,   -76,   -76,
+     -76,   -76,   -76,    16,   -76,   -76,    40,    80,   -76,    57,
+      57,    57,    57,    57,    57,    57,    57,    57,    57,   -76,
+     -76,   -76,     1,    93,   -76,   -76,   -76,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   -76,   -76,    42,   -76,    94,
+      95,    96,    97,    98,    99,    99,   100,   101,   102,    90,
+      91,   -76,   -15,   -76,    21,   -76,    64,   -76,    66,   -76,
+      68,   -76,    70,   -76,    72,   -76,   -76,    74,   -76,   -76,
+      76,   -76,   -76,    92,   -76,   -76,   -76,   104,   -76,   107,
+     -76,   108,   -76,   109,   -76,   110,   -76,    99,   -76,    99,
+     -76,   100,   -76,   101,   -76,   -76,   -76,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -76,   -76,   -76,   -76,   111,    73,   -22,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,
+     -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,   -76,
+      -7,    -3,   -75,    43,   -76,   -76,   -76
+};
+
+/* 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 -44
+static const yytype_int16 yytable[] =
+{
+      95,    40,    10,   106,   107,    11,    12,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    10,    -8,     3,
+      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
+      21,    22,    28,    39,    -3,     4,     4,     5,     5,   108,
+     109,     8,   130,    10,   131,    40,    11,    12,    13,    14,
+      15,    16,    17,    18,    19,    20,    21,    22,    41,   -43,
+      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,
+      54,    55,    56,    58,    59,    60,    61,    62,    63,    64,
+      65,    66,   110,   111,   112,   113,   114,   115,   116,   117,
+     118,   119,   120,   121,   122,   123,    42,    68,    81,    83,
+      85,    87,    89,    91,    96,    99,   102,   104,   125,   105,
+     124,   126,   127,   128,   129,    67,   133,     9,   132
+};
+
+static const yytype_uint8 yycheck[] =
+{
+      75,    23,     1,    18,    19,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,     1,    17,     0,
+       4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
+      14,    15,     4,    17,     0,     1,     1,     3,     3,    18,
+      19,    16,   117,     1,   119,    67,     4,     5,     6,     7,
+       8,     9,    10,    11,    12,    13,    14,    15,    18,    17,
+       3,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    30,    31,    32,    33,    34,    35,    36,
+      37,    38,    18,    19,    18,    19,    18,    19,    18,    19,
+      18,    19,    18,    19,    18,    19,    16,     4,     4,     4,
+       4,     4,     4,     4,     4,     4,     4,    17,     4,    18,
+      18,     4,     4,     4,     4,    42,   123,     6,   121
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    21,    22,     0,     1,     3,    23,    24,    16,    24,
+       1,     4,     5,     6,     7,     8,     9,    10,    11,    12,
+      13,    14,    15,    25,    26,    64,    49,    47,     4,    27,
+      29,    31,    33,    35,    37,    39,    41,    43,    45,    17,
+      26,    18,    16,    65,     3,     4,     5,     6,     7,     8,
+       9,    10,    11,    12,    13,    14,    15,    63,    63,    63,
+      63,    63,    63,    63,    63,    63,    63,    25,     4,    28,
+      30,    32,    34,    36,    38,    40,    42,    44,    46,    48,
+      66,     4,    50,     4,    51,     4,    52,     4,    53,     4,
+      54,     4,    55,    62,    56,    62,     4,    57,    61,     4,
+      58,    60,     4,    59,    17,    18,    18,    19,    18,    19,
+      18,    19,    18,    19,    18,    19,    18,    19,    18,    19,
+      18,    19,    18,    19,    18,     4,     4,     4,     4,     4,
+      62,    62,    61,    60
+};
+
+#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 (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 (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#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); \
+      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)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# 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)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  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, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#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)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} 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)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  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 (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| 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 (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  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;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* 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;
+
+  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;
+
+
+	/* 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),
+
+		    &yystacksize);
+
+	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);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + 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;
+
+  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];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 185 "das.y"
+    {
+		name = new string();
+		type = new string();
+		attr_tab_stack = new vector<AttrTable *>;
+
+		// push outermost AttrTable
+		PUSH(DAS_OBJ(arg)->get_top_level_attributes());
+	;}
+    break;
+
+  case 3:
+#line 194 "das.y"
+    {
+		POP;	// pop the DAS/AttrTable before stack's dtor
+		delete name;
+		delete type;
+		delete attr_tab_stack;
+	;}
+    break;
+
+  case 7:
+#line 209 "das.y"
+    {
+		    parse_error((parser_arg *)arg, NO_DAS_MSG, das_line_num);
+		;}
+    break;
+
+  case 12:
+#line 221 "das.y"
+    { save_str(*type, "Byte", das_line_num); ;}
+    break;
+
+  case 13:
+#line 222 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 15:
+#line 225 "das.y"
+    { save_str(*type, "Int16", das_line_num); ;}
+    break;
+
+  case 16:
+#line 226 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 18:
+#line 229 "das.y"
+    { save_str(*type, "UInt16", das_line_num); ;}
+    break;
+
+  case 19:
+#line 230 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 21:
+#line 233 "das.y"
+    { save_str(*type, "Int32", das_line_num); ;}
+    break;
+
+  case 22:
+#line 234 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 24:
+#line 237 "das.y"
+    { save_str(*type, "UInt32", das_line_num); ;}
+    break;
+
+  case 25:
+#line 238 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 27:
+#line 241 "das.y"
+    { save_str(*type, "Float32", das_line_num); ;}
+    break;
+
+  case 28:
+#line 242 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 30:
+#line 245 "das.y"
+    { save_str(*type, "Float64", das_line_num); ;}
+    break;
+
+  case 31:
+#line 246 "das.y"
+    { save_str(*name, (yyvsp[(3) - (3)]), das_line_num); ;}
+    break;
+
+  case 33:
+#line 249 "das.y"
+    { *type = "String"; ;}
+    break;
+
+  case 34:
+#line 250 "das.y"
+    { *name = (yyvsp[(3) - (3)]); ;}
+    break;
+
+  case 36:
+#line 253 "das.y"
+    { *type = "Url"; ;}
+    break;
+
+  case 37:
+#line 254 "das.y"
+    { *name = (yyvsp[(3) - (3)]); ;}
+    break;
+
+  case 39:
+#line 257 "das.y"
+    { *type = "OtherXML"; ;}
+    break;
+
+  case 40:
+#line 258 "das.y"
+    { *name = (yyvsp[(3) - (3)]); ;}
+    break;
+
+  case 42:
+#line 262 "das.y"
+    {
+		    DBG(cerr << "Processing ID: " << (yyvsp[(1) - (1)]) << endl);
+		    
+		    AttrTable *at = TOP_OF_STACK->get_attr_table((yyvsp[(1) - (1)]));
+		    if (!at) {
+			try {
+			    at = TOP_OF_STACK->append_container((yyvsp[(1) - (1)]));
+			}
+			catch (Error &e) {
+			    // re-throw with line number info
+			    parse_error(e.get_error_message().c_str(), 
+					das_line_num);
+			}
+		    }
+		    PUSH(at);
+
+		    DBG(cerr << " Pushed attr_tab: " << at << endl);
+
+		;}
+    break;
+
+  case 43:
+#line 282 "das.y"
+    {
+		    /* pop top of stack; store in attr_tab */
+		    DBG(cerr << " Popped attr_tab: " << TOP_OF_STACK << endl);
+		    POP;
+		;}
+    break;
+
+  case 45:
+#line 290 "das.y"
+    { 
+		    parse_error(ATTR_TUPLE_MSG, das_line_num, (yyvsp[(1) - (1)]));
+		;}
+    break;
+
+  case 47:
+#line 296 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_byte);
+		;}
+    break;
+
+  case 48:
+#line 300 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_byte);
+		;}
+    break;
+
+  case 49:
+#line 306 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_int16);
+		;}
+    break;
+
+  case 50:
+#line 310 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_int16);
+		;}
+    break;
+
+  case 51:
+#line 316 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_uint16);
+		;}
+    break;
+
+  case 52:
+#line 320 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_uint16);
+		;}
+    break;
+
+  case 53:
+#line 326 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_int32);
+		;}
+    break;
+
+  case 54:
+#line 330 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_int32);
+		;}
+    break;
+
+  case 55:
+#line 336 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_uint32);
+		;}
+    break;
+
+  case 56:
+#line 340 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_uint32);
+		;}
+    break;
+
+  case 57:
+#line 346 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_float32);
+		;}
+    break;
+
+  case 58:
+#line 350 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_float32);
+		;}
+    break;
+
+  case 59:
+#line 356 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_float64);
+		;}
+    break;
+
+  case 60:
+#line 360 "das.y"
+    {
+		    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_float64);
+		;}
+    break;
+
+  case 61:
+#line 366 "das.y"
+    {
+		    string attr = remove_quotes((yyvsp[(1) - (1)]));
+		    add_attribute(*type, *name, attr, 0);
+		;}
+    break;
+
+  case 62:
+#line 371 "das.y"
+    {
+		    string attr = remove_quotes((yyvsp[(3) - (3)]));
+		    add_attribute(*type, *name, attr, 0);
+		;}
+    break;
+
+  case 63:
+#line 378 "das.y"
+    {
+                    add_attribute(*type, *name, (yyvsp[(1) - (1)]), &check_url);
+                ;}
+    break;
+
+  case 64:
+#line 382 "das.y"
+    {
+                    add_attribute(*type, *name, (yyvsp[(3) - (3)]), &check_url);
+                ;}
+    break;
+
+  case 65:
+#line 388 "das.y"
+    {
+                    // XML must be quoted in the DAS but the quotes are an
+                    // artifact of the DAS syntax so they are not part of the
+                    // value.
+                    cerr << "Attr value as read: " << (yyvsp[(1) - (1)]) << endl;
+                    string xml = unescape_double_quotes((yyvsp[(1) - (1)]));
+                    cerr << "w/o quotes: " << remove_quotes(xml) << endl;
+                    
+                    if (is_quoted(xml))
+                        add_attribute(*type, *name, remove_quotes(xml), 0);
+                    else
+                        add_attribute(*type, *name, xml, 0);
+                ;}
+    break;
+
+  case 82:
+#line 418 "das.y"
+    { 
+		    *name = (yyvsp[(2) - (2)]);
+		;}
+    break;
+
+  case 83:
+#line 422 "das.y"
+    {
+		    add_alias( DAS_OBJ(arg)->get_top_level_attributes(),
+		               TOP_OF_STACK, *name, string((yyvsp[(4) - (4)])) ) ;
+                ;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1868 "das.tab.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* 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 (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 (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  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);
+	  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;
+
+  /* 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;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* 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 (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* 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);
+      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);
+}
+
+
+#line 429 "das.y"
+
+
+// This function is required for linking, but DODS uses its own error
+// reporting mechanism.
+
+static void
+daserror(char *)
+{
+}
+
+static string
+a_or_an(const string &subject)
+{
+    string first_char(1, subject[0]);
+    string::size_type pos = first_char.find_first_of("aeiouAEIOUyY");
+    
+    if (pos == string::npos)
+	return "a";
+    else
+	return "an";
+}
+
+// This code used to throw an exception when a bad attribute value came
+// along; now it dumps the errant value(s) into a sub container called *_DODS
+// and stores the parser's error message in a string attribute named
+// `explanation.' 
+static void
+add_attribute(const string &type, const string &name, const string &value,
+	      checker *chk) throw (Error)
+{
+    DBG(cerr << "Adding: " << type << " " << name << " " << value \
+	<< " to Attrtable: " << TOP_OF_STACK << endl);
+
+    if (chk && !(*chk)(value.c_str())) {
+	string msg = "`";
+	msg += value + "' is not " + a_or_an(type) + " " + type + " value.";
+	add_bad_attribute(TOP_OF_STACK, type, name, value, msg);
+	return;
+    }
+    
+    if (STACK_EMPTY) {
+	string msg = "Whoa! Attribute table stack empty when adding `" ;
+	msg += name + ".' ";
+	parse_error(msg, das_line_num);
+    }
+    
+    try {
+#if 0
+        // Special treatment for XML: remove the double quotes that were 
+        // included in the value by this parser.
+        if (type == OtherXML && is_quoted(value))
+            TOP_OF_STACK->append_attr(name, type, value.substr(1, value.size()-2));
+        else    
+#endif
+	    TOP_OF_STACK->append_attr(name, type, value);
+    }
+    catch (Error &e) {
+	// re-throw with line number
+	parse_error(e.get_error_message().c_str(), das_line_num);
+    }
+}
+
+static void
+add_alias(AttrTable *das, AttrTable *current, const string &name, 
+	  const string &src) throw (Error)
+{
+    DBG(cerr << "Adding an alias: " << name << ": " << src << endl);
+
+    AttrTable *table = das->get_attr_table(src);
+    if (table) {
+	try {
+	    current->add_container_alias(name, table);
+	}
+	catch (Error &e) {
+	    parse_error(e.get_error_message().c_str(), das_line_num);
+	}
+    }
+    else {
+	try {
+	    current->add_value_alias(das, name, src);
+	}
+	catch (Error &e) {
+	    parse_error(e.get_error_message().c_str(), das_line_num);
+	}
+    }
+}
+
+static void
+add_bad_attribute(AttrTable *attr, const string &type, const string &name,
+		  const string &value, const string &msg)
+{
+    // First, if this bad value is already in a *_dods_errors container,
+    // then just add it. This can happen when the server side processes a DAS
+    // and then hands it off to a client which does the same.
+    // Make a new container. Call it <attr's name>_errors. If that container
+    // already exists, use it.
+    // Add the attribute.
+    // Add the error string to an attribute in the container called
+    // `<name_explanation.'. 
+    
+    if (attr->get_name().find("_dods_errors") != string::npos) {
+	attr->append_attr(name, type, value);
+    }
+    else {
+	string error_cont_name = attr->get_name() + "_dods_errors";
+	AttrTable *error_cont = attr->get_attr_table(error_cont_name);
+	if (!error_cont)
+	    error_cont = attr->append_container(error_cont_name);
+
+	error_cont->append_attr(name, type, value);
+#ifndef ATTR_STRING_QUOTE_FIX
+    error_cont->append_attr(name + "_explanation", "String",
+                "\"" + msg + "\"");
+#else
+       error_cont->append_attr(name + "_explanation", "String", msg);
+#endif
+    }
+}
+
+
diff --git a/das.tab.hh b/das.tab.hh
new file mode 100644
index 0000000..78af108
--- /dev/null
+++ b/das.tab.hh
@@ -0,0 +1,83 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface 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.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_ATTR = 258,
+     SCAN_WORD = 259,
+     SCAN_ALIAS = 260,
+     SCAN_BYTE = 261,
+     SCAN_INT16 = 262,
+     SCAN_UINT16 = 263,
+     SCAN_INT32 = 264,
+     SCAN_UINT32 = 265,
+     SCAN_FLOAT32 = 266,
+     SCAN_FLOAT64 = 267,
+     SCAN_STRING = 268,
+     SCAN_URL = 269,
+     SCAN_XML = 270
+   };
+#endif
+/* Tokens.  */
+#define SCAN_ATTR 258
+#define SCAN_WORD 259
+#define SCAN_ALIAS 260
+#define SCAN_BYTE 261
+#define SCAN_INT16 262
+#define SCAN_UINT16 263
+#define SCAN_INT32 264
+#define SCAN_UINT32 265
+#define SCAN_FLOAT32 266
+#define SCAN_FLOAT64 267
+#define SCAN_STRING 268
+#define SCAN_URL 269
+#define SCAN_XML 270
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef int YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE daslval;
+
diff --git a/das.y b/das.y
new file mode 100644
index 0000000..7ba6a86
--- /dev/null
+++ b/das.y
@@ -0,0 +1,547 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+/*
+   Grammar for the DAS. This grammar can be used with the bison parser
+   generator to build a parser for the DAS. It assumes that a scanner called
+   `daslex()' exists and that the objects DAS and AttrTable also exist.
+
+   jhrg 7/12/94 
+*/
+
+%{
+
+#define YYSTYPE char *
+#define ATTR_STRING_QUOTE_FIX
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: das.y 21577 2009-10-02 16:12:17Z jimg $"};
+
+#include <string>
+
+#include <vector>
+
+#include "DAS.h"
+#include "Error.h"
+#include "util.h"
+#include "escaping.h"
+#include "debug.h"
+#include "parser.h"
+#include "util.h"
+#include "das.tab.hh"
+
+#ifdef TRACE_NEW
+#include "trace_new.h"
+#endif
+
+#define yylex daslex
+#define yyerror daserror 
+
+using namespace std;
+using namespace libdap ;
+
+// These macros are used to access the `arguments' passed to the parser. A
+// pointer to an error object and a pointer to an integer status variable are
+// passed in to the parser within a structure (which itself is passed as a
+// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *. 
+// The parser now throws an exception when it encounters an error. 5/23/2002
+// jhrg 
+
+#define DAS_OBJ(arg) ((DAS *)((parser_arg *)(arg))->_object)
+
+#define YYPARSE_PARAM arg
+
+extern int das_line_num;	/* defined in das.lex */
+
+// No global static objects. We go through this every so often, I guess I
+// should learn... 1/24/2000 jhrg
+static string *name;	/* holds name in attr_pair rule */
+static string *type;	/* holds type in attr_pair rule */
+
+static vector<AttrTable *> *attr_tab_stack;
+
+// I use a vector of AttrTable pointers for a stack
+
+#define TOP_OF_STACK (attr_tab_stack->back())
+#define PUSH(x) (attr_tab_stack->push_back((x)))
+#define POP (attr_tab_stack->pop_back())
+#define STACK_LENGTH (attr_tab_stack->size())
+#define OUTER_TABLE_ONLY (attr_tab_stack->size() == 1)
+#define STACK_EMPTY (attr_tab_stack->empty())
+
+#define TYPE_NAME_VALUE(x) *type << " " << *name << " " << (x)
+
+static const char *ATTR_TUPLE_MSG = 
+"Expected an attribute type (Byte, Int16, UInt16, Int32, UInt32, Float32,\n\
+Float64, String or Url) followed by a name and value.";
+static const char *NO_DAS_MSG =
+"The attribute object returned from the dataset was null\n\
+Check that the URL is correct.";
+
+typedef int checker(const char *);
+
+int daslex(void);
+static void daserror(char *s);
+static void add_attribute(const string &type, const string &name, 
+			  const string &value, checker *chk) throw (Error);
+static void add_alias(AttrTable *das, AttrTable *current, const string &name, 
+		      const string &src) throw (Error);
+static void add_bad_attribute(AttrTable *attr, const string &type,
+			      const string &name, const string &value,
+			      const string &msg);
+
+%}
+
+%expect 26
+
+%token SCAN_ATTR
+
+%token SCAN_WORD
+
+%token SCAN_ALIAS
+
+%token SCAN_BYTE
+%token SCAN_INT16
+%token SCAN_UINT16
+%token SCAN_INT32
+%token SCAN_UINT32
+%token SCAN_FLOAT32
+%token SCAN_FLOAT64
+%token SCAN_STRING
+%token SCAN_URL
+%token SCAN_XML
+
+%%
+
+/*
+  Parser algorithm: 
+
+  Look for a `variable' name (this can be any identifier, but by convention
+  it is either the name of a variable in a dataset or the name of a grouping
+  of global attributes). Create a new attribute table for this identifier and
+  push the new attribute table onto a stack. If attribute tuples
+  (type-name-value tuples) are found, intern them in the attribute table
+  found on the top of the stack. If the start of a new attribute table if
+  found (before the current table is closed), create the new table and push
+  *it* on the stack. As attribute tables are closed, pop them off the stack.
+  This algorithm ensures that we can nest attribute tables to an arbitrary
+  depth.
+
+  Aliases are handled using mfuncs of both the DAS and AttrTable objects. This
+  is necessary because the first level of a DAS object can contain only
+  AttrTables, not attribute tuples. Whereas, the subsequent levels can
+  contain both. Thus the compete definition is split into two objects. In
+  part this is also a hold over from an older design which did not
+  have the recursive properties of the current design.
+
+  Aliases can be made between attributes within a given lexical level, from
+  one level to the next within a sub-hierarchy or across hierarchies.
+
+  Tokens:
+
+  BYTE, INT32, UINT32, FLOAT64, STRING and URL are tokens for the type
+  keywords. The tokens INT, FLOAT, STR and ID are returned by the scanner to
+  indicate the type of the value represented by the string contained in the
+  global DASLVAL. These two types of tokens are used to implement type
+  checking for the attributes. See the rules `bytes', etc. Additional tokens:
+  ATTR (indicates the start of an attribute object) and ALIAS (indicates an
+  alias). */
+
+/* This rule makes sure the objects needed by this parser are built. Because
+   the DODS DAP library is often used with linkers that are not C++-aware, we
+   cannot use global objects (because their constructors might never be
+   called). I had thought this was going to go away... 1/24/2000 jhrg */
+
+attr_start:
+	{
+		name = new string();
+		type = new string();
+		attr_tab_stack = new vector<AttrTable *>;
+
+		// push outermost AttrTable
+		PUSH(DAS_OBJ(arg)->get_top_level_attributes());
+	}
+        attributes
+        {
+		POP;	// pop the DAS/AttrTable before stack's dtor
+		delete name;
+		delete type;
+		delete attr_tab_stack;
+	}
+;
+
+attributes:     attribute
+    	    	| attributes attribute
+
+;
+    	    	
+attribute:    	SCAN_ATTR '{' attr_list '}'
+                | error
+                {
+		    parse_error((parser_arg *)arg, NO_DAS_MSG, das_line_num);
+		}
+;
+
+attr_list:  	/* empty */
+    	    	| attr_tuple
+    	    	| attr_list attr_tuple
+;
+
+attr_tuple:	alias
+
+                | SCAN_BYTE { save_str(*type, "Byte", das_line_num); }
+                name { save_str(*name, $3, das_line_num); } 
+		bytes ';'
+
+		| SCAN_INT16 { save_str(*type, "Int16", das_line_num); } 
+                name { save_str(*name, $3, das_line_num); } 
+		int16 ';'
+
+		| SCAN_UINT16 { save_str(*type, "UInt16", das_line_num); } 
+                name { save_str(*name, $3, das_line_num); } 
+		uint16 ';'
+
+		| SCAN_INT32 { save_str(*type, "Int32", das_line_num); } 
+                name { save_str(*name, $3, das_line_num); } 
+		int32 ';'
+
+		| SCAN_UINT32 { save_str(*type, "UInt32", das_line_num); } 
+                name { save_str(*name, $3, das_line_num); } 
+		uint32 ';'
+
+		| SCAN_FLOAT32 { save_str(*type, "Float32", das_line_num); } 
+                name { save_str(*name, $3, das_line_num); } 
+		float32 ';'
+
+		| SCAN_FLOAT64 { save_str(*type, "Float64", das_line_num); } 
+                name { save_str(*name, $3, das_line_num); } 
+		float64 ';'
+
+		| SCAN_STRING { *type = "String"; } 
+                name { *name = $3; } 
+		strs ';'
+
+                | SCAN_URL { *type = "Url"; } 
+                name { *name = $3; } 
+                urls ';'
+
+                | SCAN_XML { *type = "OtherXML"; } 
+                name { *name = $3; } 
+                xml ';'
+
+		| SCAN_WORD
+                {
+		    DBG(cerr << "Processing ID: " << $1 << endl);
+		    
+		    AttrTable *at = TOP_OF_STACK->get_attr_table($1);
+		    if (!at) {
+			try {
+			    at = TOP_OF_STACK->append_container($1);
+			}
+			catch (Error &e) {
+			    // re-throw with line number info
+			    parse_error(e.get_error_message().c_str(), 
+					das_line_num);
+			}
+		    }
+		    PUSH(at);
+
+		    DBG(cerr << " Pushed attr_tab: " << at << endl);
+
+		}
+		'{' attr_list 
+                {
+		    /* pop top of stack; store in attr_tab */
+		    DBG(cerr << " Popped attr_tab: " << TOP_OF_STACK << endl);
+		    POP;
+		}
+		'}'
+
+		| error 
+                { 
+		    parse_error(ATTR_TUPLE_MSG, das_line_num, $1);
+		} ';'
+;
+
+bytes:		SCAN_WORD
+		{
+		    add_attribute(*type, *name, $1, &check_byte);
+		}
+		| bytes ',' SCAN_WORD
+		{
+		    add_attribute(*type, *name, $3, &check_byte);
+		}
+;
+
+int16:		SCAN_WORD
+		{
+		    add_attribute(*type, *name, $1, &check_int16);
+		}
+		| int16 ',' SCAN_WORD
+		{
+		    add_attribute(*type, *name, $3, &check_int16);
+		}
+;
+
+uint16:		SCAN_WORD
+		{
+		    add_attribute(*type, *name, $1, &check_uint16);
+		}
+		| uint16 ',' SCAN_WORD
+		{
+		    add_attribute(*type, *name, $3, &check_uint16);
+		}
+;
+
+int32:		SCAN_WORD
+		{
+		    add_attribute(*type, *name, $1, &check_int32);
+		}
+		| int32 ',' SCAN_WORD
+		{
+		    add_attribute(*type, *name, $3, &check_int32);
+		}
+;
+
+uint32:		SCAN_WORD
+		{
+		    add_attribute(*type, *name, $1, &check_uint32);
+		}
+		| uint32 ',' SCAN_WORD
+		{
+		    add_attribute(*type, *name, $3, &check_uint32);
+		}
+;
+
+float32:	float_or_int
+		{
+		    add_attribute(*type, *name, $1, &check_float32);
+		}
+		| float32 ',' float_or_int
+		{
+		    add_attribute(*type, *name, $3, &check_float32);
+		}
+;
+
+float64:	float_or_int
+		{
+		    add_attribute(*type, *name, $1, &check_float64);
+		}
+		| float64 ',' float_or_int
+		{
+		    add_attribute(*type, *name, $3, &check_float64);
+		}
+;
+
+strs:		str_or_id
+		{
+		    string attr = remove_quotes($1);
+		    add_attribute(*type, *name, attr, 0);
+		}
+		| strs ',' str_or_id
+		{
+		    string attr = remove_quotes($3);
+		    add_attribute(*type, *name, attr, 0);
+		}
+;
+
+urls:           url
+                {
+                    add_attribute(*type, *name, $1, &check_url);
+                }
+                | urls ',' url
+                {
+                    add_attribute(*type, *name, $3, &check_url);
+                }
+;
+
+xml:            SCAN_WORD
+                {
+                    // XML must be quoted in the DAS but the quotes are an
+                    // artifact of the DAS syntax so they are not part of the
+                    // value.
+                    cerr << "Attr value as read: " << $1 << endl;
+                    string xml = unescape_double_quotes($1);
+                    cerr << "w/o quotes: " << remove_quotes(xml) << endl;
+                    
+                    if (is_quoted(xml))
+                        add_attribute(*type, *name, remove_quotes(xml), 0);
+                    else
+                        add_attribute(*type, *name, xml, 0);
+                }
+;
+
+url:		SCAN_WORD
+;
+
+str_or_id:	SCAN_WORD
+;
+
+float_or_int:   SCAN_WORD
+;
+
+name:           SCAN_WORD | SCAN_ATTR | SCAN_ALIAS | SCAN_BYTE | SCAN_INT16 
+                | SCAN_UINT16 | SCAN_INT32 | SCAN_UINT32 | SCAN_FLOAT32 
+                | SCAN_FLOAT64 | SCAN_STRING | SCAN_URL | SCAN_XML
+;
+
+alias:          SCAN_ALIAS SCAN_WORD
+                { 
+		    *name = $2;
+		} 
+                SCAN_WORD
+                {
+		    add_alias( DAS_OBJ(arg)->get_top_level_attributes(),
+		               TOP_OF_STACK, *name, string($4) ) ;
+                }
+                ';'
+;
+
+%%
+
+// This function is required for linking, but DODS uses its own error
+// reporting mechanism.
+
+static void
+daserror(char *)
+{
+}
+
+static string
+a_or_an(const string &subject)
+{
+    string first_char(1, subject[0]);
+    string::size_type pos = first_char.find_first_of("aeiouAEIOUyY");
+    
+    if (pos == string::npos)
+	return "a";
+    else
+	return "an";
+}
+
+// This code used to throw an exception when a bad attribute value came
+// along; now it dumps the errant value(s) into a sub container called *_DODS
+// and stores the parser's error message in a string attribute named
+// `explanation.' 
+static void
+add_attribute(const string &type, const string &name, const string &value,
+	      checker *chk) throw (Error)
+{
+    DBG(cerr << "Adding: " << type << " " << name << " " << value \
+	<< " to Attrtable: " << TOP_OF_STACK << endl);
+
+    if (chk && !(*chk)(value.c_str())) {
+	string msg = "`";
+	msg += value + "' is not " + a_or_an(type) + " " + type + " value.";
+	add_bad_attribute(TOP_OF_STACK, type, name, value, msg);
+	return;
+    }
+    
+    if (STACK_EMPTY) {
+	string msg = "Whoa! Attribute table stack empty when adding `" ;
+	msg += name + ".' ";
+	parse_error(msg, das_line_num);
+    }
+    
+    try {
+#if 0
+        // Special treatment for XML: remove the double quotes that were 
+        // included in the value by this parser.
+        if (type == OtherXML && is_quoted(value))
+            TOP_OF_STACK->append_attr(name, type, value.substr(1, value.size()-2));
+        else    
+#endif
+	    TOP_OF_STACK->append_attr(name, type, value);
+    }
+    catch (Error &e) {
+	// re-throw with line number
+	parse_error(e.get_error_message().c_str(), das_line_num);
+    }
+}
+
+static void
+add_alias(AttrTable *das, AttrTable *current, const string &name, 
+	  const string &src) throw (Error)
+{
+    DBG(cerr << "Adding an alias: " << name << ": " << src << endl);
+
+    AttrTable *table = das->get_attr_table(src);
+    if (table) {
+	try {
+	    current->add_container_alias(name, table);
+	}
+	catch (Error &e) {
+	    parse_error(e.get_error_message().c_str(), das_line_num);
+	}
+    }
+    else {
+	try {
+	    current->add_value_alias(das, name, src);
+	}
+	catch (Error &e) {
+	    parse_error(e.get_error_message().c_str(), das_line_num);
+	}
+    }
+}
+
+static void
+add_bad_attribute(AttrTable *attr, const string &type, const string &name,
+		  const string &value, const string &msg)
+{
+    // First, if this bad value is already in a *_dods_errors container,
+    // then just add it. This can happen when the server side processes a DAS
+    // and then hands it off to a client which does the same.
+    // Make a new container. Call it <attr's name>_errors. If that container
+    // already exists, use it.
+    // Add the attribute.
+    // Add the error string to an attribute in the container called
+    // `<name_explanation.'. 
+    
+    if (attr->get_name().find("_dods_errors") != string::npos) {
+	attr->append_attr(name, type, value);
+    }
+    else {
+	string error_cont_name = attr->get_name() + "_dods_errors";
+	AttrTable *error_cont = attr->get_attr_table(error_cont_name);
+	if (!error_cont)
+	    error_cont = attr->append_container(error_cont_name);
+
+	error_cont->append_attr(name, type, value);
+#ifndef ATTR_STRING_QUOTE_FIX
+    error_cont->append_attr(name + "_explanation", "String",
+                "\"" + msg + "\"");
+#else
+       error_cont->append_attr(name + "_explanation", "String", msg);
+#endif
+    }
+}
+
diff --git a/dds.lex b/dds.lex
new file mode 100644
index 0000000..b1cd0de
--- /dev/null
+++ b/dds.lex
@@ -0,0 +1,195 @@
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-1999
+
+*/
+
+/*
+   Scanner for the DDS. This file works with gnu's flex scanner generator. It
+   returns either DATASET, INDEPENDENT, DEPENDENT, ARRAY, MAPS, LIST,
+   SEQUENCE, STRUCTURE, FUNCTION, GRID, BYTE, INT32, FLOAT64, STRING, URL, ID
+   or one of the single character tokens `{', `}', `;', `=' or `\n' as
+   integers. In the case of an ID, the scanner stores a pointer to the lexeme
+   in yylval (whose type is char *).
+
+   The scanner discards all comment text.
+
+   The scanner is not reentrant, but can share name spaces with other
+   scanners.
+
+   Note:
+   1) The `defines' file dds.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `ddslex'.
+   3) When bison builds the dds.tab.h file, it uses `dds' instead of `yy' for
+   variable name prefixes (e.g., yylval --> ddslval).
+
+   jhrg 8/29/94
+*/
+
+%{
+
+#include "config_dap.h"
+
+#include <cstdio>
+#include <cstring>
+
+static char rcsid[] not_used = {"$Id: dds.lex 20716 2009-04-08 19:50:54Z jimg $"};
+
+#include "parser.h"
+#include "dds.tab.hh"
+#include "escaping.h"
+
+using namespace libdap ;
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_DECL int ddslex YY_PROTO(( void ))
+
+#define YY_INPUT(buf,result,max_size) { \
+    if (fgets((buf), (max_size), (ddsin)) == NULL) { \
+      *buf = '\0'; \
+    } \
+    result = (feof(ddsin) || *buf == '\0' || strncmp(buf, "Data:\n", 6) == 0) \
+             ? YY_NULL : strlen(buf); \
+}
+
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning DDS object text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+int dds_line_num = 1;
+
+static void store_word();
+
+%}
+
+%option noyywrap
+%option prefix="dds"
+%option outfile="lex.dds.cc"
+%x comment
+
+DATASET 	DATASET|Dataset|dataset
+LIST 		LIST|List|list
+SEQUENCE 	SEQUENCE|Sequence|sequence
+STRUCTURE 	STRUCTURE|Structure|structure
+GRID 		GRID|Grid|grid
+BYTE 		BYTE|Byte|byte
+INT16 		INT16|Int16|int16
+UINT16 		UINT16|UInt16|uint16
+INT32 		INT32|Int32|int32
+UINT32 		UINT32|UInt32|uint32
+FLOAT32 	FLOAT32|Float32|float32
+FLOAT64 	FLOAT64|Float64|float64
+STRING 		STRING|String|string
+URL 		URL|Url|url
+
+/* See das.lex for comments about the characters allowed in a WORD.
+   10/31/2001 jhrg */
+
+WORD        [-+a-zA-Z0-9_/%.\\*][-+a-zA-Z0-9_/%.\\#*]*
+
+NEVER		[^\-+a-zA-Z0-9_/%.\\#,(){}[\]]
+
+%%
+
+"{"         return (int)*yytext;
+"}" 	    return (int)*yytext;
+"["			return (int)*yytext;
+"]"			return (int)*yytext;
+":"			return (int)*yytext;
+";" 	    return (int)*yytext;
+"="			return (int)*yytext;
+
+{DATASET}		store_word(); return SCAN_DATASET;
+{LIST}			store_word(); return SCAN_LIST;
+{SEQUENCE}		store_word(); return SCAN_SEQUENCE;
+{STRUCTURE}		store_word(); return SCAN_STRUCTURE;
+{GRID}			store_word(); return SCAN_GRID;
+{BYTE}			store_word(); return SCAN_BYTE;
+{INT16}			store_word(); return SCAN_INT16;
+{UINT16}		store_word(); return SCAN_UINT16;
+{INT32}			store_word(); return SCAN_INT32;
+{UINT32}		store_word(); return SCAN_UINT32;
+{FLOAT32}		store_word(); return SCAN_FLOAT32;
+{FLOAT64}		store_word(); return SCAN_FLOAT64;
+{STRING}		store_word(); return SCAN_STRING;
+{URL}			store_word(); return SCAN_URL;
+
+{WORD}      store_word(); return SCAN_WORD;
+
+[ \t\r]+
+\n	    	++dds_line_num;
+<INITIAL><<EOF>>    yy_init = 1; dds_line_num = 1; yyterminate();
+
+"#"     BEGIN(comment);
+<comment>[^\n]*
+<comment>\n		++dds_line_num; BEGIN(INITIAL);
+<comment><<EOF>>    yy_init = 1; dds_line_num = 1; yyterminate();
+
+"Data:\n"		yyterminate();
+"Data:\r\n"		yyterminate();
+
+{NEVER} {
+            if (yytext) {	/* suppress msgs about `' chars */
+                fprintf(stderr, "Character `%c' is not", *yytext);
+                fprintf(stderr, " allowed and has been ignored\n");
+	    }
+	}
+%%
+
+// These three glue routines enable DDS to reclaim the memory used to parse a
+// DDS off the wire. They are here because this file can see the YY_*
+// symbols; the file DDS.cc cannot.
+
+void *
+dds_buffer(FILE *fp)
+{
+    return (void *)dds_create_buffer(fp, YY_BUF_SIZE);
+}
+
+void
+dds_switch_to_buffer(void *buf)
+{
+    dds_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+dds_delete_buffer(void *buf)
+{
+    dds_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+static void
+store_word()
+{
+    // dods2id(string(yytext)).c_str()
+    strncpy(ddslval.word, yytext, ID_MAX-1);
+    ddslval.word[ID_MAX-1] = '\0'; // for the paranoid...
+}
+
diff --git a/dds.tab.cc b/dds.tab.cc
new file mode 100644
index 0000000..d83f4f6
--- /dev/null
+++ b/dds.tab.cc
@@ -0,0 +1,2177 @@
+/* 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 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse ddsparse
+#define yylex   ddslex
+#define yyerror ddserror
+#define yylval  ddslval
+#define yychar  ddschar
+#define yydebug ddsdebug
+#define yynerrs ddsnerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_WORD = 258,
+     SCAN_DATASET = 259,
+     SCAN_LIST = 260,
+     SCAN_SEQUENCE = 261,
+     SCAN_STRUCTURE = 262,
+     SCAN_FUNCTION = 263,
+     SCAN_GRID = 264,
+     SCAN_BYTE = 265,
+     SCAN_INT16 = 266,
+     SCAN_UINT16 = 267,
+     SCAN_INT32 = 268,
+     SCAN_UINT32 = 269,
+     SCAN_FLOAT32 = 270,
+     SCAN_FLOAT64 = 271,
+     SCAN_STRING = 272,
+     SCAN_URL = 273
+   };
+#endif
+/* Tokens.  */
+#define SCAN_WORD 258
+#define SCAN_DATASET 259
+#define SCAN_LIST 260
+#define SCAN_SEQUENCE 261
+#define SCAN_STRUCTURE 262
+#define SCAN_FUNCTION 263
+#define SCAN_GRID 264
+#define SCAN_BYTE 265
+#define SCAN_INT16 266
+#define SCAN_UINT16 267
+#define SCAN_INT32 268
+#define SCAN_UINT32 269
+#define SCAN_FLOAT32 270
+#define SCAN_FLOAT64 271
+#define SCAN_STRING 272
+#define SCAN_URL 273
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 47 "dds.y"
+
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: dds.y 21577 2009-10-02 16:12:17Z jimg $"};
+
+#include <cstring>
+#include <cassert>
+#include <iostream>
+#include <stack>
+#include <sstream>
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "Error.h"
+#include "parser.h"
+#include "util.h"
+
+using namespace std;
+using namespace libdap;
+
+// These macros are used to access the `arguments' passed to the parser. A
+// pointer to an error object and a pointer to an integer status variable are
+// passed in to the parser within a structure (which itself is passed as a
+// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *. 
+// ERROR is no longer used. These parsers now signal problems by throwing
+// exceptions. 5/22/2002 jhrg
+#define DDS_OBJ(arg) ((DDS *)((parser_arg *)(arg))->_object)
+
+#define YYPARSE_PARAM arg
+
+extern int dds_line_num;	/* defined in dds.lex */
+
+// No global static objects in the dap library! 1/24/2000 jhrg
+static stack<BaseType *> *ctor;
+static BaseType *current;
+static string *id;
+static Part part = nil;		/* Part is defined in BaseType */
+
+static const char *NO_DDS_MSG =
+"The descriptor object returned from the dataset was null.\n\
+Check that the URL is correct.";
+
+static const char *BAD_DECLARATION =
+"In the dataset descriptor object: Expected a variable declaration\n\
+(e.g., Int32 i;). Make sure that the variable name is not the name\n\
+of a datatype and that the Array: and Maps: sections of a Grid are\n\
+labeled properly.";
+ 
+int ddslex();
+void ddserror(char *s);
+void error_exit_cleanup();
+void add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current, 
+	       Part p);
+void invalid_declaration(parser_arg *arg, string semantic_err_msg, 
+			 char *type, char *name);
+
+
+
+/* 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
+#line 121 "dds.y"
+{
+    bool boolean;
+    char word[ID_MAX];
+}
+/* Line 187 of yacc.c.  */
+#line 217 "dds.tab.cc"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 230 "dds.tab.cc"
+
+#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__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# 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 YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* 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)) \
+      + 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  3
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   194
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  26
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  22
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  56
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  88
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   273
+
+#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,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    22,    21,
+       2,    25,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,    23,     2,    24,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,    19,     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,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18
+};
+
+#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,    12,    19,    21,    22,
+      24,    27,    31,    32,    40,    41,    49,    50,    51,    52,
+      67,    69,    71,    73,    75,    77,    79,    81,    83,    85,
+      87,    89,    91,    93,    95,    98,   100,   102,   104,   106,
+     108,   110,   112,   114,   116,   118,   120,   122,   124,   126,
+     130,   131,   132,   140,   142,   144,   146
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      27,     0,    -1,    -1,    28,    29,    -1,    30,    -1,    29,
+      30,    -1,     4,    19,    31,    20,    47,    21,    -1,     1,
+      -1,    -1,    32,    -1,    31,    32,    -1,    41,    42,    21,
+      -1,    -1,    38,    19,    31,    20,    33,    42,    21,    -1,
+      -1,    39,    19,    31,    20,    34,    42,    21,    -1,    -1,
+      -1,    -1,    40,    19,     3,    22,    35,    32,     3,    22,
+      36,    31,    20,    37,    42,    21,    -1,     1,    -1,     7,
+      -1,     6,    -1,     9,    -1,    10,    -1,    11,    -1,    12,
+      -1,    13,    -1,    14,    -1,    15,    -1,    16,    -1,    17,
+      -1,    18,    -1,    43,    -1,    42,    44,    -1,     3,    -1,
+      10,    -1,    11,    -1,    13,    -1,    12,    -1,    14,    -1,
+      15,    -1,    16,    -1,    17,    -1,    18,    -1,     7,    -1,
+       6,    -1,     9,    -1,     5,    -1,    23,     3,    24,    -1,
+      -1,    -1,    23,     3,    45,    25,     3,    46,    24,    -1,
+       1,    -1,    43,    -1,     4,    -1,     1,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   150,   150,   150,   160,   161,   164,   168,   178,   182,
+     183,   190,   213,   212,   233,   232,   253,   265,   277,   252,
+     298,   309,   315,   321,   327,   328,   329,   330,   331,   332,
+     333,   334,   335,   338,   339,   342,   342,   342,   342,   342,
+     343,   343,   343,   343,   344,   344,   344,   344,   345,   348,
+     372,   376,   371,   403,   414,   415,   416
+};
+#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", "SCAN_WORD", "SCAN_DATASET", "SCAN_LIST",
+  "SCAN_SEQUENCE", "SCAN_STRUCTURE", "SCAN_FUNCTION", "SCAN_GRID",
+  "SCAN_BYTE", "SCAN_INT16", "SCAN_UINT16", "SCAN_INT32", "SCAN_UINT32",
+  "SCAN_FLOAT32", "SCAN_FLOAT64", "SCAN_STRING", "SCAN_URL", "'{'", "'}'",
+  "';'", "':'", "'['", "']'", "'='", "$accept", "start", "@1", "datasets",
+  "dataset", "declarations", "declaration", "@2", "@3", "@4", "@5", "@6",
+  "structure", "sequence", "grid", "base_type", "var", "var_name",
+  "array_decl", "@7", "@8", "name", 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,   123,
+     125,    59,    58,    91,    93,    61
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    26,    28,    27,    29,    29,    30,    30,    31,    31,
+      31,    32,    33,    32,    34,    32,    35,    36,    37,    32,
+      32,    38,    39,    40,    41,    41,    41,    41,    41,    41,
+      41,    41,    41,    42,    42,    43,    43,    43,    43,    43,
+      43,    43,    43,    43,    43,    43,    43,    43,    43,    44,
+      45,    46,    44,    44,    47,    47,    47
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     2,     6,     1,     0,     1,
+       2,     3,     0,     7,     0,     7,     0,     0,     0,    14,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     2,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     3,
+       0,     0,     7,     1,     1,     1,     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,     0,     1,     7,     0,     0,     4,     0,     5,
+      20,    22,    21,    23,    24,    25,    26,    27,    28,    29,
+      30,    31,    32,     0,     9,     0,     0,     0,     0,     0,
+      10,     0,     0,     0,    35,    48,    46,    45,    47,    36,
+      37,    39,    38,    40,    41,    42,    43,    44,     0,    33,
+      56,    55,    54,     0,     0,     0,     0,    53,    11,     0,
+      34,     6,    12,    14,    16,    50,     0,     0,     0,    49,
+       0,     0,     0,     0,     0,    13,    15,     0,    51,    17,
+       0,     0,    52,     0,    18,     0,     0,    19
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     1,     2,     6,     7,    23,    24,    66,    67,    68,
+      81,    85,    25,    26,    27,    28,    48,    49,    60,    70,
+      80,    53
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -53
+static const yytype_int16 yypact[] =
+{
+     -53,    11,     9,   -53,   -53,    -7,     5,   -53,    52,   -53,
+     -53,   -53,   -53,   -53,   -53,   -53,   -53,   -53,   -53,   -53,
+     -53,   -53,   -53,    70,   -53,    -3,    -2,    -1,   176,   142,
+     -53,    52,    52,    16,   -53,   -53,   -53,   -53,   -53,   -53,
+     -53,   -53,   -53,   -53,   -53,   -53,   -53,   -53,     2,   -53,
+     -53,   -53,   -53,     0,    88,   106,    12,   -53,   -53,    17,
+     -53,   -53,   -53,   -53,   -53,    13,   176,   176,   160,   -53,
+      10,     3,     6,    19,    33,   -53,   -53,    18,   -53,   -53,
+      14,    52,   -53,   124,   -53,   176,     7,   -53
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -53,   -53,   -53,   -53,    35,   -30,   -23,   -53,   -53,   -53,
+     -53,   -53,   -53,   -53,   -53,   -53,   -52,    15,   -53,   -53,
+     -53,   -53
+};
+
+/* 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 -9
+static const yytype_int8 yytable[] =
+{
+      30,    54,    55,    57,    57,    -3,     4,    57,    57,     5,
+       4,     3,     8,     5,    71,    72,    31,    32,    33,    56,
+      65,    61,    77,    58,    75,    59,    59,    76,    87,    59,
+      59,    30,    30,    86,    64,    74,    78,    69,    82,     0,
+      79,     9,     0,     0,    52,    73,     0,     0,     0,     0,
+       0,    83,     0,    10,     0,     0,     0,     0,    11,    12,
+      30,    13,    14,    15,    16,    17,    18,    19,    20,    21,
+      22,    10,    -8,     0,     0,     0,    11,    12,     0,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    10,
+      29,     0,     0,     0,    11,    12,     0,    13,    14,    15,
+      16,    17,    18,    19,    20,    21,    22,    10,    62,     0,
+       0,     0,    11,    12,     0,    13,    14,    15,    16,    17,
+      18,    19,    20,    21,    22,    10,    63,     0,     0,     0,
+      11,    12,     0,    13,    14,    15,    16,    17,    18,    19,
+      20,    21,    22,    50,    84,    34,    51,    35,    36,    37,
+       0,    38,    39,    40,    41,    42,    43,    44,    45,    46,
+      47,    10,     0,     0,     0,     0,    11,    12,     0,    13,
+      14,    15,    16,    17,    18,    19,    20,    21,    22,    34,
+       0,    35,    36,    37,     0,    38,    39,    40,    41,    42,
+      43,    44,    45,    46,    47
+};
+
+static const yytype_int8 yycheck[] =
+{
+      23,    31,    32,     1,     1,     0,     1,     1,     1,     4,
+       1,     0,    19,     4,    66,    67,    19,    19,    19,     3,
+       3,    21,     3,    21,    21,    23,    23,    21,    21,    23,
+      23,    54,    55,    85,    22,    25,     3,    24,    24,    -1,
+      22,     6,    -1,    -1,    29,    68,    -1,    -1,    -1,    -1,
+      -1,    81,    -1,     1,    -1,    -1,    -1,    -1,     6,     7,
+      83,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,     1,    20,    -1,    -1,    -1,     6,     7,    -1,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,     1,
+      20,    -1,    -1,    -1,     6,     7,    -1,     9,    10,    11,
+      12,    13,    14,    15,    16,    17,    18,     1,    20,    -1,
+      -1,    -1,     6,     7,    -1,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18,     1,    20,    -1,    -1,    -1,
+       6,     7,    -1,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,     1,    20,     3,     4,     5,     6,     7,
+      -1,     9,    10,    11,    12,    13,    14,    15,    16,    17,
+      18,     1,    -1,    -1,    -1,    -1,     6,     7,    -1,     9,
+      10,    11,    12,    13,    14,    15,    16,    17,    18,     3,
+      -1,     5,     6,     7,    -1,     9,    10,    11,    12,    13,
+      14,    15,    16,    17,    18
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    27,    28,     0,     1,     4,    29,    30,    19,    30,
+       1,     6,     7,     9,    10,    11,    12,    13,    14,    15,
+      16,    17,    18,    31,    32,    38,    39,    40,    41,    20,
+      32,    19,    19,    19,     3,     5,     6,     7,     9,    10,
+      11,    12,    13,    14,    15,    16,    17,    18,    42,    43,
+       1,     4,    43,    47,    31,    31,     3,     1,    21,    23,
+      44,    21,    20,    20,    22,     3,    33,    34,    35,    24,
+      45,    42,    42,    32,    25,    21,    21,     3,     3,    22,
+      46,    36,    24,    31,    20,    37,    42,    21
+};
+
+#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 (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 (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#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); \
+      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)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# 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)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  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, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#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)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} 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)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  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 (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| 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 (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  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;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* 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;
+
+  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;
+
+
+	/* 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),
+
+		    &yystacksize);
+
+	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);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + 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;
+
+  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];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 150 "dds.y"
+    {
+		    /* On entry to the parser, make the BaseType stack. */
+		    ctor = new stack<BaseType *>;
+                ;}
+    break;
+
+  case 3:
+#line 155 "dds.y"
+    {
+		    delete ctor; ctor = 0;
+		;}
+    break;
+
+  case 6:
+#line 165 "dds.y"
+    {
+		    (yyval.boolean) = (yyvsp[(3) - (6)].boolean) && (yyvsp[(5) - (6)].word);
+		;}
+    break;
+
+  case 7:
+#line 169 "dds.y"
+    {
+		    parse_error((parser_arg *)arg, NO_DDS_MSG,
+ 				dds_line_num, (yyvsp[(1) - (1)].word));
+		    error_exit_cleanup();
+		    YYABORT;
+		;}
+    break;
+
+  case 8:
+#line 178 "dds.y"
+    {
+		    (yyval.boolean) = true;
+		;}
+    break;
+
+  case 9:
+#line 182 "dds.y"
+    { (yyval.boolean) = true; ;}
+    break;
+
+  case 10:
+#line 183 "dds.y"
+    { (yyval.boolean) = true; ;}
+    break;
+
+  case 11:
+#line 191 "dds.y"
+    { 
+		    string smsg;
+		    if (current->check_semantics(smsg)) {
+			/* BaseType *current_save = current ; */
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+			/* FIX
+			if( current_save == current )
+			{
+			    delete current ;
+			    current = 0 ;
+			}
+			*/
+		    } else {
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[(1) - (3)].word), (yyvsp[(2) - (3)].word));
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy((yyval.word),(yyvsp[(2) - (3)].word),ID_MAX);
+                    (yyval.word)[ID_MAX-1] = '\0';
+		;}
+    break;
+
+  case 12:
+#line 213 "dds.y"
+    { 
+		    if( current ) delete current ;
+		    current = ctor->top(); 
+		    ctor->pop();
+		;}
+    break;
+
+  case 13:
+#line 219 "dds.y"
+    { 
+		    string smsg;
+		    if (current->check_semantics(smsg))
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+		    else {
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[(1) - (7)].word), (yyvsp[(6) - (7)].word));
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy((yyval.word),(yyvsp[(6) - (7)].word),ID_MAX);
+                    (yyval.word)[ID_MAX-1] = '\0';
+		;}
+    break;
+
+  case 14:
+#line 233 "dds.y"
+    { 
+		    if( current ) delete current ;
+		    current = ctor->top(); 
+		    ctor->pop();
+		;}
+    break;
+
+  case 15:
+#line 239 "dds.y"
+    { 
+		    string smsg;
+		    if (current->check_semantics(smsg))
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+		    else {
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[(1) - (7)].word), (yyvsp[(6) - (7)].word));
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy((yyval.word),(yyvsp[(6) - (7)].word),ID_MAX);
+                    (yyval.word)[ID_MAX-1] = '\0';
+		;}
+    break;
+
+  case 16:
+#line 253 "dds.y"
+    { 
+		    if (is_keyword(string((yyvsp[(3) - (4)].word)), "array"))
+			part = array; 
+		    else {
+			ostringstream msg;
+			msg << BAD_DECLARATION;
+			parse_error((parser_arg *)arg, msg.str().c_str(),
+				    dds_line_num, (yyvsp[(3) - (4)].word));
+			YYABORT;
+		    }
+                ;}
+    break;
+
+  case 17:
+#line 265 "dds.y"
+    { 
+		    if (is_keyword(string((yyvsp[(7) - (8)].word)), "maps"))
+			part = maps; 
+		    else {
+			ostringstream msg;
+			msg << BAD_DECLARATION;
+			parse_error((parser_arg *)arg, msg.str().c_str(),
+				    dds_line_num, (yyvsp[(7) - (8)].word));
+			YYABORT;
+		    }
+                ;}
+    break;
+
+  case 18:
+#line 277 "dds.y"
+    {
+		    if( current ) delete current ;
+		    current = ctor->top(); 
+		    ctor->pop();
+		;}
+    break;
+
+  case 19:
+#line 283 "dds.y"
+    {
+		    string smsg;
+		    if (current->check_semantics(smsg)) {
+			part = nil; 
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+		    }
+		    else {
+		      invalid_declaration((parser_arg *)arg, smsg, (yyvsp[(1) - (14)].word), (yyvsp[(13) - (14)].word));
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy((yyval.word),(yyvsp[(13) - (14)].word),ID_MAX);
+                    (yyval.word)[ID_MAX-1] = '\0';
+		;}
+    break;
+
+  case 20:
+#line 299 "dds.y"
+    {
+		    ostringstream msg;
+		    msg << BAD_DECLARATION;
+		    parse_error((parser_arg *)arg, msg.str().c_str(),
+				dds_line_num, (yyvsp[(1) - (1)].word));
+		    YYABORT;
+		;}
+    break;
+
+  case 21:
+#line 310 "dds.y"
+    { 
+		    ctor->push(DDS_OBJ(arg)->get_factory()->NewStructure()); 
+		;}
+    break;
+
+  case 22:
+#line 316 "dds.y"
+    { 
+		    ctor->push(DDS_OBJ(arg)->get_factory()->NewSequence()); 
+		;}
+    break;
+
+  case 23:
+#line 322 "dds.y"
+    { 
+		    ctor->push(DDS_OBJ(arg)->get_factory()->NewGrid()); 
+		;}
+    break;
+
+  case 24:
+#line 327 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewByte(); ;}
+    break;
+
+  case 25:
+#line 328 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt16(); ;}
+    break;
+
+  case 26:
+#line 329 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt16(); ;}
+    break;
+
+  case 27:
+#line 330 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt32(); ;}
+    break;
+
+  case 28:
+#line 331 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt32(); ;}
+    break;
+
+  case 29:
+#line 332 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat32(); ;}
+    break;
+
+  case 30:
+#line 333 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat64(); ;}
+    break;
+
+  case 31:
+#line 334 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewStr(); ;}
+    break;
+
+  case 32:
+#line 335 "dds.y"
+    { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUrl(); ;}
+    break;
+
+  case 33:
+#line 338 "dds.y"
+    { current->set_name((yyvsp[(1) - (1)].word)); ;}
+    break;
+
+  case 49:
+#line 349 "dds.y"
+    { 
+		     if (!check_int32((yyvsp[(2) - (3)].word))) {
+			 string msg = "In the dataset descriptor object:\n";
+			 msg += "Expected an array subscript.\n";
+			 parse_error((parser_arg *)arg, msg.c_str(), 
+				 dds_line_num, (yyvsp[(2) - (3)].word));
+		     }
+		     if (current->type() == dods_array_c
+			 && check_int32((yyvsp[(2) - (3)].word))) {
+			 ((Array *)current)->append_dim(atoi((yyvsp[(2) - (3)].word)));
+		     }
+		     else {
+			 Array *a = DDS_OBJ(arg)->get_factory()->NewArray(); 
+			 a->add_var(current); 
+			 a->append_dim(atoi((yyvsp[(2) - (3)].word)));
+			 if( current ) delete current ;
+			 current = a;
+		     }
+
+		     (yyval.boolean) = true;
+		 ;}
+    break;
+
+  case 50:
+#line 372 "dds.y"
+    {
+		     id = new string((yyvsp[(2) - (2)].word));
+		 ;}
+    break;
+
+  case 51:
+#line 376 "dds.y"
+    { 
+		     if (!check_int32((yyvsp[(5) - (5)].word))) {
+			 string msg = "In the dataset descriptor object:\n";
+			 msg += "Expected an array subscript.\n";
+			 parse_error((parser_arg *)arg, msg.c_str(), 
+				 dds_line_num, (yyvsp[(5) - (5)].word));
+			 error_exit_cleanup();
+			 YYABORT;
+		     }
+		     if (current->type() == dods_array_c) {
+			 ((Array *)current)->append_dim(atoi((yyvsp[(5) - (5)].word)), *id);
+		     }
+		     else {
+			 Array *a = DDS_OBJ(arg)->get_factory()->NewArray(); 
+			 a->add_var(current); 
+			 a->append_dim(atoi((yyvsp[(5) - (5)].word)), *id);
+			 if( current ) delete current ;
+			 current = a;
+		     }
+
+		     delete id; id = 0;
+		 ;}
+    break;
+
+  case 52:
+#line 399 "dds.y"
+    {
+		     (yyval.boolean) = true;
+		 ;}
+    break;
+
+  case 53:
+#line 404 "dds.y"
+    {
+		     ostringstream msg;
+		     msg << "In the dataset descriptor object:" << endl
+			 << "Expected an array subscript." << endl;
+		     parse_error((parser_arg *)arg, msg.str().c_str(), 
+				 dds_line_num, (yyvsp[(1) - (1)].word));
+		     YYABORT;
+		 ;}
+    break;
+
+  case 54:
+#line 414 "dds.y"
+    { (*DDS_OBJ(arg)).set_dataset_name((yyvsp[(1) - (1)].word)); ;}
+    break;
+
+  case 55:
+#line 415 "dds.y"
+    { (*DDS_OBJ(arg)).set_dataset_name((yyvsp[(1) - (1)].word)); ;}
+    break;
+
+  case 56:
+#line 417 "dds.y"
+    {
+		  ostringstream msg;
+		  msg << "Error parsing the dataset name." << endl
+		      << "The name may be missing or may contain an illegal character." << endl;
+		     parse_error((parser_arg *)arg, msg.str().c_str(),
+				 dds_line_num, (yyvsp[(1) - (1)].word));
+		     YYABORT;
+		;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1880 "dds.tab.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* 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 (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 (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  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);
+	  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;
+
+  /* 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;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* 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 (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* 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);
+      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);
+}
+
+
+#line 427 "dds.y"
+
+
+/* 
+   This function must be defined. However, use the error reporting code in
+   parser-utils.cc.
+*/
+
+void 
+ddserror(char *)
+{
+}
+
+/*
+  Error clean up. Call this before calling YYBORT. Don't call this on a
+  normal exit.
+*/
+
+void
+error_exit_cleanup()
+{
+    delete id; id = 0;
+    delete current; current = 0;
+    delete ctor; ctor = 0;
+}
+
+/*
+  Invalid declaration message.
+*/
+
+void
+invalid_declaration(parser_arg *arg, string semantic_err_msg, char *type, 
+		    char *name)
+{
+  ostringstream msg;
+  msg << "In the dataset descriptor object: `" << type << " " << name 
+      << "'" << endl << "is not a valid declaration." << endl 
+      << semantic_err_msg;
+  parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num);
+}
+
+/*
+  Add the variable pointed to by CURRENT to either the topmost ctor object on
+  the stack CTOR or to the dataset variable table TABLE if CTOR is empty.  If
+  it exists, the current ctor object is popped off the stack and assigned to
+  CURRENT.
+
+  NB: the ctor stack is popped for arrays because they are ctors which
+  contain only a single variable. For other ctor types, several variables may
+  be members and the parse rule (see `declaration' above) determines when to
+  pop the stack.
+
+  Returns: void 
+*/
+
+void	
+add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current, Part part)
+{ 
+    if (!*ctor)
+	*ctor = new stack<BaseType *>;
+
+    if (!(*ctor)->empty()) { /* must be parsing a ctor type */
+	(*ctor)->top()->add_var(*current, part);
+
+ 	const Type &ctor_type = (*ctor)->top()->type();
+
+	if (ctor_type == dods_array_c) {
+	    if( *current ) delete *current ;
+	    *current = (*ctor)->top();
+	    (*ctor)->pop();
+
+	    // Return here to avoid deleting the new value of 'current.'
+	    return;
+	}
+    }
+    else {
+	table.add_var(*current);
+    }
+
+    if (*current) 
+	delete *current; 
+    *current = 0;
+}
+
+
diff --git a/dds.tab.hh b/dds.tab.hh
new file mode 100644
index 0000000..cdda8f5
--- /dev/null
+++ b/dds.tab.hh
@@ -0,0 +1,97 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface 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.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_WORD = 258,
+     SCAN_DATASET = 259,
+     SCAN_LIST = 260,
+     SCAN_SEQUENCE = 261,
+     SCAN_STRUCTURE = 262,
+     SCAN_FUNCTION = 263,
+     SCAN_GRID = 264,
+     SCAN_BYTE = 265,
+     SCAN_INT16 = 266,
+     SCAN_UINT16 = 267,
+     SCAN_INT32 = 268,
+     SCAN_UINT32 = 269,
+     SCAN_FLOAT32 = 270,
+     SCAN_FLOAT64 = 271,
+     SCAN_STRING = 272,
+     SCAN_URL = 273
+   };
+#endif
+/* Tokens.  */
+#define SCAN_WORD 258
+#define SCAN_DATASET 259
+#define SCAN_LIST 260
+#define SCAN_SEQUENCE 261
+#define SCAN_STRUCTURE 262
+#define SCAN_FUNCTION 263
+#define SCAN_GRID 264
+#define SCAN_BYTE 265
+#define SCAN_INT16 266
+#define SCAN_UINT16 267
+#define SCAN_INT32 268
+#define SCAN_UINT32 269
+#define SCAN_FLOAT32 270
+#define SCAN_FLOAT64 271
+#define SCAN_STRING 272
+#define SCAN_URL 273
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 121 "dds.y"
+{
+    bool boolean;
+    char word[ID_MAX];
+}
+/* Line 1489 of yacc.c.  */
+#line 90 "dds.tab.hh"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE ddslval;
+
diff --git a/dds.y b/dds.y
new file mode 100644
index 0000000..a228541
--- /dev/null
+++ b/dds.y
@@ -0,0 +1,509 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+/*
+   Grammar for the DDS. This grammar can be used with the bison parser
+   generator to build a parser for the DDS. It assumes that a scanner called
+   `ddslex()' exists and returns several token types (see das.tab.h)
+   in addition to several single character token types. The matched lexeme
+   for an ID is stored by the scanner in a global char * `ddslval'.
+   Because the scanner returns a value via this global and because the parser
+   stores ddslval (not the information pointed to), the values of rule
+   components must be stored as they are parsed and used once accumulated at
+   or near the end of a rule. If ddslval returned a value (instead of a
+   pointer to a value) this would not be necessary.
+
+   jhrg 8/29/94 
+*/
+
+%{
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: dds.y 21577 2009-10-02 16:12:17Z jimg $"};
+
+#include <cstring>
+#include <cassert>
+#include <iostream>
+#include <stack>
+#include <sstream>
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+#include "Error.h"
+#include "parser.h"
+#include "util.h"
+
+using namespace std;
+using namespace libdap;
+
+// These macros are used to access the `arguments' passed to the parser. A
+// pointer to an error object and a pointer to an integer status variable are
+// passed in to the parser within a structure (which itself is passed as a
+// pointer). Note that the ERROR macro explicitly casts OBJ to an ERROR *. 
+// ERROR is no longer used. These parsers now signal problems by throwing
+// exceptions. 5/22/2002 jhrg
+#define DDS_OBJ(arg) ((DDS *)((parser_arg *)(arg))->_object)
+
+#define YYPARSE_PARAM arg
+
+extern int dds_line_num;	/* defined in dds.lex */
+
+// No global static objects in the dap library! 1/24/2000 jhrg
+static stack<BaseType *> *ctor;
+static BaseType *current;
+static string *id;
+static Part part = nil;		/* Part is defined in BaseType */
+
+static const char *NO_DDS_MSG =
+"The descriptor object returned from the dataset was null.\n\
+Check that the URL is correct.";
+
+static const char *BAD_DECLARATION =
+"In the dataset descriptor object: Expected a variable declaration\n\
+(e.g., Int32 i;). Make sure that the variable name is not the name\n\
+of a datatype and that the Array: and Maps: sections of a Grid are\n\
+labeled properly.";
+ 
+int ddslex();
+void ddserror(char *s);
+void error_exit_cleanup();
+void add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current, 
+	       Part p);
+void invalid_declaration(parser_arg *arg, string semantic_err_msg, 
+			 char *type, char *name);
+
+%}
+
+%expect 52
+
+%union {
+    bool boolean;
+    char word[ID_MAX];
+}
+
+%token <word> SCAN_WORD
+%token <word> SCAN_DATASET
+%token <word> SCAN_LIST
+%token <word> SCAN_SEQUENCE
+%token <word> SCAN_STRUCTURE
+%token <word> SCAN_FUNCTION
+%token <word> SCAN_GRID
+%token <word> SCAN_BYTE
+%token <word> SCAN_INT16
+%token <word> SCAN_UINT16
+%token <word> SCAN_INT32
+%token <word> SCAN_UINT32
+%token <word> SCAN_FLOAT32
+%token <word> SCAN_FLOAT64
+%token <word> SCAN_STRING
+%token <word> SCAN_URL 
+
+%type <boolean> datasets dataset declarations array_decl
+
+%type <word> declaration base_type structure sequence grid var var_name name
+
+%%
+
+start:
+                {
+		    /* On entry to the parser, make the BaseType stack. */
+		    ctor = new stack<BaseType *>;
+                }
+                datasets
+                {
+		    delete ctor; ctor = 0;
+		}
+;
+
+datasets:	dataset
+		| datasets dataset
+;
+
+dataset:	SCAN_DATASET '{' declarations '}' name ';'
+                {
+		    $$ = $3 && $5;
+		}
+                | error
+                {
+		    parse_error((parser_arg *)arg, NO_DDS_MSG,
+ 				dds_line_num, $<word>1);
+		    error_exit_cleanup();
+		    YYABORT;
+		}
+;
+
+declarations:	/* empty */
+                {
+		    $$ = true;
+		}
+
+                | declaration { $$ = true; }
+                | declarations declaration { $$ = true; }
+;
+
+/* This non-terminal is here only to keep types like `List List Int32' from
+   parsing. DODS does not allow Lists of Lists. Those types make translation
+   to/from arrays too hard. */
+
+declaration:  base_type var ';' 
+                { 
+		    string smsg;
+		    if (current->check_semantics(smsg)) {
+			/* BaseType *current_save = current ; */
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+			/* FIX
+			if( current_save == current )
+			{
+			    delete current ;
+			    current = 0 ;
+			}
+			*/
+		    } else {
+		      invalid_declaration((parser_arg *)arg, smsg, $1, $2);
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy($$,$2,ID_MAX);
+                    $$[ID_MAX-1] = '\0';
+		}
+
+		| structure  '{' declarations '}' 
+		{ 
+		    if( current ) delete current ;
+		    current = ctor->top(); 
+		    ctor->pop();
+		} 
+                var ';' 
+                { 
+		    string smsg;
+		    if (current->check_semantics(smsg))
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+		    else {
+		      invalid_declaration((parser_arg *)arg, smsg, $1, $6);
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy($$,$6,ID_MAX);
+                    $$[ID_MAX-1] = '\0';
+		}
+
+		| sequence '{' declarations '}' 
+                { 
+		    if( current ) delete current ;
+		    current = ctor->top(); 
+		    ctor->pop();
+		} 
+                var ';' 
+                { 
+		    string smsg;
+		    if (current->check_semantics(smsg))
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+		    else {
+		      invalid_declaration((parser_arg *)arg, smsg, $1, $6);
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy($$,$6,ID_MAX);
+                    $$[ID_MAX-1] = '\0';
+		}
+
+		| grid '{' SCAN_WORD ':'
+		{ 
+		    if (is_keyword(string($3), "array"))
+			part = array; 
+		    else {
+			ostringstream msg;
+			msg << BAD_DECLARATION;
+			parse_error((parser_arg *)arg, msg.str().c_str(),
+				    dds_line_num, $3);
+			YYABORT;
+		    }
+                }
+                declaration SCAN_WORD ':'
+		{ 
+		    if (is_keyword(string($7), "maps"))
+			part = maps; 
+		    else {
+			ostringstream msg;
+			msg << BAD_DECLARATION;
+			parse_error((parser_arg *)arg, msg.str().c_str(),
+				    dds_line_num, $7);
+			YYABORT;
+		    }
+                }
+                declarations '}' 
+		{
+		    if( current ) delete current ;
+		    current = ctor->top(); 
+		    ctor->pop();
+		}
+                var ';' 
+                {
+		    string smsg;
+		    if (current->check_semantics(smsg)) {
+			part = nil; 
+			add_entry(*DDS_OBJ(arg), &ctor, &current, part); 
+		    }
+		    else {
+		      invalid_declaration((parser_arg *)arg, smsg, $1, $13);
+		      error_exit_cleanup();
+		      YYABORT;
+		    }
+                    strncpy($$,$13,ID_MAX);
+                    $$[ID_MAX-1] = '\0';
+		}
+
+                | error 
+                {
+		    ostringstream msg;
+		    msg << BAD_DECLARATION;
+		    parse_error((parser_arg *)arg, msg.str().c_str(),
+				dds_line_num, $<word>1);
+		    YYABORT;
+		}
+;
+ 
+
+structure:	SCAN_STRUCTURE
+		{ 
+		    ctor->push(DDS_OBJ(arg)->get_factory()->NewStructure()); 
+		}
+;
+
+sequence:	SCAN_SEQUENCE 
+		{ 
+		    ctor->push(DDS_OBJ(arg)->get_factory()->NewSequence()); 
+		}
+;
+
+grid:		SCAN_GRID 
+		{ 
+		    ctor->push(DDS_OBJ(arg)->get_factory()->NewGrid()); 
+		}
+;
+
+base_type:	SCAN_BYTE { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewByte(); }
+		| SCAN_INT16 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt16(); }
+		| SCAN_UINT16 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt16(); }
+		| SCAN_INT32 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewInt32(); }
+		| SCAN_UINT32 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUInt32(); }
+		| SCAN_FLOAT32 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat32(); }
+		| SCAN_FLOAT64 { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewFloat64(); }
+		| SCAN_STRING { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewStr(); }
+		| SCAN_URL { if( current ) delete current ;current = DDS_OBJ(arg)->get_factory()->NewUrl(); }
+;
+
+var:		var_name { current->set_name($1); }
+ 		| var array_decl
+;
+
+var_name:       SCAN_WORD | SCAN_BYTE | SCAN_INT16 | SCAN_INT32 | SCAN_UINT16
+                | SCAN_UINT32 | SCAN_FLOAT32 | SCAN_FLOAT64 | SCAN_STRING
+                | SCAN_URL | SCAN_STRUCTURE | SCAN_SEQUENCE | SCAN_GRID
+                | SCAN_LIST
+;
+
+array_decl:	'[' SCAN_WORD ']'
+                 { 
+		     if (!check_int32($2)) {
+			 string msg = "In the dataset descriptor object:\n";
+			 msg += "Expected an array subscript.\n";
+			 parse_error((parser_arg *)arg, msg.c_str(), 
+				 dds_line_num, $2);
+		     }
+		     if (current->type() == dods_array_c
+			 && check_int32($2)) {
+			 ((Array *)current)->append_dim(atoi($2));
+		     }
+		     else {
+			 Array *a = DDS_OBJ(arg)->get_factory()->NewArray(); 
+			 a->add_var(current); 
+			 a->append_dim(atoi($2));
+			 if( current ) delete current ;
+			 current = a;
+		     }
+
+		     $$ = true;
+		 }
+
+		 | '[' SCAN_WORD 
+		 {
+		     id = new string($2);
+		 } 
+                 '=' SCAN_WORD 
+                 { 
+		     if (!check_int32($5)) {
+			 string msg = "In the dataset descriptor object:\n";
+			 msg += "Expected an array subscript.\n";
+			 parse_error((parser_arg *)arg, msg.c_str(), 
+				 dds_line_num, $5);
+			 error_exit_cleanup();
+			 YYABORT;
+		     }
+		     if (current->type() == dods_array_c) {
+			 ((Array *)current)->append_dim(atoi($5), *id);
+		     }
+		     else {
+			 Array *a = DDS_OBJ(arg)->get_factory()->NewArray(); 
+			 a->add_var(current); 
+			 a->append_dim(atoi($5), *id);
+			 if( current ) delete current ;
+			 current = a;
+		     }
+
+		     delete id; id = 0;
+		 }
+		 ']'
+                 {
+		     $$ = true;
+		 }
+
+		 | error
+                 {
+		     ostringstream msg;
+		     msg << "In the dataset descriptor object:" << endl
+			 << "Expected an array subscript." << endl;
+		     parse_error((parser_arg *)arg, msg.str().c_str(), 
+				 dds_line_num, $<word>1);
+		     YYABORT;
+		 }
+;
+
+name:		var_name { (*DDS_OBJ(arg)).set_dataset_name($1); }
+		| SCAN_DATASET { (*DDS_OBJ(arg)).set_dataset_name($1); }
+                | error 
+                {
+		  ostringstream msg;
+		  msg << "Error parsing the dataset name." << endl
+		      << "The name may be missing or may contain an illegal character." << endl;
+		     parse_error((parser_arg *)arg, msg.str().c_str(),
+				 dds_line_num, $<word>1);
+		     YYABORT;
+		}
+;
+
+%%
+
+/* 
+   This function must be defined. However, use the error reporting code in
+   parser-utils.cc.
+*/
+
+void 
+ddserror(char *)
+{
+}
+
+/*
+  Error clean up. Call this before calling YYBORT. Don't call this on a
+  normal exit.
+*/
+
+void
+error_exit_cleanup()
+{
+    delete id; id = 0;
+    delete current; current = 0;
+    delete ctor; ctor = 0;
+}
+
+/*
+  Invalid declaration message.
+*/
+
+void
+invalid_declaration(parser_arg *arg, string semantic_err_msg, char *type, 
+		    char *name)
+{
+  ostringstream msg;
+  msg << "In the dataset descriptor object: `" << type << " " << name 
+      << "'" << endl << "is not a valid declaration." << endl 
+      << semantic_err_msg;
+  parse_error((parser_arg *)arg, msg.str().c_str(), dds_line_num);
+}
+
+/*
+  Add the variable pointed to by CURRENT to either the topmost ctor object on
+  the stack CTOR or to the dataset variable table TABLE if CTOR is empty.  If
+  it exists, the current ctor object is popped off the stack and assigned to
+  CURRENT.
+
+  NB: the ctor stack is popped for arrays because they are ctors which
+  contain only a single variable. For other ctor types, several variables may
+  be members and the parse rule (see `declaration' above) determines when to
+  pop the stack.
+
+  Returns: void 
+*/
+
+void	
+add_entry(DDS &table, stack<BaseType *> **ctor, BaseType **current, Part part)
+{ 
+    if (!*ctor)
+	*ctor = new stack<BaseType *>;
+
+    if (!(*ctor)->empty()) { /* must be parsing a ctor type */
+	(*ctor)->top()->add_var(*current, part);
+
+ 	const Type &ctor_type = (*ctor)->top()->type();
+
+	if (ctor_type == dods_array_c) {
+	    if( *current ) delete *current ;
+	    *current = (*ctor)->top();
+	    (*ctor)->pop();
+
+	    // Return here to avoid deleting the new value of 'current.'
+	    return;
+	}
+    }
+    else {
+	table.add_var(*current);
+    }
+
+    if (*current) 
+	delete *current; 
+    *current = 0;
+}
+
diff --git a/debug.h b/debug.h
new file mode 100644
index 0000000..834cde2
--- /dev/null
+++ b/debug.h
@@ -0,0 +1,80 @@
+/*
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+*/
+
+/*
+  This header defines macros which enable compile-time program
+  instrumentation. These macros work for both C and C++. Enclose the entire
+  statement to be debugged within the DBG() macro *and* put the semicolon
+  after the macro. (e.g., DBG(cerr << "Bad program" << endl); ). Statements
+  should not span lines unless they include `\'s to escape the newlines.
+
+  jhrg 10/13/94
+*/
+
+#ifndef _debug_h
+#define _debug_h
+
+#ifdef __cplusplus
+
+#include <iostream>
+using std::cerr;
+using std::string;
+using std::endl;
+#define FILE_N_LINE cerr << __FILE__ << ": " << __LINE__ << ":"
+
+#else
+
+#define FILE_N_LINE fprintf(stderr, "%s:%d: ", __FILE__, __LINE__);
+
+#endif /* cplusplus */
+
+#ifdef DODS_DEBUG
+#define DBG(x) FILE_N_LINE; x
+#define DBGN(x) x
+#else
+#define DBG(x) /* x */
+#define DBGN(x) /* x */
+#endif
+
+/** The purpose of DODS_DEBUG1 is to look at only a handful of the DBG()
+    macros by changing them to DBG1() macros and defining DODS_DEBUG1. */
+#ifdef DODS_DEBUG1
+#define DBG1(x) FILE_N_LINE; x
+#else
+#define DBG1(x) /* x */
+#endif
+
+#ifdef DODS_DEBUG2
+#define DBG2(x) FILE_N_LINE; x
+#else
+#define DBG2(x) /* x */
+#endif
+
+#ifdef DODS_PERF
+#error "Deprecated macro!"
+#endif
+
+#endif /* _debug_h */
diff --git a/dods-datatypes-config.h.in b/dods-datatypes-config.h.in
new file mode 100644
index 0000000..ee92aac
--- /dev/null
+++ b/dods-datatypes-config.h.in
@@ -0,0 +1,49 @@
+
+/*
+  Determine at compile-time the sizes of various datatypes. This uses symbols
+  defined by configure (See configure.in).
+  jhrg 10/24/94
+
+  This header is included by all of the DODS DAP library header files which
+  make use of the dods_* typedefs. C or C++ files can either include
+  config_dap.h, use their own configure script which defines SIZEOF_LONG,
+  _INT, _CHAR and _DOUBLE or set these preprocessor symbols themselves in a
+  Makefile, etc.
+
+  This used to be part of the config_dap.h header, but including that in the
+  DAP library headers introduced problems when the DAP was used in conjunction
+  with other libraries. 8/1/2000 jhrg
+*/
+
+#ifndef __DODS_DATATYPES__
+#define __DODS_DATATYPES__
+
+/* The typedefs are done using a preprocessor symbol so that autoconf's
+   `CONFIG_HEADER' can be used. The configure script will then only modify
+   the dods-datatypes.h header when its contents change. This saves on
+   compilation since the header is used by many files in the dap++ library.
+   The downside is that the typedefs are so ugly... 2/14/2001 jhrg */
+
+#undef DINT32
+typedef DINT32 dods_int32;
+
+#undef DUINT32
+typedef DUINT32 dods_uint32;
+
+#undef DINT16
+typedef DINT16 dods_int16;
+
+#undef DUINT16
+typedef DUINT16 dods_uint16;
+
+#undef DBYTE
+typedef DBYTE dods_byte;
+
+#undef DFLOAT64
+typedef DFLOAT64 dods_float64;
+
+#undef DFLOAT32
+typedef DFLOAT32 dods_float32;		
+
+#endif /* __DODS_DATATYPES__ */
+
diff --git a/dods-datatypes-static.h b/dods-datatypes-static.h
new file mode 100644
index 0000000..9ceb0e0
--- /dev/null
+++ b/dods-datatypes-static.h
@@ -0,0 +1,49 @@
+/* dods-datatypes.h.  Generated from dods-datatypes.h.in by configure.  */
+
+/*
+  Determine at compile-time the sizes of various datatypes. This uses symbols
+  defined by configure (See configure.in).
+  jhrg 10/24/94
+
+  This header is included by all of the DODS DAP library header files which
+  make use of the dods_* typedefs. C or C++ files can either include
+  config_dap.h, use their own configure script which defines SIZEOF_LONG,
+  _INT, _CHAR and _DOUBLE or set these preprocessor symbols themselves in a
+  Makefile, etc.
+
+  This used to be part of the config_dap.h header, but including that in the
+  DAP library headers introduced problems when the DAP was used in conjunction
+  with other libraries. 8/1/2000 jhrg
+*/
+
+#ifndef __DODS_DATATYPES__
+#define __DODS_DATATYPES__
+
+#include <inttypes.h>
+
+namespace libdap
+{
+
+/* The typedefs are done using a preprocessor symbol so that autoconf's
+   `CONFIG_HEADER' can be used. The configure script will then only modify
+   the dods-datatypes.h header when its contents change. This saves on
+   compilation since the header is used by many files in the dap++ library.
+   The downside is that the typedefs are so ugly... 2/14/2001 jhrg */
+
+typedef int32_t dods_int32;
+
+typedef uint32_t dods_uint32;
+
+typedef int16_t dods_int16;
+
+typedef uint16_t dods_uint16;
+
+typedef uint8_t dods_byte;
+
+typedef double dods_float64;
+
+typedef float dods_float32;		
+
+} // namespace libdap
+
+#endif /* __DODS_DATATYPES__ */
diff --git a/dods-datatypes.h b/dods-datatypes.h
new file mode 100644
index 0000000..9ceb0e0
--- /dev/null
+++ b/dods-datatypes.h
@@ -0,0 +1,49 @@
+/* dods-datatypes.h.  Generated from dods-datatypes.h.in by configure.  */
+
+/*
+  Determine at compile-time the sizes of various datatypes. This uses symbols
+  defined by configure (See configure.in).
+  jhrg 10/24/94
+
+  This header is included by all of the DODS DAP library header files which
+  make use of the dods_* typedefs. C or C++ files can either include
+  config_dap.h, use their own configure script which defines SIZEOF_LONG,
+  _INT, _CHAR and _DOUBLE or set these preprocessor symbols themselves in a
+  Makefile, etc.
+
+  This used to be part of the config_dap.h header, but including that in the
+  DAP library headers introduced problems when the DAP was used in conjunction
+  with other libraries. 8/1/2000 jhrg
+*/
+
+#ifndef __DODS_DATATYPES__
+#define __DODS_DATATYPES__
+
+#include <inttypes.h>
+
+namespace libdap
+{
+
+/* The typedefs are done using a preprocessor symbol so that autoconf's
+   `CONFIG_HEADER' can be used. The configure script will then only modify
+   the dods-datatypes.h header when its contents change. This saves on
+   compilation since the header is used by many files in the dap++ library.
+   The downside is that the typedefs are so ugly... 2/14/2001 jhrg */
+
+typedef int32_t dods_int32;
+
+typedef uint32_t dods_uint32;
+
+typedef int16_t dods_int16;
+
+typedef uint16_t dods_uint16;
+
+typedef uint8_t dods_byte;
+
+typedef double dods_float64;
+
+typedef float dods_float32;		
+
+} // namespace libdap
+
+#endif /* __DODS_DATATYPES__ */
diff --git a/dods-limits.h b/dods-limits.h
new file mode 100644
index 0000000..a112c5b
--- /dev/null
+++ b/dods-limits.h
@@ -0,0 +1,68 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1996,1998,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Limits for DAP2. Use these *instead* of <limits.h> since DAP2 needs to see
+// the same values on all machines.
+
+#ifndef _dods_limits_h
+#define _dods_limits_h
+
+#define DODS_CHAR_BIT 8
+#define DODS_SCHAR_MIN -128
+#define DODS_SCHAR_MAX 127
+#define DODS_UCHAR_MAX 255U
+#define DODS_UCHAR_MIN 0
+
+#define DODS_SHRT_MIN -32768
+#define DODS_SHRT_MAX 32767
+#define DODS_USHRT_MAX 65535U
+
+#define DODS_INT_MIN (-2147483647 - 1)
+#define DODS_INT_MAX 2147483647
+#define DODS_UINT_MAX 4294967295U
+
+#define DODS_LONG_MIN (-2147483647 - 1)
+#define DODS_LONG_MAX 2147483647
+#define DODS_ULONG_MAX 4294967295UL
+
+#define DODS_DBL_DIG 15 /* digits of precision of a "double" */
+#define DODS_DBL_MAX 1.7976931348623157E+308 /* max decimal value of a */
+/* "double" */
+#define DODS_DBL_MIN 2.2250738585072014E-308 /* min decimal value of a */
+/* "double" */
+#define DODS_FLT_DIG 6  /* digits of precision of a "float" */
+#define DODS_FLT_MAX 3.402823466E+38F  /* max decimal value of a "float" */
+#define DODS_FLT_MIN 1.175494351E-38F  /* min decimal value of a "float" */
+
+/* This constant should not be used. */
+#define DODS_MB_LEN_MAX 4
+
+#endif // _dods_limits_h
diff --git a/doxy.conf b/doxy.conf
new file mode 100644
index 0000000..389f221
--- /dev/null
+++ b/doxy.conf
@@ -0,0 +1,1363 @@
+# Doxyfile 1.5.5
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file 
+# that follow. The default is UTF-8 which is also the encoding used for all 
+# text before the first occurrence of this tag. Doxygen uses libiconv (or the 
+# iconv built into libc) for the transcoding. See 
+# http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = libdap++
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = "Updated for version 3.8.2"
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = docs
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, 
+# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), 
+# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, 
+# Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, 
+# and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = NO
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like regular Qt-style comments 
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will 
+# interpret the first line (until the first dot) of a Qt-style 
+# comment as the brief description. If set to NO, the comments 
+# will behave just like regular Qt-style comments (thus requiring 
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Java. For instance, namespaces will be presented as packages, qualified 
+# scopes will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran 
+# sources only. Doxygen will then generate output that is more tailored for 
+# Fortran.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL 
+# sources. Doxygen will then generate output that is tailored for 
+# VHDL.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want 
+# to include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. 
+# Doxygen will parse them like normal C++ but will assume all classes use public 
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT            = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum 
+# is documented as struct, union, or enum with the name of the typedef. So 
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct 
+# with name TypeT. When disabled the typedef will appear as a member of a file, 
+# namespace, or class. And the struct will be named TypeS. This can typically 
+# be useful for C code in case the coding convention dictates that all compound 
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = NO
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be 
+# extracted and appear in the documentation as a namespace called 
+# 'anonymous_namespace{file}', where file will be replaced with the base 
+# name of the file that contains the anonymous namespace. By default 
+# anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = YES
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the 
+# hierarchy of group names into alphabetical order. If set to NO (the default) 
+# the group names will appear in their defined order.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from 
+# the version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = .
+
+# This tag can be used to specify the character encoding of the source files 
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is 
+# also the default input encoding. Doxygen uses libiconv (or the iconv built 
+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for 
+# the list of possible encodings.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.cc \
+                         *.h \
+                         *.doxygen
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = expr.h
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = *.tab.cc \
+                         *.tab.h \
+                         lex.* \
+                         Test*.cc \
+                         Test*.h \
+                         *Test.cc
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names 
+# (namespaces, classes, functions, etc.) that should be excluded from the 
+# output. The symbol name can be a fully qualified name, a word, or if the 
+# wildcard * is used, a substring. Examples: ANamespace, AClass, 
+# AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files 
+# will be generated that can be used as input for Apple's Xcode 3 
+# integrated development environment, introduced with OSX 10.5 (Leopard). 
+# To create a documentation set, doxygen will generate a Makefile in the 
+# HTML output directory. Running make will produce the docset in that 
+# directory and running "make install" will install the docset in 
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find 
+# it at startup.
+
+GENERATE_DOCSET        = NO
+
+# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the 
+# feed. A documentation feed provides an umbrella under which multiple 
+# documentation sets from a single provider (such as a company or product suite) 
+# can be grouped.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that 
+# should uniquely identify the documentation set bundle. This should be a 
+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen 
+# will append .docset to the name.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML 
+# documentation will contain sections that can be hidden and shown after the 
+# page has loaded. For this to work a browser that supports 
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox 
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = YES
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = YES
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3n
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc 
+# command. Doxygen will then run the mscgen tool (see 
+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the 
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where 
+# the mscgen tool resides. If left empty the tool is assumed to be found in the 
+# default search path.
+
+MSCGEN_PATH            = 
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = NO
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = YES
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT options are set to YES then 
+# doxygen will generate a call dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable call graphs 
+# for selected functions only using the \callgraph command.
+
+CALL_GRAPH             = YES
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then 
+# doxygen will generate a caller dependency graph for every global function 
+# or class method. Note that enabling this option will significantly increase 
+# the time of a run. So in most cases it will be better to enable caller 
+# graphs for selected functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of 
+# nodes that will be shown in the graph. If the number of nodes in a graph 
+# becomes larger than this value, doxygen will truncate the graph, which is 
+# visualized by representing a node as a red box. Note that doxygen if the 
+# number of direct children of the root node in a graph is already larger than 
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note 
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that the size of a graph can be further restricted by 
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is enabled by default, which results in a transparent 
+# background. Warning: Depending on the platform used, enabling this option 
+# may lead to badly anti-aliased labels on the edges of a graph (i.e. they 
+# become hard to read).
+
+DOT_TRANSPARENT        = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/doxy_private.conf b/doxy_private.conf
new file mode 100644
index 0000000..a7e4dfa
--- /dev/null
+++ b/doxy_private.conf
@@ -0,0 +1,950 @@
+# Doxyfile 1.2.14
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+# This file is incorporated into the DODS project, to generate the
+# DODS DAP reference manual.
+# $Id: doxy_private.conf 11906 2005-08-08 19:51:43Z root $
+
+# $Log: doxy_private.conf,v $
+# Revision 1.3  2003/12/08 18:02:30  edavis
+# Merge release-3-4 into trunk
+#
+# Revision 1.2.4.1  2003/09/06 22:41:59  jimg
+# Only document CC and H files.
+#
+# Revision 1.2  2003/01/10 19:46:41  jimg
+# Merged with code tagged release-3-2-10 on the release-3-2 branch. In many
+# cases files were added on that branch (so they appear on the trunk for
+# the first time).
+#
+# Revision 1.1.2.1  2002/10/18 23:23:35  jimg
+# Added.
+#
+# Revision 1.2  2002/06/27 16:27:26  tom
+# doxygen can't understand "~" as part of a directory path name.
+#
+# Revision 1.1  2002/06/18 15:36:24  tom
+# Moved comments and edited to accommodate doxygen documentation-generator.
+#
+
+#---------------------------------------------------------------------------
+# General configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = OPeNDAP
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = docs
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French, 
+# German, Greek, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, 
+# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
+
+OUTPUT_LANGUAGE        = English
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these class will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = YES
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited  members of a class in the documentation of that class as if
+# those members were  ordinary class members. Constructors, destructors and
+# assignment operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. It is allowed to use relative paths in the argument list.
+
+STRIP_FROM_PATH        = 
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = YES
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower case letters. If set to YES upper case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# users are adviced to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments  will behave just like the Qt-style comments (thus requiring an 
+# explict @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# reimplements.
+
+INHERIT_DOCS           = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 4
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consist of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources 
+# only. Doxygen will then generate output that is more tailored for C. 
+# For instance some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = .
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp 
+# *.h++ *.idl *.odl
+
+FILE_PATTERNS          = *.cc *.h # *.lex *.y
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = src/dap/dods_gui.c
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories 
+# that are symbolic links (a Unix filesystem feature) are excluded from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories.
+
+EXCLUDE_PATTERNS       = *.tab.c \
+                         Test* \
+			 *Test.cc \
+                         lex.*
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.
+
+INPUT_FILTER           = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse.
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources.
+
+SOURCE_BROWSER         = YES
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = YES
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the Html help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, 
+# or Internet explorer 4.0+). Note that for large projects the tree generation 
+# can take a very long time. In such cases it is better to disable this feature. 
+# Windows users are probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = letter
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimised for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assigments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = YES
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3n
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_XML           = NO
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_PREDEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line and do not end with a semicolon. Such function macros are typically 
+# used for boiler-plate code, and will confuse the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tagfiles.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or 
+# super classes. Setting the tag to NO turns the diagrams off. Note that this 
+# option is superceded by the HAVE_DOT option below. This is only a fallback. It is 
+# recommended to install and use dot, since it yield more powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are gif, jpg, and png
+# If left blank gif will be used.
+
+DOT_IMAGE_FORMAT       = gif
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found on the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermedate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::addtions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
+
+# The CGI_NAME tag should be the name of the CGI script that 
+# starts the search engine (doxysearch) with the correct parameters. 
+# A script with this name will be generated by doxygen.
+
+CGI_NAME               = search.cgi
+
+# The CGI_URL tag should be the absolute URL to the directory where the 
+# cgi binaries are located. See the documentation of your http daemon for 
+# details.
+
+CGI_URL                = 
+
+# The DOC_URL tag should be the absolute URL to the directory where the 
+# documentation is located. If left blank the absolute path to the 
+# documentation, with file:// prepended to it, will be used.
+
+DOC_URL                = 
+
+# The DOC_ABSPATH tag should be the absolute path to the directory where the 
+# documentation is located. If left blank the directory on the local machine 
+# will be used.
+
+DOC_ABSPATH            = 
+
+# The BIN_ABSPATH tag must point to the directory where the doxysearch binary 
+# is installed.
+
+BIN_ABSPATH            = /usr/local/bin/
+
+# The EXT_DOC_PATHS tag can be used to specify one or more paths to 
+# documentation generated for other projects. This allows doxysearch to search 
+# the documentation for these projects as well.
+
+EXT_DOC_PATHS          = 
diff --git a/escaping.cc b/escaping.cc
new file mode 100644
index 0000000..212e9d7
--- /dev/null
+++ b/escaping.cc
@@ -0,0 +1,497 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Copyright (c) 1996, California Institute of Technology.
+// ALL RIGHTS RESERVED.   U.S. Government Sponsorship acknowledged.
+//
+// Please read the full copyright notice in the file COPYRIGHT_URI
+// in this directory.
+//
+// Author: Todd Karakashian, NASA/Jet Propulsion Laboratory
+//         Todd.K.Karakashian at jpl.nasa.gov
+//
+// $RCSfile: escaping.cc,v $ - Miscellaneous routines for OPeNDAP HDF server
+//
+// These two routines are for escaping/unescaping strings that are identifiers
+// in DAP2
+// id2www() -- escape (using WWW hex codes) non-allowable characters in a
+// DAP2 identifier
+// www2id() -- given an WWW hexcode escaped identifier, restore it
+//
+// These two routines are for escaping/unescaping strings storing attribute
+// values.  They use traditional octal escapes (\nnn) because they are
+// intended to be viewed by a user
+// escattr() -- escape (using traditional octal backslash) non-allowable
+// characters in the value of a DAP2 attribute
+// unescattr() -- given an octally escaped string, restore it
+//
+// These are routines used by the above, not intended to be called directly:
+//
+// hexstring()
+// unhexstring()
+// octstring()
+// unoctstring()
+//
+// -Todd
+
+#include <ctype.h>
+
+#include <iomanip>
+#include <string>
+#include <sstream>
+
+#include "GNURegex.h"
+#include "Error.h"
+#include "InternalErr.h"
+//#define DODS_DEBUG
+#include "debug.h"
+
+using namespace std;
+
+namespace libdap {
+
+// The next four functions were originally defined static, but I removed that
+// to make testing them (see generalUtilTest.cc) easier to write. 5/7/2001
+// jhrg
+
+string
+hexstring(unsigned char val)
+{
+    ostringstream buf;
+    buf << hex << setw(2) << setfill('0') << static_cast<unsigned int>(val);
+
+    return buf.str();
+}
+
+string
+unhexstring(string s)
+{
+    int val;
+    istringstream ss(s);
+    ss >> hex >> val;
+    char tmp_str[2];
+    tmp_str[0] = static_cast<char>(val);
+    tmp_str[1] = '\0';
+    return string(tmp_str);
+}
+
+string
+octstring(unsigned char val)
+{
+    ostringstream buf;
+    buf << oct << setw(3) << setfill('0')
+    << static_cast<unsigned int>(val);
+
+    return buf.str();
+}
+
+string
+unoctstring(string s)
+{
+    int val;
+
+    istringstream ss(s);
+    ss >> oct >> val;
+
+    DBG(cerr << "unoctstring: " << val << endl);
+
+    char tmp_str[2];
+    tmp_str[0] = static_cast<char>(val);
+    tmp_str[1] = '\0';
+    return string(tmp_str);
+}
+
+/** Replace characters that are not allowed in DAP2 identifiers.
+
+    -In the DAP itself, id2www() is called in:
+     -# Array::print_decl() where dimension names are escaped
+     -# AttrTable::print() (which calls AttrTable::simple_print()) where
+        attribute names are escaped
+     -# BaseType::print_decl() where variable names are escaped.
+     -# Constructor::print_decl() where the name of the constructor type is
+        printed.
+     -# DDS::print() and DDS::print_constrained() where the name of the
+        dataset is printed.
+     -# Grid::print_decl() where the name of the grid is printed.
+
+    -In the client code:
+     -# id2www_ce() is called five times in the five methods that are used to
+        request responses where a CE is appended to a URL
+        (Connect::request_version, request_protocol, request_das, request_dds,
+        request_data).
+
+    @param in Replace characters in this string.
+    @param allowable The set of characters that are allowed in a URI.
+    default: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_/.\\*"
+    @see id2www_ce()
+    @return The modified identifier. */
+string
+id2www(string in, const string &allowable)
+{
+    string::size_type i = 0;
+    DBG(cerr<<"Input string: [" << in << "]" << endl);
+    while ((i = in.find_first_not_of(allowable, i)) != string::npos) {
+	DBG(cerr<<"Found escapee: [" << in[i] << "]");
+        in.replace(i, 1, "%" + hexstring(in[i]));
+        DBGN(cerr<<" now the string is: " << in << endl);
+        i += 3;//i++;
+    }
+
+    return in;
+}
+
+/** Replace characters that are not allowed in WWW URLs using rules specific
+    to Constraint Expressions. This has changed over time and now the only
+    difference is that '*' is escaped by this function while it is not
+    escaped by id2www().
+
+    @param in The string in which to replace characters.
+    @param allowable The set of characters that are allowed in a URI.
+    default: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_/.\\"
+    @see id2www()
+    @return The modified identifier. */
+string
+id2www_ce(string in, const string &allowable)
+{
+    return id2www(in, allowable);
+
+
+}
+
+/** Given a string that contains WWW escape sequences, translate those escape
+    sequences back into the ASCII characters they represent. Return the
+    modified string.
+
+    -Places in the dap code where www2id() is called:
+     -# Array::append_dim() the name is decoded before it is added
+     -# AttrTable::set_name(), AttrTable::append_attr(),
+        AttrTable::append_container(), AttrTable::del_attr(),
+        AttrTable::add_container_alias(), AttrTable::add_value_alias()
+        names are decoded before that are set/used.
+     -# BaseType::set_name() Names are decoded before they are set
+     -# When the constraint expression parser looks for a variable, the name is
+        first decoded.
+     -# DAS::DAS() Named attribute containers are decoded
+     -# DDS::var() When a DDS searches for a variable, the name is first decoded.
+     -# Grid::var(), Sequence::var(), Structure::var() Variable names are decoded.
+
+   -In the server code:
+     -# ResponseBuilder::initialize() The dataset name is decoded except that %20
+        is not removed.
+     -# ResponseBuilder::set_ce() The CE is decoded, except for spaces (%20).
+     -# ResponseBuilder::set_dataset_name() same logic as the first case.
+     -# The ResponseBuilder methods supersede methods with the same names
+        from DODSFilter, which is still in the code although deprecated.
+
+    @param in The string to modify.
+    @param escape The character used to signal the beginning of an escape
+    sequence. default: "%"
+    @param except If there are some escape codes that should not be removed by
+    this call (e.g., you might not want to remove spaces, %20) use this
+    parameter to specify those codes. The function will then transform all
+    escapes \e except those given. For example, to suppress translation of both
+    spaces and the ampersand, pass "%20%26" for 'except'. default: ""
+    @return The modified string. */
+string
+www2id(const string &in, const string &escape, const string &except)
+{
+    string::size_type i = 0;
+    string res = in;
+    while ((i = res.find_first_of(escape, i)) != string::npos) {
+        if (except.find(res.substr(i, 3)) != string::npos) {
+            i += 3;
+            continue;
+        }
+        res.replace(i, 3, unhexstring(res.substr(i + 1, 2)));
+        ++i;
+    }
+
+    return res;
+}
+
+static string
+entity(char c)
+{
+    switch (c) {
+    case '>': return ">";
+    case '<': return "<";
+    case '&': return "&";
+    case '\'': return "'";
+    case '\"': return """;
+    default:
+        throw InternalErr(__FILE__, __LINE__, "Unrecognized character.");
+    }
+}
+
+// Assumption: There are always exactly two octal digits in the input
+// and two hex digits in the result.
+string
+octal_to_hex(const string &octal_digits)
+{
+    int val;
+
+    istringstream ss(octal_digits);
+    ss >> oct >> val;
+
+    ostringstream ds;
+    ds << hex << setw(2) << setfill('0') << val;
+    return ds.str();
+}
+
+/** Replace characters that are not allowed in XML
+
+    @param in The string in which to replace characters.
+    @param not_allowed The set of characters that are not allowed in XML.
+    default: ><&'(single quote)"(double quote)
+    @return The modified identifier. */
+string
+id2xml(string in, const string &not_allowed)
+{
+    string::size_type i = 0;
+
+    while ((i = in.find_first_of(not_allowed, i)) != string::npos) {
+        in.replace(i, 1, entity(in[i]));
+        ++i;
+    }
+#if 0
+    // Removed the encoding of octal escapes. This function is used by
+    // AttrTable to encode the stuff that is the value of the <value>
+    // element in the DDX. The problem is that some of the values are not
+    // valid UTF-8 and that makes a XML parser gag.; ticket 1512.
+    // jhrg 3/19/10
+
+    // OK, now scan for octal escape sequences like \\012 (where the '\'
+    // is itself escaped). This type of attribute value comes from the netCDF
+    // handler and maybe others. Assumption: The '\' will always appear as
+    // in its escaped form: '\\'. NB: Both backslashes must be escaped in the
+    // C++ string.
+    string octal_escape = "\\\\";
+    i = 0;
+    string::size_type length = in.length();
+    while ((i = in.find(octal_escape, i)) != string::npos) {
+        // Get the three octal digits following the '\\0'
+        string::size_type j = i + 2;
+        if (j + 1 >= length)  // Check that we're not past the end
+            break;
+        string octal_digits = in.substr(j, 3);
+        // convert to a &#xdd; XML escape
+        string hex_escape = string("&#x");
+        hex_escape.append(octal_to_hex(octal_digits));
+        hex_escape.append(string(";"));
+
+        // replace the octal escape with an XML/hex escape
+        in.replace(i, 5, hex_escape);
+
+        // increment i
+        i += 6;
+    }
+#endif
+    return in;
+}
+
+/** Given a string that contains XML escape sequences (i.e., entities),
+    translate those back into ASCII characters. Return the modified string.
+
+    @param in The string to modify.
+    @return The modified string. */
+string
+xml2id(string in)
+{
+    string::size_type i = 0;
+
+    while ((i = in.find(">", i)) != string::npos)
+        in.replace(i, 4, ">");
+
+    i = 0;
+    while ((i = in.find("<", i)) != string::npos)
+        in.replace(i, 4, "<");
+
+    i = 0;
+    while ((i = in.find("&", i)) != string::npos)
+        in.replace(i, 5, "&");
+
+    i = 0;
+    while ((i = in.find("'", i)) != string::npos)
+        in.replace(i, 6, "'");
+
+    i = 0;
+    while ((i = in.find(""", i)) != string::npos)
+        in.replace(i, 6, "\"");
+
+    return in;
+}
+
+/** Return a string that has all the \c %<hex digit><hex digit>
+    sequences replaced with underscores (`_').
+
+    @param s The string to transform
+    @return The modified string. */
+string
+esc2underscore(string s)
+{
+    string::size_type pos;
+    while ((pos = s.find('%')) != string::npos)
+        s.replace(pos, 3, "_");
+
+    return s;
+}
+
+
+/** Escape non-printable characters and quotes from an HDF attribute.
+    @param s The attribute to modify.
+    @return The modified attribute. */
+string
+escattr(string s)
+{
+    const string printable = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~`!@#$%^&*()_-+={[}]|\\:;<,>.?/'\"";
+    const string ESC = "\\";
+    const string DOUBLE_ESC = ESC + ESC;
+    const string QUOTE = "\"";
+    const string ESCQUOTE = ESC + QUOTE;
+
+    // escape non-printing characters with octal escape
+    string::size_type ind = 0;
+    while ((ind = s.find_first_not_of(printable, ind)) != s.npos)
+        s.replace(ind, 1, ESC + octstring(s[ind]));
+
+    // escape \ with a second backslash
+    ind = 0;
+    while ((ind = s.find(ESC, ind)) != s.npos) {
+        s.replace(ind, 1, DOUBLE_ESC);
+        ind += DOUBLE_ESC.length();
+    }
+
+    // escape " with backslash
+    ind = 0;
+    while ((ind = s.find(QUOTE, ind)) != s.npos) {
+        s.replace(ind, 1, ESCQUOTE);
+        ind += ESCQUOTE.length();
+    }
+
+    return s;
+}
+
+/** Un-escape special characters, quotes and backslashes from an HDF
+    attribute.
+
+    Note: A regex to match one \ must be defined as: Regex foo = "\\\\";
+    because both C++ strings and GNU's Regex also employ \ as an escape
+    character!
+
+    @param s The escaped attribute. @return The unescaped attribute. */
+string
+unescattr(string s)
+{
+    Regex octal("\\\\[0-3][0-7][0-7]");  // matches 4 characters
+    Regex esc_quote("\\\\\"");  // matches 3 characters
+    Regex esc_esc("\\\\\\\\");      // matches 2 characters
+    const string ESC = "\\";
+    const string QUOTE = "\"";
+    int matchlen;
+    unsigned int index;
+
+    DBG(cerr << "0XX" << s << "XXX" << endl);
+    // unescape any escaped backslashes
+    index = esc_esc.search(s.c_str(), s.length(), matchlen, 0);
+    while (index < s.length()) {
+        DBG(cerr << "1aXX" << s << "XXX index: " << index << endl);
+        s.replace(index, 2, ESC);
+        DBG(cerr << "1bXX" << s << "XXX index: " << index << endl);
+        index = esc_esc.search(s.c_str(), s.length(), matchlen, 0);
+    }
+
+    // unescape any escaped double quote characters
+    index = esc_quote.search(s.c_str(), s.length(), matchlen, 0);
+    while (index < s.length()) {
+        s.replace(index, 2, QUOTE);
+        DBG(cerr << "2XX" << s << "XXX index: " << index << endl);
+        index = esc_quote.search(s.c_str(), s.length(), matchlen, 0);
+    }
+
+    // unescape octal characters
+    index = octal.search(s.c_str(), s.length(), matchlen, 0);
+    while (index < s.length()) {
+        s.replace(index, 4, unoctstring(s.substr(index + 1, 3)));
+        DBG(cerr << "3XX" << s << "XXX index: " << index << endl);
+        index = octal.search(s.c_str(), s.length(), matchlen, 0);
+    }
+
+    DBG(cerr << "4XX" << s << "XXX" << endl);
+    return s;
+}
+
+string
+munge_error_message(string msg)
+{
+    // First, add enclosing quotes if needed.
+    if (*msg.begin() != '"')
+        msg.insert(msg.begin(), '"');
+    if (*(msg.end() - 1) != '"')
+        msg += "\"";
+
+    // Now escape any internal double quotes that aren't escaped.
+    string::iterator miter;
+    for (miter = msg.begin() + 1; miter != msg.end() - 1; miter++)
+        if (*miter == '"' && *(miter - 1) != '\\')
+            miter = msg.insert(miter, '\\');
+
+    return msg;
+}
+
+/** Rip through a string and replace all the double quotes with \" sequences.
+    @param source
+    @return result
+ */
+string
+escape_double_quotes(string source)
+{
+    string::size_type idx = 0;
+    while((idx = source.find('\"', idx)) != string::npos) {
+        source.replace(idx, 1, "\\\""); // a backslash and a double quote
+        idx += 2;
+    }
+
+    return source;
+}
+
+/** Rip through a string and replace all the escaped double quotes with
+    regular double quotes.
+    @param source
+    @return result
+ */
+string
+unescape_double_quotes(string source)
+{
+    string::size_type idx = 0;
+    while((idx = source.find("\\\"", idx)) != string::npos) {
+        source.replace(idx, 2, "\""); // a backslash and a double quote
+        ++idx;
+    }
+
+    return source;
+}
+
+} // namespace libdap
+
diff --git a/escaping.h b/escaping.h
new file mode 100644
index 0000000..73cdcb0
--- /dev/null
+++ b/escaping.h
@@ -0,0 +1,87 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Declarations for identifier escaping and un-escaping functions.
+
+#ifndef _escaping_h
+#define _escaping_h
+
+#include <string>
+
+using std::string;
+
+namespace libdap
+{
+
+string hexstring(unsigned char val);
+string unhexstring(string s);
+string octstring(unsigned char val);
+string unoctstring(string s);
+
+// The original set of allowed characters was: [0-9a-zA-Z_%]
+// The characters accepted in DAP2 ids: [-+a-zA-Z0-9_/%.\\#*]; everything
+// else must be escaped.  Note that for some inscrutable reason, we've been
+// escaping '*'.
+
+// The characters allowable in an id in a URI (see RFC 2396):
+// [-A-Za-z0-9_.!~*'()].
+
+string id2www(string s, const string &allowable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_/.\\*");
+
+// This is what DAP2 allows in a ce: [-+a-zA-Z0-9_/%.\\#]
+string id2www_ce(string s, const string &allowable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+_/.\\");
+
+string www2id(const string &in, const string &escape = "%",
+              const string &except = "");
+
+// Include these for compatibility with the old names. 7/19/2001 jhrg
+#define id2dods id2www
+#define dods2id www2id
+
+string octal_to_hex(const string &octal_digits);
+
+string id2xml(string in, const string &not_allowed = "><&'\"");
+string xml2id(string in);
+
+string esc2underscore(string s);
+string char2ASCII(string s, const string escape = "%[0-7][0-9a-fA-F]");
+string escattr(string s);
+string unescattr(string s);
+
+string munge_error_message(string msg);
+
+string unescape_double_quotes(string source);
+string escape_double_quotes(string source);
+
+} // namespace libdap
+
+#endif // _escaping_h
+
diff --git a/expr.h b/expr.h
new file mode 100644
index 0000000..b0bbf1f
--- /dev/null
+++ b/expr.h
@@ -0,0 +1,96 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Types for the expr parser.
+//
+// 11/4/95 jhrg
+
+#ifndef _expr_h
+#define _expr_h
+
+#include <string>
+#include <vector>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+namespace libdap
+{
+
+// VALUE is used to return constant values from the scanner to the parser.
+// Constants are packaged in BaseType *s for evaluation by the parser.
+
+typedef struct
+{
+    Type type;   // Type is an enum defined in BaseType.h
+    union {
+        unsigned int ui;
+        int i;
+        double f;
+        string *s;
+    } v;
+} value;
+
+// Syntactic sugar for `pointer to function returning boolean' (bool_func)
+// and `pointer to function returning BaseType *' (btp_func). Both function
+// types take three arguments, an integer (argc), a vector of BaseType *s
+// (argv) and the DDS for the dataset for which these function is being
+// evaluated (analogous to the ENVP in UNIX). ARGC is the length of ARGV.
+
+// These two types of functions now take four args - the DDS was added.
+
+/** @todo A better design would wrap these in a class and record at minimum
+    their names so that error messages could be a bit more informative. jhrg
+ */
+typedef void(*bool_func)(int argc, BaseType *argv[], DDS &dds, bool *result);
+typedef void(*btp_func)(int argc, BaseType *argv[], DDS &dds, BaseType **btpp);
+
+// Projection function: A function that appears in the projection part of the
+// CE and is executed for its side-effect. Usually adds a new variable to
+// the DDS. These are run _during the parse_ so their side-effects can be used
+// by subsequent parts of the CE.
+
+typedef void(*proj_func)(int argc, BaseType *argv[], DDS &dds, ConstraintEvaluator &ce);
+
+// INT_LIST and INT_LIST_LIST are used by the parser to store the array
+// indexes.
+
+typedef std::vector<int> int_list;
+typedef std::vector<int>::const_iterator int_citer ;
+typedef std::vector<int>::iterator int_iter ;
+typedef std::vector<int_list *> int_list_list;
+typedef std::vector<int_list *>::const_iterator int_list_citer ;
+typedef std::vector<int_list *>::iterator int_list_iter ;
+
+} // namespace libdap
+
+#endif /* _expr_h */
diff --git a/getdap.cc b/getdap.cc
new file mode 100644
index 0000000..3bdf713
--- /dev/null
+++ b/getdap.cc
@@ -0,0 +1,523 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1997-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// This is the source to `getdap'; a simple tool to exercise the Connect
+// class. It can be used to get naked URLs as well as the DAP2 DAS and DDS
+// objects.  jhrg.
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    { "$Id: getdap.cc 21695 2009-11-04 17:45:04Z jimg $"
+    };
+
+#ifdef WIN32
+#include <io.h>
+#include <fcntl.h>
+#endif
+
+#include <cstring>
+#include <string>
+#include <sstream>
+
+#include "GetOpt.h"
+
+#include "Sequence.h"
+#include "Connect.h"
+#include "Response.h"
+#include "StdinResponse.h"
+
+using std::cerr;
+using std::endl;
+using std::flush;
+
+using namespace libdap ;
+
+const char *version = CVER " (" DVR " DAP/" DAP_PROTOCOL_VERSION ")";
+
+extern int libdap::dods_keep_temps;     // defined in HTTPResponse.h
+extern int libdap::www_trace;
+
+void usage(string name)
+{
+    cerr << "Usage: " << name << endl;
+    cerr <<
+    " [idDaxAVvks] [-B <db>][-c <expr>][-m <num>] <url> [<url> ...]" <<
+    endl;
+    cerr << " [VvksM] <file> [<file> ...]" << endl;
+    cerr << endl;
+    cerr << "In the first form of the command, dereference the URL and"
+    << endl;
+    cerr << "perform the requested operations. This includes routing" <<
+    endl;
+    cerr << "the returned information through the DAP processing" << endl;
+    cerr << "library (parsing the returned objects, et c.). If none" <<
+    endl;
+    cerr << "of a, d, or D are used with a URL, then the DAP library" <<
+    endl;
+    cerr << "routines are NOT used and the URLs contents are dumped" <<
+    endl;
+    cerr << "to standard output." << endl;
+    cerr << endl;
+    cerr << "In the second form of the command, assume the files are" <<
+    endl;
+    cerr << "DataDDS objects (stored in files or read from pipes)" << endl;
+    cerr << "and process them as if -D were given. In this case the" <<
+    endl;
+    cerr << "information *must* contain valid MIME header in order" <<
+    endl;
+    cerr << "to be processed." << endl;
+    cerr << endl;
+    cerr << "Options:" << endl;
+    cerr << "        i: For each URL, get the server version." << endl;
+    cerr << "        d: For each URL, get the the DDS." << endl;
+    cerr << "        a: For each URL, get the the DAS." << endl;
+    cerr << "        D: For each URL, get the the DataDDS." << endl;
+    cerr <<
+    "        x: For each URL, get the DDX object. Does not get data."
+    << endl;
+    cerr << "        X: Request a DataDDX from the server (the DAP4 data response" << endl;
+    cerr << "        B: Build a DDX in getdap using the DDS and DAS." << endl;
+    cerr << "        v: Verbose output." << endl;
+    cerr << "        V: Version of this client; see 'i' for server version." << endl;
+    cerr << "        c: <expr> is a constraint expression. Used with -D/X." <<
+    endl;
+    cerr << "           NB: You can use a `?' for the CE also." << endl;
+    cerr << "        k: Keep temporary files created by libdap." << endl;
+    cerr << "        m: Request the same URL <num> times." << endl;
+    cerr << "        z: Ask the server to compress data." << endl;
+    cerr << "        s: Print Sequences using numbered rows." << endl;
+    cerr << "        M: Assume data read from a file has no MIME headers" << endl;
+    cerr << "           (the default is to assume the headers are present)." << endl;
+    cerr << "        p: Set DAP protocol to x.y" << endl;
+}
+
+bool read_data(FILE * fp)
+{
+    if (!fp) {
+        fprintf(stderr, "getdap: Whoa!!! Null stream pointer.\n");
+        return false;
+    }
+    // Changed from a loop that used getc() to one that uses fread(). getc()
+    // worked fine for transfers of text information, but *not* for binary
+    // transfers. fread() will handle both.
+    char c;
+    while (fp && !feof(fp) && fread(&c, 1, 1, fp))
+        printf("%c", c);        // stick with stdio
+
+    return true;
+}
+
+static void print_data(DDS & dds, bool print_rows = false)
+{
+    cout << "The data:" << endl;
+
+    for (DDS::Vars_iter i = dds.var_begin(); i != dds.var_end(); i++) {
+        BaseType *v = *i;
+        if (print_rows && (*i)->type() == dods_sequence_c)
+            dynamic_cast < Sequence * >(*i)->print_val_by_rows(cout);
+        else
+            v->print_val(cout);
+    }
+
+    cout << endl << flush;
+}
+
+int main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, "idaDxXBVvkc:m:zshM?Hp:t");
+    int option_char;
+
+    bool get_das = false;
+    bool get_dds = false;
+    bool get_data = false;
+    bool get_ddx = false;
+    bool get_data_ddx = false;
+    bool build_ddx = false;
+    bool get_version = false;
+    bool cexpr = false;
+    bool verbose = false;
+    bool multi = false;
+    bool accept_deflate = false;
+    bool print_rows = false;
+    bool mime_headers = true;
+    int times = 1;
+    int dap_client_major = 2;
+    int dap_client_minor = 0;
+    string expr = "";
+
+#ifdef WIN32
+    _setmode(_fileno(stdout), _O_BINARY);
+#endif
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'd':
+            get_dds = true;
+            break;
+        case 'a':
+            get_das = true;
+            break;
+        case 'D':
+            get_data = true;
+            break;
+        case 'x':
+            get_ddx = true;
+            break;
+        case 'X':
+            get_data_ddx = true;
+            break;
+        case 'V':
+            fprintf(stderr, "getdap version: %s\n", version);
+            exit(0);
+        case 'i':
+            get_version = true;
+            break;
+        case 'v':
+            verbose = true;
+            break;
+        case 'k':
+            dods_keep_temps = 1;
+            break;              // keep_temp is in Connect.cc
+        case 'c':
+            cexpr = true;
+            expr = getopt.optarg;
+            break;
+        case 'm':
+            multi = true;
+            times = atoi(getopt.optarg);
+            break;
+        case 'B':
+            build_ddx = true;
+            break;
+        case 'z':
+            accept_deflate = true;
+            break;
+        case 's':
+            print_rows = true;
+            break;
+        case 'M':
+            mime_headers = false;
+            break;
+        case 'p': {
+            istringstream iss(getopt.optarg);
+            char dot;
+            iss >> dap_client_major;
+            iss >> dot;
+            iss >> dap_client_minor;
+            break;
+        }
+        case 't':
+            www_trace = 1;
+            break;
+        case 'h':
+        case '?':
+        default:
+            usage(argv[0]);
+            exit(1);
+            break;
+        }
+
+    try {
+        // If after processing all the command line options there is nothing
+        // left (no URL or file) assume that we should read from stdin.
+        for (int i = getopt.optind; i < argc; ++i) {
+            if (verbose)
+                fprintf(stderr, "Fetching: %s\n", argv[i]);
+
+            string name = argv[i];
+            Connect *url = 0;
+
+            url = new Connect(name);
+
+            // This overrides the value set in the .dodsrc file.
+            if (accept_deflate)
+                url->set_accept_deflate(accept_deflate);
+
+            if (dap_client_major > 2)
+                url->set_xdap_protocol(dap_client_major, dap_client_minor);
+
+            if (url->is_local()) {
+                if (verbose) {
+                    fprintf(stderr,
+                            "Assuming that the argument %s is a file that contains a DAP2 data object; decoding.\n", argv[i]);
+                }
+
+                Response *r = 0;
+                BaseTypeFactory factory;
+                DataDDS dds(&factory);
+
+                try {
+                    if (strcmp(argv[i], "-") == 0) {
+                        r = new StdinResponse(stdin);
+
+                        if (!r->get_stream())
+                            throw Error("Could not open standard input.");
+
+                        if (mime_headers)
+                            url->read_data(dds, r); // The default case
+                        else
+                            url->read_data_no_mime(dds, r);
+                    }
+                    else {
+                        r = new Response(fopen(argv[i], "r"), 0);
+
+                        if (!r->get_stream())
+                            throw Error(string("The input source: ")
+                                        + string(argv[i])
+                                        + string(" could not be opened"));
+
+                        url->read_data_no_mime(dds, r);
+                    }
+                }
+                catch (Error & e) {
+                    cerr << e.get_error_message() << endl;
+                    delete r;
+                    r = 0;
+                    delete url;
+                    url = 0;
+                    break;
+                }
+
+                if (verbose)
+                    fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                            url->get_protocol().c_str(),
+                            url->get_version().c_str());
+
+                print_data(dds, print_rows);
+
+            }
+
+            else if (get_version) {
+                fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                        url->request_protocol().c_str(),
+                        url->get_version().c_str());
+            }
+
+            else if (get_das) {
+                for (int j = 0; j < times; ++j) {
+                    DAS das;
+                    try {
+                        url->request_das(das);
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                                url->get_protocol().c_str(),
+                                url->get_version().c_str());
+
+                        fprintf(stderr, "DAS:\n");
+                    }
+
+                    das.print(stdout);
+                }
+            }
+
+            else if (get_dds) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DDS dds(&factory);
+                    try {
+                        url->request_dds(dds, expr);
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;       // Goto the next URL or exit the loop.
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                                url->get_protocol().c_str(),
+                                url->get_version().c_str());
+
+                        fprintf(stderr, "DDS:\n");
+                    }
+
+                    dds.print(cout);
+                }
+            }
+
+            else if (get_ddx) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DDS dds(&factory);
+                    try {
+                        url->request_ddx(dds, expr);
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        continue;       // Goto the next URL or exit the loop.
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                                url->get_protocol().c_str(),
+                                url->get_version().c_str());
+
+                        fprintf(stderr, "DDX:\n");
+                    }
+
+                    dds.print_xml(cout, false);
+                }
+            }
+
+            else if (build_ddx) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DDS dds(&factory);
+                    try {
+                        url->request_dds(dds, expr);
+                        DAS das;
+                        url->request_das(das);
+                        dds.transfer_attributes(&das);
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        continue;       // Goto the next URL or exit the loop.
+                    }
+
+                    if (verbose) {
+                        fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                                url->get_protocol().c_str(),
+                                url->get_version().c_str());
+
+                        fprintf(stderr, "Client-built DDX:\n");
+                    }
+
+                    dds.print_xml(cout, false);
+                }
+            }
+
+            else if (get_data) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DataDDS dds(&factory);
+                    try {
+                        DBG(cerr << "URL: " << url->URL(false) << endl);
+                        DBG(cerr << "CE: " << expr << endl);
+                        url->request_data(dds, expr);
+
+                        if (verbose)
+                            fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                                    url->get_protocol().c_str(),
+                                    url->get_version().c_str());
+
+                        print_data(dds, print_rows);
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;
+                    }
+                }
+            }
+
+            else if (get_data_ddx) {
+                for (int j = 0; j < times; ++j) {
+                    BaseTypeFactory factory;
+                    DataDDS dds(&factory);
+                    try {
+                        DBG(cerr << "URL: " << url->URL(false) << endl);
+                        DBG(cerr << "CE: " << expr << endl);
+                        url->request_data_ddx(dds, expr);
+
+                        if (verbose)
+                            fprintf(stderr, "DAP version: %s, Server version: %s\n",
+                                    url->get_protocol().c_str(),
+                                    url->get_version().c_str());
+
+                        print_data(dds, print_rows);
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        delete url;
+                        url = 0;
+                        continue;
+                    }
+                }
+            }
+
+            else {
+                // if (!get_das && !get_dds && !get_data) This code uses
+                // HTTPConnect::fetch_url which cannot be accessed using an
+                // instance of Connect. So some of the options supported by
+                // other URLs won't work here (e.g., the verbose option
+                // doesn't show the server version number).
+                HTTPConnect http(RCReader::instance());
+
+                // This overrides the value set in the .dodsrc file.
+                if (accept_deflate)
+                    http.set_accept_deflate(accept_deflate);
+
+                if (dap_client_major > 2)
+                    url->set_xdap_protocol(dap_client_major, dap_client_minor);
+
+                string url_string = argv[i];
+                for (int j = 0; j < times; ++j) {
+                    try {
+                        Response *r = http.fetch_url(url_string);
+                        if (!read_data(r->get_stream())) {
+                            continue;
+                        }
+                        delete r;
+                        r = 0;
+                    }
+                    catch (Error & e) {
+                        cerr << e.get_error_message() << endl;
+                        continue;
+                    }
+                }
+            }
+
+            delete url;
+            url = 0;
+        }
+    }
+    catch (Error &e) {
+        cerr << e.get_error_message() << endl;
+        return 1;
+    }
+    catch (exception &e) {
+        cerr << "C++ library exception: " << e.what() << endl;
+        return 1;
+    }
+
+    return 0;
+}
diff --git a/gl/Makefile.am b/gl/Makefile.am
new file mode 100644
index 0000000..bfb32e6
--- /dev/null
+++ b/gl/Makefile.am
@@ -0,0 +1,775 @@
+## DO NOT EDIT! GENERATED AUTOMATICALLY!
+## Process this file with automake to produce Makefile.in.
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License.  As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=gl/doc --tests-base=tests --aux-dir=conf --lgpl --libtool --macro-prefix=gl regex
+
+AUTOMAKE_OPTIONS = 1.5 gnits
+
+SUBDIRS =
+noinst_HEADERS =
+noinst_LIBRARIES =
+noinst_LTLIBRARIES =
+EXTRA_DIST =
+BUILT_SOURCES =
+SUFFIXES =
+MOSTLYCLEANFILES = core *.stackdump
+MOSTLYCLEANDIRS =
+CLEANFILES =
+DISTCLEANFILES =
+MAINTAINERCLEANFILES =
+EXTRA_DIST += m4/gnulib-cache.m4
+
+AM_CPPFLAGS =
+AM_CFLAGS =
+
+noinst_LTLIBRARIES += libgnu.la
+
+libgnu_la_SOURCES =
+libgnu_la_LIBADD = $(gl_LTLIBOBJS)
+libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS)
+EXTRA_libgnu_la_SOURCES =
+libgnu_la_LDFLAGS = $(AM_LDFLAGS)
+libgnu_la_LDFLAGS += -no-undefined
+libgnu_la_LDFLAGS += $(LTLIBINTL)
+
+## begin gnulib module alloca-opt
+
+BUILT_SOURCES += $(ALLOCA_H)
+
+# We need the following in order to create <alloca.h> when the system
+# doesn't have one that works with the given compiler.
+alloca.h: alloca.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  cat $(srcdir)/alloca.in.h; \
+	} > $@-t && \
+	mv -f $@-t $@
+MOSTLYCLEANFILES += alloca.h alloca.h-t
+
+EXTRA_DIST += alloca.in.h
+
+## end   gnulib module alloca-opt
+
+## begin gnulib module arg-nonnull
+
+# The BUILT_SOURCES created by this Makefile snippet are not used via #include
+# statements but through direct file reference. Therefore this snippet must be
+# present in all Makefile.am that need it. This is ensured by the applicability
+# 'all' defined above.
+
+BUILT_SOURCES += arg-nonnull.h
+# The arg-nonnull.h that gets inserted into generated .h files is the same as
+# build-aux/arg-nonnull.h, except that it has the copyright header cut off.
+arg-nonnull.h: $(top_srcdir)/conf/arg-nonnull.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	sed -n -e '/GL_ARG_NONNULL/,$$p' \
+	  < $(top_srcdir)/conf/arg-nonnull.h \
+	  > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += arg-nonnull.h arg-nonnull.h-t
+
+ARG_NONNULL_H=arg-nonnull.h
+
+EXTRA_DIST += $(top_srcdir)/conf/arg-nonnull.h
+
+## end   gnulib module arg-nonnull
+
+## begin gnulib module btowc
+
+
+EXTRA_DIST += btowc.c
+
+EXTRA_libgnu_la_SOURCES += btowc.c
+
+## end   gnulib module btowc
+
+## begin gnulib module c++defs
+
+# The BUILT_SOURCES created by this Makefile snippet are not used via #include
+# statements but through direct file reference. Therefore this snippet must be
+# present in all Makefile.am that need it. This is ensured by the applicability
+# 'all' defined above.
+
+BUILT_SOURCES += c++defs.h
+# The c++defs.h that gets inserted into generated .h files is the same as
+# build-aux/c++defs.h, except that it has the copyright header cut off.
+c++defs.h: $(top_srcdir)/conf/c++defs.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	sed -n -e '/_GL_CXXDEFS/,$$p' \
+	  < $(top_srcdir)/conf/c++defs.h \
+	  > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += c++defs.h c++defs.h-t
+
+CXXDEFS_H=c++defs.h
+
+EXTRA_DIST += $(top_srcdir)/conf/c++defs.h
+
+## end   gnulib module c++defs
+
+## begin gnulib module configmake
+
+# Listed in the same order as the GNU makefile conventions, and
+# provided by autoconf 2.59c+.
+# The Automake-defined pkg* macros are appended, in the order
+# listed in the Automake 1.10a+ documentation.
+configmake.h: Makefile
+	$(AM_V_GEN)rm -f $@-t && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  echo '#define PREFIX "$(prefix)"'; \
+	  echo '#define EXEC_PREFIX "$(exec_prefix)"'; \
+	  echo '#define BINDIR "$(bindir)"'; \
+	  echo '#define SBINDIR "$(sbindir)"'; \
+	  echo '#define LIBEXECDIR "$(libexecdir)"'; \
+	  echo '#define DATAROOTDIR "$(datarootdir)"'; \
+	  echo '#define DATADIR "$(datadir)"'; \
+	  echo '#define SYSCONFDIR "$(sysconfdir)"'; \
+	  echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \
+	  echo '#define LOCALSTATEDIR "$(localstatedir)"'; \
+	  echo '#define INCLUDEDIR "$(includedir)"'; \
+	  echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \
+	  echo '#define DOCDIR "$(docdir)"'; \
+	  echo '#define INFODIR "$(infodir)"'; \
+	  echo '#define HTMLDIR "$(htmldir)"'; \
+	  echo '#define DVIDIR "$(dvidir)"'; \
+	  echo '#define PDFDIR "$(pdfdir)"'; \
+	  echo '#define PSDIR "$(psdir)"'; \
+	  echo '#define LIBDIR "$(libdir)"'; \
+	  echo '#define LISPDIR "$(lispdir)"'; \
+	  echo '#define LOCALEDIR "$(localedir)"'; \
+	  echo '#define MANDIR "$(mandir)"'; \
+	  echo '#define MANEXT "$(manext)"'; \
+	  echo '#define PKGDATADIR "$(pkgdatadir)"'; \
+	  echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \
+	  echo '#define PKGLIBDIR "$(pkglibdir)"'; \
+	  echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \
+	} | sed '/""/d' > $@-t && \
+	if test -f $@ && cmp $@-t $@ > /dev/null; then \
+	  rm -f $@-t; \
+	else \
+	  rm -f $@; mv $@-t $@; \
+	fi
+
+BUILT_SOURCES += configmake.h
+CLEANFILES += configmake.h configmake.h-t
+
+## end   gnulib module configmake
+
+## begin gnulib module gettext-h
+
+libgnu_la_SOURCES += gettext.h
+
+## end   gnulib module gettext-h
+
+## begin gnulib module langinfo
+
+BUILT_SOURCES += langinfo.h
+
+# We need the following in order to create an empty placeholder for
+# <langinfo.h> when the system doesn't have one.
+langinfo.h: langinfo.in.h $(CXXDEFS_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \
+	      -e 's|@''GNULIB_NL_LANGINFO''@|$(GNULIB_NL_LANGINFO)|g' \
+	      -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \
+	      -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \
+	      -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \
+	      -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \
+	      -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \
+	      -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/langinfo.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += langinfo.h langinfo.h-t
+
+EXTRA_DIST += langinfo.in.h
+
+## end   gnulib module langinfo
+
+## begin gnulib module localcharset
+
+libgnu_la_SOURCES += localcharset.h localcharset.c
+
+# We need the following in order to install a simple file in $(libdir)
+# which is shared with other installed packages. We use a list of referencing
+# packages so that "make uninstall" will remove the file if and only if it
+# is not used by another installed package.
+# On systems with glibc-2.1 or newer, the file is redundant, therefore we
+# avoid installing it.
+
+all-local: charset.alias ref-add.sed ref-del.sed
+
+charset_alias = $(DESTDIR)$(libdir)/charset.alias
+charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
+install-exec-local: install-exec-localcharset
+install-exec-localcharset: all-local
+	if test $(GLIBC21) = no; then \
+	  case '$(host_os)' in \
+	    darwin[56]*) \
+	      need_charset_alias=true ;; \
+	    darwin* | cygwin* | mingw* | pw32* | cegcc*) \
+	      need_charset_alias=false ;; \
+	    *) \
+	      need_charset_alias=true ;; \
+	  esac ; \
+	else \
+	  need_charset_alias=false ; \
+	fi ; \
+	if $$need_charset_alias; then \
+	  $(mkinstalldirs) $(DESTDIR)$(libdir) ; \
+	fi ; \
+	if test -f $(charset_alias); then \
+	  sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \
+	  $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
+	  rm -f $(charset_tmp) ; \
+	else \
+	  if $$need_charset_alias; then \
+	    sed -f ref-add.sed charset.alias > $(charset_tmp) ; \
+	    $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
+	    rm -f $(charset_tmp) ; \
+	  fi ; \
+	fi
+
+uninstall-local: uninstall-localcharset
+uninstall-localcharset: all-local
+	if test -f $(charset_alias); then \
+	  sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \
+	  if grep '^# Packages using this file: $$' $(charset_tmp) \
+	      > /dev/null; then \
+	    rm -f $(charset_alias); \
+	  else \
+	    $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \
+	  fi; \
+	  rm -f $(charset_tmp); \
+	fi
+
+charset.alias: config.charset
+	$(AM_V_GEN)rm -f t-$@ $@ && \
+	$(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \
+	mv t-$@ $@
+
+SUFFIXES += .sed .sin
+.sin.sed:
+	$(AM_V_GEN)rm -f t-$@ $@ && \
+	sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \
+	mv t-$@ $@
+
+CLEANFILES += charset.alias ref-add.sed ref-del.sed
+
+EXTRA_DIST += config.charset ref-add.sin ref-del.sin
+
+## end   gnulib module localcharset
+
+## begin gnulib module malloc-gnu
+
+
+EXTRA_DIST += malloc.c
+
+EXTRA_libgnu_la_SOURCES += malloc.c
+
+## end   gnulib module malloc-gnu
+
+## begin gnulib module malloc-posix
+
+
+EXTRA_DIST += malloc.c
+
+EXTRA_libgnu_la_SOURCES += malloc.c
+
+## end   gnulib module malloc-posix
+
+## begin gnulib module mbrtowc
+
+
+EXTRA_DIST += mbrtowc.c
+
+EXTRA_libgnu_la_SOURCES += mbrtowc.c
+
+## end   gnulib module mbrtowc
+
+## begin gnulib module mbsinit
+
+
+EXTRA_DIST += mbsinit.c
+
+EXTRA_libgnu_la_SOURCES += mbsinit.c
+
+## end   gnulib module mbsinit
+
+## begin gnulib module nl_langinfo
+
+
+EXTRA_DIST += nl_langinfo.c
+
+EXTRA_libgnu_la_SOURCES += nl_langinfo.c
+
+## end   gnulib module nl_langinfo
+
+## begin gnulib module regex
+
+
+EXTRA_DIST += regcomp.c regex.c regex.h regex_internal.c regex_internal.h regexec.c
+
+EXTRA_libgnu_la_SOURCES += regcomp.c regex.c regex_internal.c regexec.c
+
+## end   gnulib module regex
+
+## begin gnulib module stdbool
+
+BUILT_SOURCES += $(STDBOOL_H)
+
+# We need the following in order to create <stdbool.h> when the system
+# doesn't have one that works.
+stdbool.h: stdbool.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += stdbool.h stdbool.h-t
+
+EXTRA_DIST += stdbool.in.h
+
+## end   gnulib module stdbool
+
+## begin gnulib module stddef
+
+BUILT_SOURCES += $(STDDEF_H)
+
+# We need the following in order to create <stddef.h> when the system
+# doesn't have one that works with the given compiler.
+stddef.h: stddef.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+	  sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \
+	      -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
+	      -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
+	      < $(srcdir)/stddef.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += stddef.h stddef.h-t
+
+EXTRA_DIST += stddef.in.h
+
+## end   gnulib module stddef
+
+## begin gnulib module stdint
+
+BUILT_SOURCES += $(STDINT_H)
+
+# We need the following in order to create <stdint.h> when the system
+# doesn't have one that works with the given compiler.
+stdint.h: stdint.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \
+	      -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
+	      -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
+	      -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \
+	      -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \
+	      -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \
+	      -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \
+	      -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \
+	      -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \
+	      -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \
+	      -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \
+	      -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \
+	      -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \
+	      -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \
+	      -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
+	      -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
+	      -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
+	      < $(srcdir)/stdint.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += stdint.h stdint.h-t
+
+EXTRA_DIST += stdint.in.h
+
+## end   gnulib module stdint
+
+## begin gnulib module stdlib
+
+BUILT_SOURCES += stdlib.h
+
+# We need the following in order to create <stdlib.h> when the system
+# doesn't have one that works with the given compiler.
+stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+	  sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
+	      -e 's|@''GNULIB__EXIT''@|$(GNULIB__EXIT)|g' \
+	      -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \
+	      -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \
+	      -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \
+	      -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \
+	      -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
+	      -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \
+	      -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
+	      -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
+	      -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \
+	      -e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \
+	      -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \
+	      -e 's|@''GNULIB_MKSTEMPS''@|$(GNULIB_MKSTEMPS)|g' \
+	      -e 's|@''GNULIB_PTSNAME''@|$(GNULIB_PTSNAME)|g' \
+	      -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \
+	      -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \
+	      -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \
+	      -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \
+	      -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \
+	      -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \
+	      -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \
+	      -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \
+	      -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \
+	      -e 's|@''GNULIB_SYSTEM_POSIX''@|$(GNULIB_SYSTEM_POSIX)|g' \
+	      -e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \
+	      -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
+	      -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
+	      -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
+	      -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \
+	      -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \
+	      -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
+	      -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \
+	      -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \
+	      -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \
+	      -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \
+	      -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \
+	      -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \
+	      -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
+	      -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
+	      -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
+	      -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
+	      -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
+	      -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \
+	      -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
+	      -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
+	      -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \
+	      -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \
+	      -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \
+	      -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \
+	      -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \
+	      -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \
+	      -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
+	      -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
+	      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+	      -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
+	      -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
+	      -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
+	      -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
+	      -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
+	      -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/stdlib.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += stdlib.h stdlib.h-t
+
+EXTRA_DIST += stdlib.in.h
+
+## end   gnulib module stdlib
+
+## begin gnulib module streq
+
+
+EXTRA_DIST += streq.h
+
+## end   gnulib module streq
+
+## begin gnulib module unistd
+
+BUILT_SOURCES += unistd.h
+
+# We need the following in order to create an empty placeholder for
+# <unistd.h> when the system doesn't have one.
+unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
+	      -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \
+	      -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|g' \
+	      -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \
+	      -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \
+	      -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \
+	      -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \
+	      -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \
+	      -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \
+	      -e 's|@''GNULIB_FCHOWNAT''@|$(GNULIB_FCHOWNAT)|g' \
+	      -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \
+	      -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
+	      -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \
+	      -e 's|@''GNULIB_GETDOMAINNAME''@|$(GNULIB_GETDOMAINNAME)|g' \
+	      -e 's|@''GNULIB_GETDTABLESIZE''@|$(GNULIB_GETDTABLESIZE)|g' \
+	      -e 's|@''GNULIB_GETGROUPS''@|$(GNULIB_GETGROUPS)|g' \
+	      -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \
+	      -e 's|@''GNULIB_GETLOGIN''@|$(GNULIB_GETLOGIN)|g' \
+	      -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \
+	      -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \
+	      -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \
+	      -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \
+	      -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \
+	      -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \
+	      -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \
+	      -e 's|@''GNULIB_PIPE''@|$(GNULIB_PIPE)|g' \
+	      -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \
+	      -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \
+	      -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \
+	      -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \
+	      -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \
+	      -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \
+	      -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \
+	      -e 's|@''GNULIB_SYMLINK''@|$(GNULIB_SYMLINK)|g' \
+	      -e 's|@''GNULIB_SYMLINKAT''@|$(GNULIB_SYMLINKAT)|g' \
+	      -e 's|@''GNULIB_TTYNAME_R''@|$(GNULIB_TTYNAME_R)|g' \
+	      -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \
+	      -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \
+	      -e 's|@''GNULIB_UNLINK''@|$(GNULIB_UNLINK)|g' \
+	      -e 's|@''GNULIB_UNLINKAT''@|$(GNULIB_UNLINKAT)|g' \
+	      -e 's|@''GNULIB_USLEEP''@|$(GNULIB_USLEEP)|g' \
+	      -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \
+	      < $(srcdir)/unistd.in.h | \
+	  sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \
+	      -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
+	      -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \
+	      -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \
+	      -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \
+	      -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \
+	      -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \
+	      -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \
+	      -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
+	      -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \
+	      -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
+	      -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \
+	      -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \
+	      -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
+	      -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \
+	      -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
+	      -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \
+	      -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \
+	      -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \
+	      -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \
+	      -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \
+	      -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
+	      -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \
+	      -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
+	      -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \
+	      -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \
+	      -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \
+	      -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \
+	      -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \
+	      -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \
+	      -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \
+	      -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
+	      -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
+	      -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \
+	      -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \
+	      -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
+	      -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
+	      -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
+	      -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
+	      -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \
+	      -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
+	      -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \
+	      -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
+	      -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \
+	      -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \
+	      -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
+	      -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
+	      -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \
+	      -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \
+	      -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \
+	      -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \
+	      -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \
+	      -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \
+	      -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \
+	      -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
+	      -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
+	      -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
+	      -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
+	      -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
+	      -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
+	      -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \
+	      -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \
+	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \
+	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += unistd.h unistd.h-t
+
+EXTRA_DIST += unistd.in.h
+
+## end   gnulib module unistd
+
+## begin gnulib module verify
+
+libgnu_la_SOURCES += verify.h
+
+## end   gnulib module verify
+
+## begin gnulib module warn-on-use
+
+BUILT_SOURCES += warn-on-use.h
+# The warn-on-use.h that gets inserted into generated .h files is the same as
+# build-aux/warn-on-use.h, except that it has the copyright header cut off.
+warn-on-use.h: $(top_srcdir)/conf/warn-on-use.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	sed -n -e '/^.ifndef/,$$p' \
+	  < $(top_srcdir)/conf/warn-on-use.h \
+	  > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += warn-on-use.h warn-on-use.h-t
+
+WARN_ON_USE_H=warn-on-use.h
+
+EXTRA_DIST += $(top_srcdir)/conf/warn-on-use.h
+
+## end   gnulib module warn-on-use
+
+## begin gnulib module wchar
+
+BUILT_SOURCES += wchar.h
+
+# We need the following in order to create <wchar.h> when the system
+# version does not work standalone.
+wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \
+	      -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
+	      -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \
+	      -e 's|@''GNULIB_BTOWC''@|$(GNULIB_BTOWC)|g' \
+	      -e 's|@''GNULIB_WCTOB''@|$(GNULIB_WCTOB)|g' \
+	      -e 's|@''GNULIB_MBSINIT''@|$(GNULIB_MBSINIT)|g' \
+	      -e 's|@''GNULIB_MBRTOWC''@|$(GNULIB_MBRTOWC)|g' \
+	      -e 's|@''GNULIB_MBRLEN''@|$(GNULIB_MBRLEN)|g' \
+	      -e 's|@''GNULIB_MBSRTOWCS''@|$(GNULIB_MBSRTOWCS)|g' \
+	      -e 's|@''GNULIB_MBSNRTOWCS''@|$(GNULIB_MBSNRTOWCS)|g' \
+	      -e 's|@''GNULIB_WCRTOMB''@|$(GNULIB_WCRTOMB)|g' \
+	      -e 's|@''GNULIB_WCSRTOMBS''@|$(GNULIB_WCSRTOMBS)|g' \
+	      -e 's|@''GNULIB_WCSNRTOMBS''@|$(GNULIB_WCSNRTOMBS)|g' \
+	      -e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \
+	      -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \
+	      -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \
+	      -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \
+	      -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \
+	      -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \
+	      -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \
+	      -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \
+	      -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \
+	      -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \
+	      -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \
+	      -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \
+	      -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \
+	      -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \
+	      -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \
+	      -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \
+	      -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \
+	      -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \
+	      -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \
+	      -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \
+	      -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \
+	      -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \
+	      -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \
+	      -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \
+	      -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	    < $(srcdir)/wchar.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += wchar.h wchar.h-t
+
+EXTRA_DIST += wchar.in.h
+
+## end   gnulib module wchar
+
+## begin gnulib module wcrtomb
+
+
+EXTRA_DIST += wcrtomb.c
+
+EXTRA_libgnu_la_SOURCES += wcrtomb.c
+
+## end   gnulib module wcrtomb
+
+## begin gnulib module wctype
+
+BUILT_SOURCES += wctype.h
+
+# We need the following in order to create <wctype.h> when the system
+# doesn't have one that works with the given compiler.
+wctype.h: wctype.in.h $(CXXDEFS_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \
+	      -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \
+	      -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \
+	      -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \
+	      -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \
+	      -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/wctype.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+MOSTLYCLEANFILES += wctype.h wctype.h-t
+
+EXTRA_DIST += iswblank.c wctype.in.h
+
+EXTRA_libgnu_la_SOURCES += iswblank.c
+
+## end   gnulib module wctype
+
+
+mostlyclean-local: mostlyclean-generic
+	@for dir in '' $(MOSTLYCLEANDIRS); do \
+	  if test -n "$$dir" && test -d $$dir; then \
+	    echo "rmdir $$dir"; rmdir $$dir; \
+	  fi; \
+	done; \
+	:
diff --git a/gl/Makefile.in b/gl/Makefile.in
new file mode 100644
index 0000000..1e60329
--- /dev/null
+++ b/gl/Makefile.in
@@ -0,0 +1,1561 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License.  As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=gl/doc --tests-base=tests --aux-dir=conf --lgpl --libtool --macro-prefix=gl regex
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = gl
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
+	$(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/btowc.m4 \
+	$(top_srcdir)/gl/m4/codeset.m4 \
+	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/fcntl-o.m4 $(top_srcdir)/gl/m4/glibc21.m4 \
+	$(top_srcdir)/gl/m4/gnulib-common.m4 \
+	$(top_srcdir)/gl/m4/gnulib-comp.m4 \
+	$(top_srcdir)/gl/m4/gnulib-tool.m4 \
+	$(top_srcdir)/gl/m4/include_next.m4 \
+	$(top_srcdir)/gl/m4/langinfo_h.m4 \
+	$(top_srcdir)/gl/m4/localcharset.m4 \
+	$(top_srcdir)/gl/m4/locale-fr.m4 \
+	$(top_srcdir)/gl/m4/locale-ja.m4 \
+	$(top_srcdir)/gl/m4/locale-zh.m4 \
+	$(top_srcdir)/gl/m4/longlong.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+	$(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+	$(top_srcdir)/gl/m4/mbstate_t.m4 \
+	$(top_srcdir)/gl/m4/multiarch.m4 \
+	$(top_srcdir)/gl/m4/nl_langinfo.m4 \
+	$(top_srcdir)/gl/m4/regex.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+	$(top_srcdir)/gl/m4/stdbool.m4 $(top_srcdir)/gl/m4/stddef_h.m4 \
+	$(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/stdlib_h.m4 \
+	$(top_srcdir)/gl/m4/unistd_h.m4 \
+	$(top_srcdir)/gl/m4/warn-on-use.m4 \
+	$(top_srcdir)/gl/m4/wchar_h.m4 $(top_srcdir)/gl/m4/wchar_t.m4 \
+	$(top_srcdir)/gl/m4/wcrtomb.m4 $(top_srcdir)/gl/m4/wctype_h.m4 \
+	$(top_srcdir)/gl/m4/wint_t.m4 $(top_srcdir)/conf/acinclude.m4 \
+	$(top_srcdir)/conf/check_zlib.m4 $(top_srcdir)/conf/cppunit.m4 \
+	$(top_srcdir)/conf/libtool.m4 $(top_srcdir)/conf/ltoptions.m4 \
+	$(top_srcdir)/conf/ltsugar.m4 $(top_srcdir)/conf/ltversion.m4 \
+	$(top_srcdir)/conf/lt~obsolete.m4 $(top_srcdir)/conf/pkg.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+	$(top_builddir)/dods-datatypes-config.h \
+	$(top_builddir)/xdr-datatypes-config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+LTLIBRARIES = $(noinst_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+am_libgnu_la_OBJECTS = localcharset.lo
+libgnu_la_OBJECTS = $(am_libgnu_la_OBJECTS)
+libgnu_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+	$(libgnu_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/conf/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libgnu_la_SOURCES) $(EXTRA_libgnu_la_SOURCES)
+DIST_SOURCES = $(libgnu_la_SOURCES) $(EXTRA_libgnu_la_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+HEADERS = $(noinst_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLIENTLIB_AGE = @CLIENTLIB_AGE@
+CLIENTLIB_CURRENT = @CLIENTLIB_CURRENT@
+CLIENTLIB_REVISION = @CLIENTLIB_REVISION@
+CLIENTLIB_VERSION = @CLIENTLIB_VERSION@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
+CPPUNIT_CONFIG = @CPPUNIT_CONFIG@
+CPPUNIT_LIBS = @CPPUNIT_LIBS@
+CURL_CFLAGS = @CURL_CFLAGS@
+CURL_LIBS = @CURL_LIBS@
+CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DAPLIB_AGE = @DAPLIB_AGE@
+DAPLIB_CURRENT = @DAPLIB_CURRENT@
+DAPLIB_REVISION = @DAPLIB_REVISION@
+DAP_PROTOCOL_VERSION = @DAP_PROTOCOL_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVR = @DVR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EVAL = @EVAL@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIBC21 = @GLIBC21@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDAP_VERSION = @LIBDAP_VERSION@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_MAJOR_VERSION = @PACKAGE_MAJOR_VERSION@
+PACKAGE_MINOR_VERSION = @PACKAGE_MINOR_VERSION@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_SUBMINOR_VERSION = @PACKAGE_SUBMINOR_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVERLIB_AGE = @SERVERLIB_AGE@
+SERVERLIB_CURRENT = @SERVERLIB_CURRENT@
+SERVERLIB_REVISION = @SERVERLIB_REVISION@
+SERVERLIB_VERSION = @SERVERLIB_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+XML2_STATIC_LIBS = @XML2_STATIC_LIBS@
+YACC = @YACC@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+curlprivatelibs = @curlprivatelibs@
+curlprivatereq = @curlprivatereq@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xmlprivatelibs = @xmlprivatelibs@
+xmlprivatereq = @xmlprivatereq@
+AUTOMAKE_OPTIONS = 1.5 gnits
+SUBDIRS = 
+noinst_HEADERS = 
+noinst_LIBRARIES = 
+noinst_LTLIBRARIES = libgnu.la
+EXTRA_DIST = m4/gnulib-cache.m4 alloca.in.h \
+	$(top_srcdir)/conf/arg-nonnull.h btowc.c \
+	$(top_srcdir)/conf/c++defs.h langinfo.in.h config.charset \
+	ref-add.sin ref-del.sin malloc.c malloc.c mbrtowc.c mbsinit.c \
+	nl_langinfo.c regcomp.c regex.c regex.h regex_internal.c \
+	regex_internal.h regexec.c stdbool.in.h stddef.in.h \
+	stdint.in.h stdlib.in.h streq.h unistd.in.h \
+	$(top_srcdir)/conf/warn-on-use.h wchar.in.h wcrtomb.c \
+	iswblank.c wctype.in.h
+
+# The BUILT_SOURCES created by this Makefile snippet are not used via #include
+# statements but through direct file reference. Therefore this snippet must be
+# present in all Makefile.am that need it. This is ensured by the applicability
+# 'all' defined above.
+
+# The BUILT_SOURCES created by this Makefile snippet are not used via #include
+# statements but through direct file reference. Therefore this snippet must be
+# present in all Makefile.am that need it. This is ensured by the applicability
+# 'all' defined above.
+BUILT_SOURCES = $(ALLOCA_H) arg-nonnull.h c++defs.h configmake.h \
+	langinfo.h $(STDBOOL_H) $(STDDEF_H) $(STDINT_H) stdlib.h \
+	unistd.h warn-on-use.h wchar.h wctype.h
+SUFFIXES = .sed .sin
+MOSTLYCLEANFILES = core *.stackdump alloca.h alloca.h-t arg-nonnull.h \
+	arg-nonnull.h-t c++defs.h c++defs.h-t langinfo.h langinfo.h-t \
+	stdbool.h stdbool.h-t stddef.h stddef.h-t stdint.h stdint.h-t \
+	stdlib.h stdlib.h-t unistd.h unistd.h-t warn-on-use.h \
+	warn-on-use.h-t wchar.h wchar.h-t wctype.h wctype.h-t
+MOSTLYCLEANDIRS = 
+CLEANFILES = configmake.h configmake.h-t charset.alias ref-add.sed \
+	ref-del.sed
+DISTCLEANFILES = 
+MAINTAINERCLEANFILES = 
+AM_CPPFLAGS = 
+AM_CFLAGS = 
+libgnu_la_SOURCES = gettext.h localcharset.h localcharset.c verify.h
+libgnu_la_LIBADD = $(gl_LTLIBOBJS)
+libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS)
+EXTRA_libgnu_la_SOURCES = btowc.c malloc.c malloc.c mbrtowc.c \
+	mbsinit.c nl_langinfo.c regcomp.c regex.c regex_internal.c \
+	regexec.c wcrtomb.c iswblank.c
+libgnu_la_LDFLAGS = $(AM_LDFLAGS) -no-undefined $(LTLIBINTL)
+ARG_NONNULL_H = arg-nonnull.h
+CXXDEFS_H = c++defs.h
+charset_alias = $(DESTDIR)$(libdir)/charset.alias
+charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
+WARN_ON_USE_H = warn-on-use.h
+all: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .sed .sin .c .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnits gl/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnits gl/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+
+clean-noinstLTLIBRARIES:
+	-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+	@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
+	  dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+	  test "$$dir" != "$$p" || dir=.; \
+	  echo "rm -f \"$${dir}/so_locations\""; \
+	  rm -f "$${dir}/so_locations"; \
+	done
+libgnu.la: $(libgnu_la_OBJECTS) $(libgnu_la_DEPENDENCIES) 
+	$(libgnu_la_LINK)  $(libgnu_la_OBJECTS) $(libgnu_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/btowc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/iswblank.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/localcharset.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/malloc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mbrtowc.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/mbsinit.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/nl_langinfo.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regcomp.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regex.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regex_internal.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/regexec.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/wcrtomb.Plo at am__quote@
+
+.c.o:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c $<
+
+.c.obj:
+ at am__fastdepCC_TRUE@	$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ at am__fastdepCC_TRUE@	$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCC_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(HEADERS) all-local
+installdirs: installdirs-recursive
+installdirs-am:
+install: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+	-test -z "$(MOSTLYCLEANFILES)" || rm -f $(MOSTLYCLEANFILES)
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+	-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
+clean: clean-recursive
+
+clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
+	clean-noinstLTLIBRARIES mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-exec-local
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool mostlyclean-local
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-local
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all check \
+	ctags-recursive install install-am install-strip \
+	tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am all-local check check-am clean clean-generic \
+	clean-libtool clean-noinstLIBRARIES clean-noinstLTLIBRARIES \
+	ctags ctags-recursive distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-tags distdir dvi \
+	dvi-am html html-am info info-am install install-am \
+	install-data install-data-am install-dvi install-dvi-am \
+	install-exec install-exec-am install-exec-local install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	mostlyclean mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool mostlyclean-local pdf pdf-am ps ps-am tags \
+	tags-recursive uninstall uninstall-am uninstall-local
+
+
+# We need the following in order to create <alloca.h> when the system
+# doesn't have one that works with the given compiler.
+alloca.h: alloca.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  cat $(srcdir)/alloca.in.h; \
+	} > $@-t && \
+	mv -f $@-t $@
+# The arg-nonnull.h that gets inserted into generated .h files is the same as
+# build-aux/arg-nonnull.h, except that it has the copyright header cut off.
+arg-nonnull.h: $(top_srcdir)/conf/arg-nonnull.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	sed -n -e '/GL_ARG_NONNULL/,$$p' \
+	  < $(top_srcdir)/conf/arg-nonnull.h \
+	  > $@-t && \
+	mv $@-t $@
+# The c++defs.h that gets inserted into generated .h files is the same as
+# build-aux/c++defs.h, except that it has the copyright header cut off.
+c++defs.h: $(top_srcdir)/conf/c++defs.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	sed -n -e '/_GL_CXXDEFS/,$$p' \
+	  < $(top_srcdir)/conf/c++defs.h \
+	  > $@-t && \
+	mv $@-t $@
+
+# Listed in the same order as the GNU makefile conventions, and
+# provided by autoconf 2.59c+.
+# The Automake-defined pkg* macros are appended, in the order
+# listed in the Automake 1.10a+ documentation.
+configmake.h: Makefile
+	$(AM_V_GEN)rm -f $@-t && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  echo '#define PREFIX "$(prefix)"'; \
+	  echo '#define EXEC_PREFIX "$(exec_prefix)"'; \
+	  echo '#define BINDIR "$(bindir)"'; \
+	  echo '#define SBINDIR "$(sbindir)"'; \
+	  echo '#define LIBEXECDIR "$(libexecdir)"'; \
+	  echo '#define DATAROOTDIR "$(datarootdir)"'; \
+	  echo '#define DATADIR "$(datadir)"'; \
+	  echo '#define SYSCONFDIR "$(sysconfdir)"'; \
+	  echo '#define SHAREDSTATEDIR "$(sharedstatedir)"'; \
+	  echo '#define LOCALSTATEDIR "$(localstatedir)"'; \
+	  echo '#define INCLUDEDIR "$(includedir)"'; \
+	  echo '#define OLDINCLUDEDIR "$(oldincludedir)"'; \
+	  echo '#define DOCDIR "$(docdir)"'; \
+	  echo '#define INFODIR "$(infodir)"'; \
+	  echo '#define HTMLDIR "$(htmldir)"'; \
+	  echo '#define DVIDIR "$(dvidir)"'; \
+	  echo '#define PDFDIR "$(pdfdir)"'; \
+	  echo '#define PSDIR "$(psdir)"'; \
+	  echo '#define LIBDIR "$(libdir)"'; \
+	  echo '#define LISPDIR "$(lispdir)"'; \
+	  echo '#define LOCALEDIR "$(localedir)"'; \
+	  echo '#define MANDIR "$(mandir)"'; \
+	  echo '#define MANEXT "$(manext)"'; \
+	  echo '#define PKGDATADIR "$(pkgdatadir)"'; \
+	  echo '#define PKGINCLUDEDIR "$(pkgincludedir)"'; \
+	  echo '#define PKGLIBDIR "$(pkglibdir)"'; \
+	  echo '#define PKGLIBEXECDIR "$(pkglibexecdir)"'; \
+	} | sed '/""/d' > $@-t && \
+	if test -f $@ && cmp $@-t $@ > /dev/null; then \
+	  rm -f $@-t; \
+	else \
+	  rm -f $@; mv $@-t $@; \
+	fi
+
+# We need the following in order to create an empty placeholder for
+# <langinfo.h> when the system doesn't have one.
+langinfo.h: langinfo.in.h $(CXXDEFS_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''HAVE_LANGINFO_H''@|$(HAVE_LANGINFO_H)|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_LANGINFO_H''@|$(NEXT_LANGINFO_H)|g' \
+	      -e 's|@''GNULIB_NL_LANGINFO''@|$(GNULIB_NL_LANGINFO)|g' \
+	      -e 's|@''HAVE_LANGINFO_CODESET''@|$(HAVE_LANGINFO_CODESET)|g' \
+	      -e 's|@''HAVE_LANGINFO_T_FMT_AMPM''@|$(HAVE_LANGINFO_T_FMT_AMPM)|g' \
+	      -e 's|@''HAVE_LANGINFO_ERA''@|$(HAVE_LANGINFO_ERA)|g' \
+	      -e 's|@''HAVE_LANGINFO_YESEXPR''@|$(HAVE_LANGINFO_YESEXPR)|g' \
+	      -e 's|@''HAVE_NL_LANGINFO''@|$(HAVE_NL_LANGINFO)|g' \
+	      -e 's|@''REPLACE_NL_LANGINFO''@|$(REPLACE_NL_LANGINFO)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/langinfo.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to install a simple file in $(libdir)
+# which is shared with other installed packages. We use a list of referencing
+# packages so that "make uninstall" will remove the file if and only if it
+# is not used by another installed package.
+# On systems with glibc-2.1 or newer, the file is redundant, therefore we
+# avoid installing it.
+
+all-local: charset.alias ref-add.sed ref-del.sed
+install-exec-local: install-exec-localcharset
+install-exec-localcharset: all-local
+	if test $(GLIBC21) = no; then \
+	  case '$(host_os)' in \
+	    darwin[56]*) \
+	      need_charset_alias=true ;; \
+	    darwin* | cygwin* | mingw* | pw32* | cegcc*) \
+	      need_charset_alias=false ;; \
+	    *) \
+	      need_charset_alias=true ;; \
+	  esac ; \
+	else \
+	  need_charset_alias=false ; \
+	fi ; \
+	if $$need_charset_alias; then \
+	  $(mkinstalldirs) $(DESTDIR)$(libdir) ; \
+	fi ; \
+	if test -f $(charset_alias); then \
+	  sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \
+	  $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
+	  rm -f $(charset_tmp) ; \
+	else \
+	  if $$need_charset_alias; then \
+	    sed -f ref-add.sed charset.alias > $(charset_tmp) ; \
+	    $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
+	    rm -f $(charset_tmp) ; \
+	  fi ; \
+	fi
+
+uninstall-local: uninstall-localcharset
+uninstall-localcharset: all-local
+	if test -f $(charset_alias); then \
+	  sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \
+	  if grep '^# Packages using this file: $$' $(charset_tmp) \
+	      > /dev/null; then \
+	    rm -f $(charset_alias); \
+	  else \
+	    $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \
+	  fi; \
+	  rm -f $(charset_tmp); \
+	fi
+
+charset.alias: config.charset
+	$(AM_V_GEN)rm -f t-$@ $@ && \
+	$(SHELL) $(srcdir)/config.charset '$(host)' > t-$@ && \
+	mv t-$@ $@
+.sin.sed:
+	$(AM_V_GEN)rm -f t-$@ $@ && \
+	sed -e '/^#/d' -e 's/@''PACKAGE''@/$(PACKAGE)/g' $< > t-$@ && \
+	mv t-$@ $@
+
+# We need the following in order to create <stdbool.h> when the system
+# doesn't have one that works.
+stdbool.h: stdbool.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to create <stddef.h> when the system
+# doesn't have one that works with the given compiler.
+stddef.h: stddef.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+	  sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_STDDEF_H''@|$(NEXT_STDDEF_H)|g' \
+	      -e 's|@''HAVE_WCHAR_T''@|$(HAVE_WCHAR_T)|g' \
+	      -e 's|@''REPLACE_NULL''@|$(REPLACE_NULL)|g' \
+	      < $(srcdir)/stddef.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to create <stdint.h> when the system
+# doesn't have one that works with the given compiler.
+stdint.h: stdint.in.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/@''HAVE_STDINT_H''@/$(HAVE_STDINT_H)/g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_STDINT_H''@|$(NEXT_STDINT_H)|g' \
+	      -e 's/@''HAVE_SYS_TYPES_H''@/$(HAVE_SYS_TYPES_H)/g' \
+	      -e 's/@''HAVE_INTTYPES_H''@/$(HAVE_INTTYPES_H)/g' \
+	      -e 's/@''HAVE_SYS_INTTYPES_H''@/$(HAVE_SYS_INTTYPES_H)/g' \
+	      -e 's/@''HAVE_SYS_BITYPES_H''@/$(HAVE_SYS_BITYPES_H)/g' \
+	      -e 's/@''HAVE_LONG_LONG_INT''@/$(HAVE_LONG_LONG_INT)/g' \
+	      -e 's/@''HAVE_UNSIGNED_LONG_LONG_INT''@/$(HAVE_UNSIGNED_LONG_LONG_INT)/g' \
+	      -e 's/@''APPLE_UNIVERSAL_BUILD''@/$(APPLE_UNIVERSAL_BUILD)/g' \
+	      -e 's/@''BITSIZEOF_PTRDIFF_T''@/$(BITSIZEOF_PTRDIFF_T)/g' \
+	      -e 's/@''PTRDIFF_T_SUFFIX''@/$(PTRDIFF_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_SIG_ATOMIC_T''@/$(BITSIZEOF_SIG_ATOMIC_T)/g' \
+	      -e 's/@''HAVE_SIGNED_SIG_ATOMIC_T''@/$(HAVE_SIGNED_SIG_ATOMIC_T)/g' \
+	      -e 's/@''SIG_ATOMIC_T_SUFFIX''@/$(SIG_ATOMIC_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_SIZE_T''@/$(BITSIZEOF_SIZE_T)/g' \
+	      -e 's/@''SIZE_T_SUFFIX''@/$(SIZE_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_WCHAR_T''@/$(BITSIZEOF_WCHAR_T)/g' \
+	      -e 's/@''HAVE_SIGNED_WCHAR_T''@/$(HAVE_SIGNED_WCHAR_T)/g' \
+	      -e 's/@''WCHAR_T_SUFFIX''@/$(WCHAR_T_SUFFIX)/g' \
+	      -e 's/@''BITSIZEOF_WINT_T''@/$(BITSIZEOF_WINT_T)/g' \
+	      -e 's/@''HAVE_SIGNED_WINT_T''@/$(HAVE_SIGNED_WINT_T)/g' \
+	      -e 's/@''WINT_T_SUFFIX''@/$(WINT_T_SUFFIX)/g' \
+	      < $(srcdir)/stdint.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to create <stdlib.h> when the system
+# doesn't have one that works with the given compiler.
+stdlib.h: stdlib.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
+	  sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
+	      -e 's|@''GNULIB__EXIT''@|$(GNULIB__EXIT)|g' \
+	      -e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \
+	      -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \
+	      -e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \
+	      -e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \
+	      -e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
+	      -e 's|@''GNULIB_GRANTPT''@|$(GNULIB_GRANTPT)|g' \
+	      -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
+	      -e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
+	      -e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \
+	      -e 's|@''GNULIB_MKOSTEMPS''@|$(GNULIB_MKOSTEMPS)|g' \
+	      -e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \
+	      -e 's|@''GNULIB_MKSTEMPS''@|$(GNULIB_MKSTEMPS)|g' \
+	      -e 's|@''GNULIB_PTSNAME''@|$(GNULIB_PTSNAME)|g' \
+	      -e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \
+	      -e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \
+	      -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \
+	      -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \
+	      -e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \
+	      -e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \
+	      -e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \
+	      -e 's|@''GNULIB_STRTOLL''@|$(GNULIB_STRTOLL)|g' \
+	      -e 's|@''GNULIB_STRTOULL''@|$(GNULIB_STRTOULL)|g' \
+	      -e 's|@''GNULIB_SYSTEM_POSIX''@|$(GNULIB_SYSTEM_POSIX)|g' \
+	      -e 's|@''GNULIB_UNLOCKPT''@|$(GNULIB_UNLOCKPT)|g' \
+	      -e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
+	      -e 's|@''HAVE__EXIT''@|$(HAVE__EXIT)|g' \
+	      -e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
+	      -e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \
+	      -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \
+	      -e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
+	      -e 's|@''HAVE_GRANTPT''@|$(HAVE_GRANTPT)|g' \
+	      -e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \
+	      -e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \
+	      -e 's|@''HAVE_MKOSTEMPS''@|$(HAVE_MKOSTEMPS)|g' \
+	      -e 's|@''HAVE_MKSTEMP''@|$(HAVE_MKSTEMP)|g' \
+	      -e 's|@''HAVE_MKSTEMPS''@|$(HAVE_MKSTEMPS)|g' \
+	      -e 's|@''HAVE_PTSNAME''@|$(HAVE_PTSNAME)|g' \
+	      -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
+	      -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
+	      -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
+	      -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
+	      -e 's|@''HAVE_DECL_SETENV''@|$(HAVE_DECL_SETENV)|g' \
+	      -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
+	      -e 's|@''HAVE_STRTOLL''@|$(HAVE_STRTOLL)|g' \
+	      -e 's|@''HAVE_STRTOULL''@|$(HAVE_STRTOULL)|g' \
+	      -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \
+	      -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \
+	      -e 's|@''HAVE_UNLOCKPT''@|$(HAVE_UNLOCKPT)|g' \
+	      -e 's|@''HAVE_DECL_UNSETENV''@|$(HAVE_DECL_UNSETENV)|g' \
+	      -e 's|@''REPLACE_CALLOC''@|$(REPLACE_CALLOC)|g' \
+	      -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
+	      -e 's|@''REPLACE_MALLOC''@|$(REPLACE_MALLOC)|g' \
+	      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
+	      -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
+	      -e 's|@''REPLACE_REALLOC''@|$(REPLACE_REALLOC)|g' \
+	      -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
+	      -e 's|@''REPLACE_SETENV''@|$(REPLACE_SETENV)|g' \
+	      -e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
+	      -e 's|@''REPLACE_UNSETENV''@|$(REPLACE_UNSETENV)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/stdlib.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to create an empty placeholder for
+# <unistd.h> when the system doesn't have one.
+unistd.h: unistd.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''HAVE_UNISTD_H''@|$(HAVE_UNISTD_H)|g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_UNISTD_H''@|$(NEXT_UNISTD_H)|g' \
+	      -e 's|@''GNULIB_CHOWN''@|$(GNULIB_CHOWN)|g' \
+	      -e 's|@''GNULIB_CLOSE''@|$(GNULIB_CLOSE)|g' \
+	      -e 's|@''GNULIB_DUP2''@|$(GNULIB_DUP2)|g' \
+	      -e 's|@''GNULIB_DUP3''@|$(GNULIB_DUP3)|g' \
+	      -e 's|@''GNULIB_ENVIRON''@|$(GNULIB_ENVIRON)|g' \
+	      -e 's|@''GNULIB_EUIDACCESS''@|$(GNULIB_EUIDACCESS)|g' \
+	      -e 's|@''GNULIB_FACCESSAT''@|$(GNULIB_FACCESSAT)|g' \
+	      -e 's|@''GNULIB_FCHDIR''@|$(GNULIB_FCHDIR)|g' \
+	      -e 's|@''GNULIB_FCHOWNAT''@|$(GNULIB_FCHOWNAT)|g' \
+	      -e 's|@''GNULIB_FSYNC''@|$(GNULIB_FSYNC)|g' \
+	      -e 's|@''GNULIB_FTRUNCATE''@|$(GNULIB_FTRUNCATE)|g' \
+	      -e 's|@''GNULIB_GETCWD''@|$(GNULIB_GETCWD)|g' \
+	      -e 's|@''GNULIB_GETDOMAINNAME''@|$(GNULIB_GETDOMAINNAME)|g' \
+	      -e 's|@''GNULIB_GETDTABLESIZE''@|$(GNULIB_GETDTABLESIZE)|g' \
+	      -e 's|@''GNULIB_GETGROUPS''@|$(GNULIB_GETGROUPS)|g' \
+	      -e 's|@''GNULIB_GETHOSTNAME''@|$(GNULIB_GETHOSTNAME)|g' \
+	      -e 's|@''GNULIB_GETLOGIN''@|$(GNULIB_GETLOGIN)|g' \
+	      -e 's|@''GNULIB_GETLOGIN_R''@|$(GNULIB_GETLOGIN_R)|g' \
+	      -e 's|@''GNULIB_GETPAGESIZE''@|$(GNULIB_GETPAGESIZE)|g' \
+	      -e 's|@''GNULIB_GETUSERSHELL''@|$(GNULIB_GETUSERSHELL)|g' \
+	      -e 's|@''GNULIB_LCHOWN''@|$(GNULIB_LCHOWN)|g' \
+	      -e 's|@''GNULIB_LINK''@|$(GNULIB_LINK)|g' \
+	      -e 's|@''GNULIB_LINKAT''@|$(GNULIB_LINKAT)|g' \
+	      -e 's|@''GNULIB_LSEEK''@|$(GNULIB_LSEEK)|g' \
+	      -e 's|@''GNULIB_PIPE''@|$(GNULIB_PIPE)|g' \
+	      -e 's|@''GNULIB_PIPE2''@|$(GNULIB_PIPE2)|g' \
+	      -e 's|@''GNULIB_PREAD''@|$(GNULIB_PREAD)|g' \
+	      -e 's|@''GNULIB_PWRITE''@|$(GNULIB_PWRITE)|g' \
+	      -e 's|@''GNULIB_READLINK''@|$(GNULIB_READLINK)|g' \
+	      -e 's|@''GNULIB_READLINKAT''@|$(GNULIB_READLINKAT)|g' \
+	      -e 's|@''GNULIB_RMDIR''@|$(GNULIB_RMDIR)|g' \
+	      -e 's|@''GNULIB_SLEEP''@|$(GNULIB_SLEEP)|g' \
+	      -e 's|@''GNULIB_SYMLINK''@|$(GNULIB_SYMLINK)|g' \
+	      -e 's|@''GNULIB_SYMLINKAT''@|$(GNULIB_SYMLINKAT)|g' \
+	      -e 's|@''GNULIB_TTYNAME_R''@|$(GNULIB_TTYNAME_R)|g' \
+	      -e 's|@''GNULIB_UNISTD_H_GETOPT''@|$(GNULIB_UNISTD_H_GETOPT)|g' \
+	      -e 's|@''GNULIB_UNISTD_H_SIGPIPE''@|$(GNULIB_UNISTD_H_SIGPIPE)|g' \
+	      -e 's|@''GNULIB_UNLINK''@|$(GNULIB_UNLINK)|g' \
+	      -e 's|@''GNULIB_UNLINKAT''@|$(GNULIB_UNLINKAT)|g' \
+	      -e 's|@''GNULIB_USLEEP''@|$(GNULIB_USLEEP)|g' \
+	      -e 's|@''GNULIB_WRITE''@|$(GNULIB_WRITE)|g' \
+	      < $(srcdir)/unistd.in.h | \
+	  sed -e 's|@''HAVE_CHOWN''@|$(HAVE_CHOWN)|g' \
+	      -e 's|@''HAVE_DUP2''@|$(HAVE_DUP2)|g' \
+	      -e 's|@''HAVE_DUP3''@|$(HAVE_DUP3)|g' \
+	      -e 's|@''HAVE_EUIDACCESS''@|$(HAVE_EUIDACCESS)|g' \
+	      -e 's|@''HAVE_FACCESSAT''@|$(HAVE_FACCESSAT)|g' \
+	      -e 's|@''HAVE_FCHDIR''@|$(HAVE_FCHDIR)|g' \
+	      -e 's|@''HAVE_FCHOWNAT''@|$(HAVE_FCHOWNAT)|g' \
+	      -e 's|@''HAVE_FSYNC''@|$(HAVE_FSYNC)|g' \
+	      -e 's|@''HAVE_FTRUNCATE''@|$(HAVE_FTRUNCATE)|g' \
+	      -e 's|@''HAVE_GETDTABLESIZE''@|$(HAVE_GETDTABLESIZE)|g' \
+	      -e 's|@''HAVE_GETGROUPS''@|$(HAVE_GETGROUPS)|g' \
+	      -e 's|@''HAVE_GETHOSTNAME''@|$(HAVE_GETHOSTNAME)|g' \
+	      -e 's|@''HAVE_GETLOGIN''@|$(HAVE_GETLOGIN)|g' \
+	      -e 's|@''HAVE_GETPAGESIZE''@|$(HAVE_GETPAGESIZE)|g' \
+	      -e 's|@''HAVE_LCHOWN''@|$(HAVE_LCHOWN)|g' \
+	      -e 's|@''HAVE_LINK''@|$(HAVE_LINK)|g' \
+	      -e 's|@''HAVE_LINKAT''@|$(HAVE_LINKAT)|g' \
+	      -e 's|@''HAVE_PIPE''@|$(HAVE_PIPE)|g' \
+	      -e 's|@''HAVE_PIPE2''@|$(HAVE_PIPE2)|g' \
+	      -e 's|@''HAVE_PREAD''@|$(HAVE_PREAD)|g' \
+	      -e 's|@''HAVE_PWRITE''@|$(HAVE_PWRITE)|g' \
+	      -e 's|@''HAVE_READLINK''@|$(HAVE_READLINK)|g' \
+	      -e 's|@''HAVE_READLINKAT''@|$(HAVE_READLINKAT)|g' \
+	      -e 's|@''HAVE_SLEEP''@|$(HAVE_SLEEP)|g' \
+	      -e 's|@''HAVE_SYMLINK''@|$(HAVE_SYMLINK)|g' \
+	      -e 's|@''HAVE_SYMLINKAT''@|$(HAVE_SYMLINKAT)|g' \
+	      -e 's|@''HAVE_UNLINKAT''@|$(HAVE_UNLINKAT)|g' \
+	      -e 's|@''HAVE_USLEEP''@|$(HAVE_USLEEP)|g' \
+	      -e 's|@''HAVE_DECL_ENVIRON''@|$(HAVE_DECL_ENVIRON)|g' \
+	      -e 's|@''HAVE_DECL_FCHDIR''@|$(HAVE_DECL_FCHDIR)|g' \
+	      -e 's|@''HAVE_DECL_GETDOMAINNAME''@|$(HAVE_DECL_GETDOMAINNAME)|g' \
+	      -e 's|@''HAVE_DECL_GETLOGIN_R''@|$(HAVE_DECL_GETLOGIN_R)|g' \
+	      -e 's|@''HAVE_DECL_GETPAGESIZE''@|$(HAVE_DECL_GETPAGESIZE)|g' \
+	      -e 's|@''HAVE_DECL_GETUSERSHELL''@|$(HAVE_DECL_GETUSERSHELL)|g' \
+	      -e 's|@''HAVE_DECL_TTYNAME_R''@|$(HAVE_DECL_TTYNAME_R)|g' \
+	      -e 's|@''HAVE_OS_H''@|$(HAVE_OS_H)|g' \
+	      -e 's|@''HAVE_SYS_PARAM_H''@|$(HAVE_SYS_PARAM_H)|g' \
+	      -e 's|@''REPLACE_CHOWN''@|$(REPLACE_CHOWN)|g' \
+	      -e 's|@''REPLACE_CLOSE''@|$(REPLACE_CLOSE)|g' \
+	      -e 's|@''REPLACE_DUP''@|$(REPLACE_DUP)|g' \
+	      -e 's|@''REPLACE_DUP2''@|$(REPLACE_DUP2)|g' \
+	      -e 's|@''REPLACE_FCHOWNAT''@|$(REPLACE_FCHOWNAT)|g' \
+	      -e 's|@''REPLACE_GETCWD''@|$(REPLACE_GETCWD)|g' \
+	      -e 's|@''REPLACE_GETDOMAINNAME''@|$(REPLACE_GETDOMAINNAME)|g' \
+	      -e 's|@''REPLACE_GETLOGIN_R''@|$(REPLACE_GETLOGIN_R)|g' \
+	      -e 's|@''REPLACE_GETGROUPS''@|$(REPLACE_GETGROUPS)|g' \
+	      -e 's|@''REPLACE_GETPAGESIZE''@|$(REPLACE_GETPAGESIZE)|g' \
+	      -e 's|@''REPLACE_LCHOWN''@|$(REPLACE_LCHOWN)|g' \
+	      -e 's|@''REPLACE_LINK''@|$(REPLACE_LINK)|g' \
+	      -e 's|@''REPLACE_LINKAT''@|$(REPLACE_LINKAT)|g' \
+	      -e 's|@''REPLACE_LSEEK''@|$(REPLACE_LSEEK)|g' \
+	      -e 's|@''REPLACE_PREAD''@|$(REPLACE_PREAD)|g' \
+	      -e 's|@''REPLACE_PWRITE''@|$(REPLACE_PWRITE)|g' \
+	      -e 's|@''REPLACE_READLINK''@|$(REPLACE_READLINK)|g' \
+	      -e 's|@''REPLACE_RMDIR''@|$(REPLACE_RMDIR)|g' \
+	      -e 's|@''REPLACE_SLEEP''@|$(REPLACE_SLEEP)|g' \
+	      -e 's|@''REPLACE_SYMLINK''@|$(REPLACE_SYMLINK)|g' \
+	      -e 's|@''REPLACE_TTYNAME_R''@|$(REPLACE_TTYNAME_R)|g' \
+	      -e 's|@''REPLACE_UNLINK''@|$(REPLACE_UNLINK)|g' \
+	      -e 's|@''REPLACE_UNLINKAT''@|$(REPLACE_UNLINKAT)|g' \
+	      -e 's|@''REPLACE_USLEEP''@|$(REPLACE_USLEEP)|g' \
+	      -e 's|@''REPLACE_WRITE''@|$(REPLACE_WRITE)|g' \
+	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H''@|$(UNISTD_H_HAVE_WINSOCK2_H)|g' \
+	      -e 's|@''UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS''@|$(UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)'; \
+	} > $@-t && \
+	mv $@-t $@
+# The warn-on-use.h that gets inserted into generated .h files is the same as
+# build-aux/warn-on-use.h, except that it has the copyright header cut off.
+warn-on-use.h: $(top_srcdir)/conf/warn-on-use.h
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	sed -n -e '/^.ifndef/,$$p' \
+	  < $(top_srcdir)/conf/warn-on-use.h \
+	  > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to create <wchar.h> when the system
+# version does not work standalone.
+wchar.h: wchar.in.h $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''HAVE_FEATURES_H''@|$(HAVE_FEATURES_H)|g' \
+	      -e 's|@''NEXT_WCHAR_H''@|$(NEXT_WCHAR_H)|g' \
+	      -e 's|@''HAVE_WCHAR_H''@|$(HAVE_WCHAR_H)|g' \
+	      -e 's|@''GNULIB_BTOWC''@|$(GNULIB_BTOWC)|g' \
+	      -e 's|@''GNULIB_WCTOB''@|$(GNULIB_WCTOB)|g' \
+	      -e 's|@''GNULIB_MBSINIT''@|$(GNULIB_MBSINIT)|g' \
+	      -e 's|@''GNULIB_MBRTOWC''@|$(GNULIB_MBRTOWC)|g' \
+	      -e 's|@''GNULIB_MBRLEN''@|$(GNULIB_MBRLEN)|g' \
+	      -e 's|@''GNULIB_MBSRTOWCS''@|$(GNULIB_MBSRTOWCS)|g' \
+	      -e 's|@''GNULIB_MBSNRTOWCS''@|$(GNULIB_MBSNRTOWCS)|g' \
+	      -e 's|@''GNULIB_WCRTOMB''@|$(GNULIB_WCRTOMB)|g' \
+	      -e 's|@''GNULIB_WCSRTOMBS''@|$(GNULIB_WCSRTOMBS)|g' \
+	      -e 's|@''GNULIB_WCSNRTOMBS''@|$(GNULIB_WCSNRTOMBS)|g' \
+	      -e 's|@''GNULIB_WCWIDTH''@|$(GNULIB_WCWIDTH)|g' \
+	      -e 's|@''HAVE_WINT_T''@|$(HAVE_WINT_T)|g' \
+	      -e 's|@''HAVE_BTOWC''@|$(HAVE_BTOWC)|g' \
+	      -e 's|@''HAVE_MBSINIT''@|$(HAVE_MBSINIT)|g' \
+	      -e 's|@''HAVE_MBRTOWC''@|$(HAVE_MBRTOWC)|g' \
+	      -e 's|@''HAVE_MBRLEN''@|$(HAVE_MBRLEN)|g' \
+	      -e 's|@''HAVE_MBSRTOWCS''@|$(HAVE_MBSRTOWCS)|g' \
+	      -e 's|@''HAVE_MBSNRTOWCS''@|$(HAVE_MBSNRTOWCS)|g' \
+	      -e 's|@''HAVE_WCRTOMB''@|$(HAVE_WCRTOMB)|g' \
+	      -e 's|@''HAVE_WCSRTOMBS''@|$(HAVE_WCSRTOMBS)|g' \
+	      -e 's|@''HAVE_WCSNRTOMBS''@|$(HAVE_WCSNRTOMBS)|g' \
+	      -e 's|@''HAVE_DECL_WCTOB''@|$(HAVE_DECL_WCTOB)|g' \
+	      -e 's|@''HAVE_DECL_WCWIDTH''@|$(HAVE_DECL_WCWIDTH)|g' \
+	      -e 's|@''REPLACE_MBSTATE_T''@|$(REPLACE_MBSTATE_T)|g' \
+	      -e 's|@''REPLACE_BTOWC''@|$(REPLACE_BTOWC)|g' \
+	      -e 's|@''REPLACE_WCTOB''@|$(REPLACE_WCTOB)|g' \
+	      -e 's|@''REPLACE_MBSINIT''@|$(REPLACE_MBSINIT)|g' \
+	      -e 's|@''REPLACE_MBRTOWC''@|$(REPLACE_MBRTOWC)|g' \
+	      -e 's|@''REPLACE_MBRLEN''@|$(REPLACE_MBRLEN)|g' \
+	      -e 's|@''REPLACE_MBSRTOWCS''@|$(REPLACE_MBSRTOWCS)|g' \
+	      -e 's|@''REPLACE_MBSNRTOWCS''@|$(REPLACE_MBSNRTOWCS)|g' \
+	      -e 's|@''REPLACE_WCRTOMB''@|$(REPLACE_WCRTOMB)|g' \
+	      -e 's|@''REPLACE_WCSRTOMBS''@|$(REPLACE_WCSRTOMBS)|g' \
+	      -e 's|@''REPLACE_WCSNRTOMBS''@|$(REPLACE_WCSNRTOMBS)|g' \
+	      -e 's|@''REPLACE_WCWIDTH''@|$(REPLACE_WCWIDTH)|g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	    < $(srcdir)/wchar.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+# We need the following in order to create <wctype.h> when the system
+# doesn't have one that works with the given compiler.
+wctype.h: wctype.in.h $(CXXDEFS_H) $(WARN_ON_USE_H)
+	$(AM_V_GEN)rm -f $@-t $@ && \
+	{ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
+	  sed -e 's/@''HAVE_WCTYPE_H''@/$(HAVE_WCTYPE_H)/g' \
+	      -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
+	      -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
+	      -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \
+	      -e 's|@''NEXT_WCTYPE_H''@|$(NEXT_WCTYPE_H)|g' \
+	      -e 's/@''HAVE_ISWBLANK''@/$(HAVE_ISWBLANK)/g' \
+	      -e 's/@''HAVE_ISWCNTRL''@/$(HAVE_ISWCNTRL)/g' \
+	      -e 's/@''HAVE_WINT_T''@/$(HAVE_WINT_T)/g' \
+	      -e 's/@''REPLACE_ISWBLANK''@/$(REPLACE_ISWBLANK)/g' \
+	      -e 's/@''REPLACE_ISWCNTRL''@/$(REPLACE_ISWCNTRL)/g' \
+	      -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \
+	      -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
+	      < $(srcdir)/wctype.in.h; \
+	} > $@-t && \
+	mv $@-t $@
+
+mostlyclean-local: mostlyclean-generic
+	@for dir in '' $(MOSTLYCLEANDIRS); do \
+	  if test -n "$$dir" && test -d $$dir; then \
+	    echo "rmdir $$dir"; rmdir $$dir; \
+	  fi; \
+	done; \
+	:
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gl/alloca.in.h b/gl/alloca.in.h
new file mode 100644
index 0000000..441b5f4
--- /dev/null
+++ b/gl/alloca.in.h
@@ -0,0 +1,56 @@
+/* Memory allocation on the stack.
+
+   Copyright (C) 1995, 1999, 2001-2004, 2006-2011 Free Software Foundation,
+   Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Lesser 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 Lesser 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.  */
+
+/* Avoid using the symbol _ALLOCA_H here, as Bison assumes _ALLOCA_H
+   means there is a real alloca function.  */
+#ifndef _GL_ALLOCA_H
+#define _GL_ALLOCA_H
+
+/* alloca (N) returns a pointer to N bytes of memory
+   allocated on the stack, which will last until the function returns.
+   Use of alloca should be avoided:
+     - inside arguments of function calls - undefined behaviour,
+     - in inline functions - the allocation may actually last until the
+       calling function returns,
+     - for huge N (say, N >= 65536) - you never know how large (or small)
+       the stack is, and when the stack cannot fulfill the memory allocation
+       request, the program just crashes.
+ */
+
+#ifndef alloca
+# ifdef __GNUC__
+#  define alloca __builtin_alloca
+# elif defined _AIX
+#  define alloca __alloca
+# elif defined _MSC_VER
+#  include <malloc.h>
+#  define alloca _alloca
+# elif defined __DECC && defined __VMS
+#  define alloca __ALLOCA
+# else
+#  include <stddef.h>
+#  ifdef  __cplusplus
+extern "C"
+#  endif
+void *alloca (size_t);
+# endif
+#endif
+
+#endif /* _GL_ALLOCA_H */
diff --git a/gl/btowc.c b/gl/btowc.c
new file mode 100644
index 0000000..2ab61a5
--- /dev/null
+++ b/gl/btowc.c
@@ -0,0 +1,39 @@
+/* Convert unibyte character to wide character.
+   Copyright (C) 2008, 2010-2011 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno at clisp.org>, 2008.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <wchar.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+wint_t
+btowc (int c)
+{
+  if (c != EOF)
+    {
+      char buf[1];
+      wchar_t wc;
+
+      buf[0] = c;
+      if (mbtowc (&wc, buf, 1) >= 0)
+        return wc;
+    }
+  return WEOF;
+}
diff --git a/gl/config.charset b/gl/config.charset
new file mode 100755
index 0000000..55d7791
--- /dev/null
+++ b/gl/config.charset
@@ -0,0 +1,683 @@
+#! /bin/sh
+# Output a system dependent table of character encoding aliases.
+#
+#   Copyright (C) 2000-2004, 2006-2011 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser 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.
+#
+# The table consists of lines of the form
+#    ALIAS  CANONICAL
+#
+# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)".
+# ALIAS is compared in a case sensitive way.
+#
+# CANONICAL is the GNU canonical name for this character encoding.
+# It must be an encoding supported by libiconv. Support by GNU libc is
+# also desirable. CANONICAL is case insensitive. Usually an upper case
+# MIME charset name is preferred.
+# The current list of GNU canonical charset names is as follows.
+#
+#       name              MIME?             used by which systems
+#   ASCII, ANSI_X3.4-1968       glibc solaris freebsd netbsd darwin cygwin
+#   ISO-8859-1              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
+#   ISO-8859-2              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
+#   ISO-8859-3              Y   glibc solaris cygwin
+#   ISO-8859-4              Y   osf solaris freebsd netbsd openbsd darwin
+#   ISO-8859-5              Y   glibc aix hpux irix osf solaris freebsd netbsd openbsd darwin cygwin
+#   ISO-8859-6              Y   glibc aix hpux solaris cygwin
+#   ISO-8859-7              Y   glibc aix hpux irix osf solaris netbsd openbsd darwin cygwin
+#   ISO-8859-8              Y   glibc aix hpux osf solaris cygwin
+#   ISO-8859-9              Y   glibc aix hpux irix osf solaris darwin cygwin
+#   ISO-8859-13                 glibc netbsd openbsd darwin cygwin
+#   ISO-8859-14                 glibc cygwin
+#   ISO-8859-15                 glibc aix osf solaris freebsd netbsd openbsd darwin cygwin
+#   KOI8-R                  Y   glibc solaris freebsd netbsd openbsd darwin
+#   KOI8-U                  Y   glibc freebsd netbsd openbsd darwin cygwin
+#   KOI8-T                      glibc
+#   CP437                       dos
+#   CP775                       dos
+#   CP850                       aix osf dos
+#   CP852                       dos
+#   CP855                       dos
+#   CP856                       aix
+#   CP857                       dos
+#   CP861                       dos
+#   CP862                       dos
+#   CP864                       dos
+#   CP865                       dos
+#   CP866                       freebsd netbsd openbsd darwin dos
+#   CP869                       dos
+#   CP874                       woe32 dos
+#   CP922                       aix
+#   CP932                       aix cygwin woe32 dos
+#   CP943                       aix
+#   CP949                       osf darwin woe32 dos
+#   CP950                       woe32 dos
+#   CP1046                      aix
+#   CP1124                      aix
+#   CP1125                      dos
+#   CP1129                      aix
+#   CP1131                      darwin
+#   CP1250                      woe32
+#   CP1251                      glibc solaris netbsd openbsd darwin cygwin woe32
+#   CP1252                      aix woe32
+#   CP1253                      woe32
+#   CP1254                      woe32
+#   CP1255                      glibc woe32
+#   CP1256                      woe32
+#   CP1257                      woe32
+#   GB2312                  Y   glibc aix hpux irix solaris freebsd netbsd darwin
+#   EUC-JP                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+#   EUC-KR                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin cygwin
+#   EUC-TW                      glibc aix hpux irix osf solaris netbsd
+#   BIG5                    Y   glibc aix hpux osf solaris freebsd netbsd darwin cygwin
+#   BIG5-HKSCS                  glibc solaris darwin
+#   GBK                         glibc aix osf solaris darwin cygwin woe32 dos
+#   GB18030                     glibc solaris netbsd darwin
+#   SHIFT_JIS               Y   hpux osf solaris freebsd netbsd darwin
+#   JOHAB                       glibc solaris woe32
+#   TIS-620                     glibc aix hpux osf solaris cygwin
+#   VISCII                  Y   glibc
+#   TCVN5712-1                  glibc
+#   ARMSCII-8                   glibc darwin
+#   GEORGIAN-PS                 glibc cygwin
+#   PT154                       glibc
+#   HP-ROMAN8                   hpux
+#   HP-ARABIC8                  hpux
+#   HP-GREEK8                   hpux
+#   HP-HEBREW8                  hpux
+#   HP-TURKISH8                 hpux
+#   HP-KANA8                    hpux
+#   DEC-KANJI                   osf
+#   DEC-HANYU                   osf
+#   UTF-8                   Y   glibc aix hpux osf solaris netbsd darwin cygwin
+#
+# Note: Names which are not marked as being a MIME name should not be used in
+# Internet protocols for information interchange (mail, news, etc.).
+#
+# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications
+# must understand both names and treat them as equivalent.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+
+host="$1"
+os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'`
+echo "# This file contains a table of character encoding aliases,"
+echo "# suitable for operating system '${os}'."
+echo "# It was automatically generated from config.charset."
+# List of references, updated during installation:
+echo "# Packages using this file: "
+case "$os" in
+  linux-gnulibc1*)
+    # Linux libc5 doesn't have nl_langinfo(CODESET); therefore
+    # localcharset.c falls back to using the full locale name
+    # from the environment variables.
+    echo "C ASCII"
+    echo "POSIX ASCII"
+    for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \
+             en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \
+             en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \
+             es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \
+             et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \
+             fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \
+             it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \
+             sv_FI sv_SE; do
+      echo "$l ISO-8859-1"
+      echo "$l.iso-8859-1 ISO-8859-1"
+      echo "$l.iso-8859-15 ISO-8859-15"
+      echo "$l.iso-8859-15 at euro ISO-8859-15"
+      echo "$l at euro ISO-8859-15"
+      echo "$l.cp-437 CP437"
+      echo "$l.cp-850 CP850"
+      echo "$l.cp-1252 CP1252"
+      echo "$l.cp-1252 at euro CP1252"
+      #echo "$l.atari-st ATARI-ST" # not a commonly used encoding
+      echo "$l.utf-8 UTF-8"
+      echo "$l.utf-8 at euro UTF-8"
+    done
+    for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \
+             sl_SI sr sr_CS sr_YU; do
+      echo "$l ISO-8859-2"
+      echo "$l.iso-8859-2 ISO-8859-2"
+      echo "$l.cp-852 CP852"
+      echo "$l.cp-1250 CP1250"
+      echo "$l.utf-8 UTF-8"
+    done
+    for l in mk mk_MK ru ru_RU; do
+      echo "$l ISO-8859-5"
+      echo "$l.iso-8859-5 ISO-8859-5"
+      echo "$l.koi8-r KOI8-R"
+      echo "$l.cp-866 CP866"
+      echo "$l.cp-1251 CP1251"
+      echo "$l.utf-8 UTF-8"
+    done
+    for l in ar ar_SA; do
+      echo "$l ISO-8859-6"
+      echo "$l.iso-8859-6 ISO-8859-6"
+      echo "$l.cp-864 CP864"
+      #echo "$l.cp-868 CP868" # not a commonly used encoding
+      echo "$l.cp-1256 CP1256"
+      echo "$l.utf-8 UTF-8"
+    done
+    for l in el el_GR gr gr_GR; do
+      echo "$l ISO-8859-7"
+      echo "$l.iso-8859-7 ISO-8859-7"
+      echo "$l.cp-869 CP869"
+      echo "$l.cp-1253 CP1253"
+      echo "$l.cp-1253 at euro CP1253"
+      echo "$l.utf-8 UTF-8"
+      echo "$l.utf-8 at euro UTF-8"
+    done
+    for l in he he_IL iw iw_IL; do
+      echo "$l ISO-8859-8"
+      echo "$l.iso-8859-8 ISO-8859-8"
+      echo "$l.cp-862 CP862"
+      echo "$l.cp-1255 CP1255"
+      echo "$l.utf-8 UTF-8"
+    done
+    for l in tr tr_TR; do
+      echo "$l ISO-8859-9"
+      echo "$l.iso-8859-9 ISO-8859-9"
+      echo "$l.cp-857 CP857"
+      echo "$l.cp-1254 CP1254"
+      echo "$l.utf-8 UTF-8"
+    done
+    for l in lt lt_LT lv lv_LV; do
+      #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name
+      echo "$l ISO-8859-13"
+    done
+    for l in ru_UA uk uk_UA; do
+      echo "$l KOI8-U"
+    done
+    for l in zh zh_CN; do
+      #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name
+      echo "$l GB2312"
+    done
+    for l in ja ja_JP ja_JP.EUC; do
+      echo "$l EUC-JP"
+    done
+    for l in ko ko_KR; do
+      echo "$l EUC-KR"
+    done
+    for l in th th_TH; do
+      echo "$l TIS-620"
+    done
+    for l in fa fa_IR; do
+      #echo "$l ISIRI-3342" # a broken encoding
+      echo "$l.utf-8 UTF-8"
+    done
+    ;;
+  linux* | *-gnu*)
+    # With glibc-2.1 or newer, we don't need any canonicalization,
+    # because glibc has iconv and both glibc and libiconv support all
+    # GNU canonical names directly. Therefore, the Makefile does not
+    # need to install the alias file at all.
+    # The following applies only to glibc-2.0.x and older libcs.
+    echo "ISO_646.IRV:1983 ASCII"
+    ;;
+  aix*)
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-6 ISO-8859-6"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-8 ISO-8859-8"
+    echo "ISO8859-9 ISO-8859-9"
+    echo "ISO8859-15 ISO-8859-15"
+    echo "IBM-850 CP850"
+    echo "IBM-856 CP856"
+    echo "IBM-921 ISO-8859-13"
+    echo "IBM-922 CP922"
+    echo "IBM-932 CP932"
+    echo "IBM-943 CP943"
+    echo "IBM-1046 CP1046"
+    echo "IBM-1124 CP1124"
+    echo "IBM-1129 CP1129"
+    echo "IBM-1252 CP1252"
+    echo "IBM-eucCN GB2312"
+    echo "IBM-eucJP EUC-JP"
+    echo "IBM-eucKR EUC-KR"
+    echo "IBM-eucTW EUC-TW"
+    echo "big5 BIG5"
+    echo "GBK GBK"
+    echo "TIS-620 TIS-620"
+    echo "UTF-8 UTF-8"
+    ;;
+  hpux*)
+    echo "iso88591 ISO-8859-1"
+    echo "iso88592 ISO-8859-2"
+    echo "iso88595 ISO-8859-5"
+    echo "iso88596 ISO-8859-6"
+    echo "iso88597 ISO-8859-7"
+    echo "iso88598 ISO-8859-8"
+    echo "iso88599 ISO-8859-9"
+    echo "iso885915 ISO-8859-15"
+    echo "roman8 HP-ROMAN8"
+    echo "arabic8 HP-ARABIC8"
+    echo "greek8 HP-GREEK8"
+    echo "hebrew8 HP-HEBREW8"
+    echo "turkish8 HP-TURKISH8"
+    echo "kana8 HP-KANA8"
+    echo "tis620 TIS-620"
+    echo "big5 BIG5"
+    echo "eucJP EUC-JP"
+    echo "eucKR EUC-KR"
+    echo "eucTW EUC-TW"
+    echo "hp15CN GB2312"
+    #echo "ccdc ?" # what is this?
+    echo "SJIS SHIFT_JIS"
+    echo "utf8 UTF-8"
+    ;;
+  irix*)
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-9 ISO-8859-9"
+    echo "eucCN GB2312"
+    echo "eucJP EUC-JP"
+    echo "eucKR EUC-KR"
+    echo "eucTW EUC-TW"
+    ;;
+  osf*)
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-4 ISO-8859-4"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-8 ISO-8859-8"
+    echo "ISO8859-9 ISO-8859-9"
+    echo "ISO8859-15 ISO-8859-15"
+    echo "cp850 CP850"
+    echo "big5 BIG5"
+    echo "dechanyu DEC-HANYU"
+    echo "dechanzi GB2312"
+    echo "deckanji DEC-KANJI"
+    echo "deckorean EUC-KR"
+    echo "eucJP EUC-JP"
+    echo "eucKR EUC-KR"
+    echo "eucTW EUC-TW"
+    echo "GBK GBK"
+    echo "KSC5601 CP949"
+    echo "sdeckanji EUC-JP"
+    echo "SJIS SHIFT_JIS"
+    echo "TACTIS TIS-620"
+    echo "UTF-8 UTF-8"
+    ;;
+  solaris*)
+    echo "646 ASCII"
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-3 ISO-8859-3"
+    echo "ISO8859-4 ISO-8859-4"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-6 ISO-8859-6"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-8 ISO-8859-8"
+    echo "ISO8859-9 ISO-8859-9"
+    echo "ISO8859-15 ISO-8859-15"
+    echo "koi8-r KOI8-R"
+    echo "ansi-1251 CP1251"
+    echo "BIG5 BIG5"
+    echo "Big5-HKSCS BIG5-HKSCS"
+    echo "gb2312 GB2312"
+    echo "GBK GBK"
+    echo "GB18030 GB18030"
+    echo "cns11643 EUC-TW"
+    echo "5601 EUC-KR"
+    echo "ko_KR.johap92 JOHAB"
+    echo "eucJP EUC-JP"
+    echo "PCK SHIFT_JIS"
+    echo "TIS620.2533 TIS-620"
+    #echo "sun_eu_greek ?" # what is this?
+    echo "UTF-8 UTF-8"
+    ;;
+  freebsd* | os2*)
+    # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore
+    # localcharset.c falls back to using the full locale name
+    # from the environment variables.
+    # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just
+    # reuse FreeBSD's locale data for OS/2.
+    echo "C ASCII"
+    echo "US-ASCII ASCII"
+    for l in la_LN lt_LN; do
+      echo "$l.ASCII ASCII"
+    done
+    for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \
+             fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \
+             lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do
+      echo "$l.ISO_8859-1 ISO-8859-1"
+      echo "$l.DIS_8859-15 ISO-8859-15"
+    done
+    for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do
+      echo "$l.ISO_8859-2 ISO-8859-2"
+    done
+    for l in la_LN lt_LT; do
+      echo "$l.ISO_8859-4 ISO-8859-4"
+    done
+    for l in ru_RU ru_SU; do
+      echo "$l.KOI8-R KOI8-R"
+      echo "$l.ISO_8859-5 ISO-8859-5"
+      echo "$l.CP866 CP866"
+    done
+    echo "uk_UA.KOI8-U KOI8-U"
+    echo "zh_TW.BIG5 BIG5"
+    echo "zh_TW.Big5 BIG5"
+    echo "zh_CN.EUC GB2312"
+    echo "ja_JP.EUC EUC-JP"
+    echo "ja_JP.SJIS SHIFT_JIS"
+    echo "ja_JP.Shift_JIS SHIFT_JIS"
+    echo "ko_KR.EUC EUC-KR"
+    ;;
+  netbsd*)
+    echo "646 ASCII"
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-4 ISO-8859-4"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-13 ISO-8859-13"
+    echo "ISO8859-15 ISO-8859-15"
+    echo "eucCN GB2312"
+    echo "eucJP EUC-JP"
+    echo "eucKR EUC-KR"
+    echo "eucTW EUC-TW"
+    echo "BIG5 BIG5"
+    echo "SJIS SHIFT_JIS"
+    ;;
+  openbsd*)
+    echo "646 ASCII"
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-4 ISO-8859-4"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-13 ISO-8859-13"
+    echo "ISO8859-15 ISO-8859-15"
+    ;;
+  darwin[56]*)
+    # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore
+    # localcharset.c falls back to using the full locale name
+    # from the environment variables.
+    echo "C ASCII"
+    for l in en_AU en_CA en_GB en_US la_LN; do
+      echo "$l.US-ASCII ASCII"
+    done
+    for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \
+             fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \
+             nl_NL no_NO pt_PT sv_SE; do
+      echo "$l ISO-8859-1"
+      echo "$l.ISO8859-1 ISO-8859-1"
+      echo "$l.ISO8859-15 ISO-8859-15"
+    done
+    for l in la_LN; do
+      echo "$l.ISO8859-1 ISO-8859-1"
+      echo "$l.ISO8859-15 ISO-8859-15"
+    done
+    for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do
+      echo "$l.ISO8859-2 ISO-8859-2"
+    done
+    for l in la_LN lt_LT; do
+      echo "$l.ISO8859-4 ISO-8859-4"
+    done
+    for l in ru_RU; do
+      echo "$l.KOI8-R KOI8-R"
+      echo "$l.ISO8859-5 ISO-8859-5"
+      echo "$l.CP866 CP866"
+    done
+    for l in bg_BG; do
+      echo "$l.CP1251 CP1251"
+    done
+    echo "uk_UA.KOI8-U KOI8-U"
+    echo "zh_TW.BIG5 BIG5"
+    echo "zh_TW.Big5 BIG5"
+    echo "zh_CN.EUC GB2312"
+    echo "ja_JP.EUC EUC-JP"
+    echo "ja_JP.SJIS SHIFT_JIS"
+    echo "ko_KR.EUC EUC-KR"
+    ;;
+  darwin*)
+    # Darwin 7.5 has nl_langinfo(CODESET), but sometimes its value is
+    # useless:
+    # - It returns the empty string when LANG is set to a locale of the
+    #   form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8
+    #   LC_CTYPE file.
+    # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by
+    #   the system; nl_langinfo(CODESET) returns "US-ASCII" in this case.
+    # - The documentation says:
+    #     "... all code that calls BSD system routines should ensure
+    #      that the const *char parameters of these routines are in UTF-8
+    #      encoding. All BSD system functions expect their string
+    #      parameters to be in UTF-8 encoding and nothing else."
+    #   It also says
+    #     "An additional caveat is that string parameters for files,
+    #      paths, and other file-system entities must be in canonical
+    #      UTF-8. In a canonical UTF-8 Unicode string, all decomposable
+    #      characters are decomposed ..."
+    #   but this is not true: You can pass non-decomposed UTF-8 strings
+    #   to file system functions, and it is the OS which will convert
+    #   them to decomposed UTF-8 before accessing the file system.
+    # - The Apple Terminal application displays UTF-8 by default.
+    # - However, other applications are free to use different encodings:
+    #   - xterm uses ISO-8859-1 by default.
+    #   - TextEdit uses MacRoman by default.
+    # We prefer UTF-8 over decomposed UTF-8-MAC because one should
+    # minimize the use of decomposed Unicode. Unfortunately, through the
+    # Darwin file system, decomposed UTF-8 strings are leaked into user
+    # space nevertheless.
+    # Then there are also the locales with encodings other than US-ASCII
+    # and UTF-8. These locales can be occasionally useful to users (e.g.
+    # when grepping through ISO-8859-1 encoded text files), when all their
+    # file names are in US-ASCII.
+    echo "ISO8859-1 ISO-8859-1"
+    echo "ISO8859-2 ISO-8859-2"
+    echo "ISO8859-4 ISO-8859-4"
+    echo "ISO8859-5 ISO-8859-5"
+    echo "ISO8859-7 ISO-8859-7"
+    echo "ISO8859-9 ISO-8859-9"
+    echo "ISO8859-13 ISO-8859-13"
+    echo "ISO8859-15 ISO-8859-15"
+    echo "KOI8-R KOI8-R"
+    echo "KOI8-U KOI8-U"
+    echo "CP866 CP866"
+    echo "CP949 CP949"
+    echo "CP1131 CP1131"
+    echo "CP1251 CP1251"
+    echo "eucCN GB2312"
+    echo "GB2312 GB2312"
+    echo "eucJP EUC-JP"
+    echo "eucKR EUC-KR"
+    echo "Big5 BIG5"
+    echo "Big5HKSCS BIG5-HKSCS"
+    echo "GBK GBK"
+    echo "GB18030 GB18030"
+    echo "SJIS SHIFT_JIS"
+    echo "ARMSCII-8 ARMSCII-8"
+    echo "PT154 PT154"
+    #echo "ISCII-DEV ?"
+    echo "* UTF-8"
+    ;;
+  beos* | haiku*)
+    # BeOS and Haiku have a single locale, and it has UTF-8 encoding.
+    echo "* UTF-8"
+    ;;
+  msdosdjgpp*)
+    # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore
+    # localcharset.c falls back to using the full locale name
+    # from the environment variables.
+    echo "#"
+    echo "# The encodings given here may not all be correct."
+    echo "# If you find that the encoding given for your language and"
+    echo "# country is not the one your DOS machine actually uses, just"
+    echo "# correct it in this file, and send a mail to"
+    echo "# Juan Manuel Guerrero <juan.guerrero at gmx.de>"
+    echo "# and Bruno Haible <bruno at clisp.org>."
+    echo "#"
+    echo "C ASCII"
+    # ISO-8859-1 languages
+    echo "ca CP850"
+    echo "ca_ES CP850"
+    echo "da CP865"    # not CP850 ??
+    echo "da_DK CP865" # not CP850 ??
+    echo "de CP850"
+    echo "de_AT CP850"
+    echo "de_CH CP850"
+    echo "de_DE CP850"
+    echo "en CP850"
+    echo "en_AU CP850" # not CP437 ??
+    echo "en_CA CP850"
+    echo "en_GB CP850"
+    echo "en_NZ CP437"
+    echo "en_US CP437"
+    echo "en_ZA CP850" # not CP437 ??
+    echo "es CP850"
+    echo "es_AR CP850"
+    echo "es_BO CP850"
+    echo "es_CL CP850"
+    echo "es_CO CP850"
+    echo "es_CR CP850"
+    echo "es_CU CP850"
+    echo "es_DO CP850"
+    echo "es_EC CP850"
+    echo "es_ES CP850"
+    echo "es_GT CP850"
+    echo "es_HN CP850"
+    echo "es_MX CP850"
+    echo "es_NI CP850"
+    echo "es_PA CP850"
+    echo "es_PY CP850"
+    echo "es_PE CP850"
+    echo "es_SV CP850"
+    echo "es_UY CP850"
+    echo "es_VE CP850"
+    echo "et CP850"
+    echo "et_EE CP850"
+    echo "eu CP850"
+    echo "eu_ES CP850"
+    echo "fi CP850"
+    echo "fi_FI CP850"
+    echo "fr CP850"
+    echo "fr_BE CP850"
+    echo "fr_CA CP850"
+    echo "fr_CH CP850"
+    echo "fr_FR CP850"
+    echo "ga CP850"
+    echo "ga_IE CP850"
+    echo "gd CP850"
+    echo "gd_GB CP850"
+    echo "gl CP850"
+    echo "gl_ES CP850"
+    echo "id CP850"    # not CP437 ??
+    echo "id_ID CP850" # not CP437 ??
+    echo "is CP861"    # not CP850 ??
+    echo "is_IS CP861" # not CP850 ??
+    echo "it CP850"
+    echo "it_CH CP850"
+    echo "it_IT CP850"
+    echo "lt CP775"
+    echo "lt_LT CP775"
+    echo "lv CP775"
+    echo "lv_LV CP775"
+    echo "nb CP865"    # not CP850 ??
+    echo "nb_NO CP865" # not CP850 ??
+    echo "nl CP850"
+    echo "nl_BE CP850"
+    echo "nl_NL CP850"
+    echo "nn CP865"    # not CP850 ??
+    echo "nn_NO CP865" # not CP850 ??
+    echo "no CP865"    # not CP850 ??
+    echo "no_NO CP865" # not CP850 ??
+    echo "pt CP850"
+    echo "pt_BR CP850"
+    echo "pt_PT CP850"
+    echo "sv CP850"
+    echo "sv_SE CP850"
+    # ISO-8859-2 languages
+    echo "cs CP852"
+    echo "cs_CZ CP852"
+    echo "hr CP852"
+    echo "hr_HR CP852"
+    echo "hu CP852"
+    echo "hu_HU CP852"
+    echo "pl CP852"
+    echo "pl_PL CP852"
+    echo "ro CP852"
+    echo "ro_RO CP852"
+    echo "sk CP852"
+    echo "sk_SK CP852"
+    echo "sl CP852"
+    echo "sl_SI CP852"
+    echo "sq CP852"
+    echo "sq_AL CP852"
+    echo "sr CP852"    # CP852 or CP866 or CP855 ??
+    echo "sr_CS CP852" # CP852 or CP866 or CP855 ??
+    echo "sr_YU CP852" # CP852 or CP866 or CP855 ??
+    # ISO-8859-3 languages
+    echo "mt CP850"
+    echo "mt_MT CP850"
+    # ISO-8859-5 languages
+    echo "be CP866"
+    echo "be_BE CP866"
+    echo "bg CP866"    # not CP855 ??
+    echo "bg_BG CP866" # not CP855 ??
+    echo "mk CP866"    # not CP855 ??
+    echo "mk_MK CP866" # not CP855 ??
+    echo "ru CP866"
+    echo "ru_RU CP866"
+    echo "uk CP1125"
+    echo "uk_UA CP1125"
+    # ISO-8859-6 languages
+    echo "ar CP864"
+    echo "ar_AE CP864"
+    echo "ar_DZ CP864"
+    echo "ar_EG CP864"
+    echo "ar_IQ CP864"
+    echo "ar_IR CP864"
+    echo "ar_JO CP864"
+    echo "ar_KW CP864"
+    echo "ar_MA CP864"
+    echo "ar_OM CP864"
+    echo "ar_QA CP864"
+    echo "ar_SA CP864"
+    echo "ar_SY CP864"
+    # ISO-8859-7 languages
+    echo "el CP869"
+    echo "el_GR CP869"
+    # ISO-8859-8 languages
+    echo "he CP862"
+    echo "he_IL CP862"
+    # ISO-8859-9 languages
+    echo "tr CP857"
+    echo "tr_TR CP857"
+    # Japanese
+    echo "ja CP932"
+    echo "ja_JP CP932"
+    # Chinese
+    echo "zh_CN GBK"
+    echo "zh_TW CP950" # not CP938 ??
+    # Korean
+    echo "kr CP949"    # not CP934 ??
+    echo "kr_KR CP949" # not CP934 ??
+    # Thai
+    echo "th CP874"
+    echo "th_TH CP874"
+    # Other
+    echo "eo CP850"
+    echo "eo_EO CP850"
+    ;;
+esac
diff --git a/gl/gettext.h b/gl/gettext.h
new file mode 100644
index 0000000..db4df6b
--- /dev/null
+++ b/gl/gettext.h
@@ -0,0 +1,280 @@
+/* Convenience header for conditional use of GNU <libintl.h>.
+   Copyright (C) 1995-1998, 2000-2002, 2004-2006, 2009-2011 Free Software
+   Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+#ifndef _LIBGETTEXT_H
+#define _LIBGETTEXT_H 1
+
+/* NLS can be disabled through the configure --disable-nls option.  */
+#if ENABLE_NLS
+
+/* Get declarations of GNU message catalog functions.  */
+# include <libintl.h>
+
+/* You can set the DEFAULT_TEXT_DOMAIN macro to specify the domain used by
+   the gettext() and ngettext() macros.  This is an alternative to calling
+   textdomain(), and is useful for libraries.  */
+# ifdef DEFAULT_TEXT_DOMAIN
+#  undef gettext
+#  define gettext(Msgid) \
+     dgettext (DEFAULT_TEXT_DOMAIN, Msgid)
+#  undef ngettext
+#  define ngettext(Msgid1, Msgid2, N) \
+     dngettext (DEFAULT_TEXT_DOMAIN, Msgid1, Msgid2, N)
+# endif
+
+#else
+
+/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
+   chokes if dcgettext is defined as a macro.  So include it now, to make
+   later inclusions of <locale.h> a NOP.  We don't include <libintl.h>
+   as well because people using "gettext.h" will not include <libintl.h>,
+   and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
+   is OK.  */
+#if defined(__sun)
+# include <locale.h>
+#endif
+
+/* Many header files from the libstdc++ coming with g++ 3.3 or newer include
+   <libintl.h>, which chokes if dcgettext is defined as a macro.  So include
+   it now, to make later inclusions of <libintl.h> a NOP.  */
+#if defined(__cplusplus) && defined(__GNUG__) && (__GNUC__ >= 3)
+# include <cstdlib>
+# if (__GLIBC__ >= 2 && !defined __UCLIBC__) || _GLIBCXX_HAVE_LIBINTL_H
+#  include <libintl.h>
+# endif
+#endif
+
+/* Disabled NLS.
+   The casts to 'const char *' serve the purpose of producing warnings
+   for invalid uses of the value returned from these functions.
+   On pre-ANSI systems without 'const', the config.h file is supposed to
+   contain "#define const".  */
+# undef gettext
+# define gettext(Msgid) ((const char *) (Msgid))
+# undef dgettext
+# define dgettext(Domainname, Msgid) ((void) (Domainname), gettext (Msgid))
+# undef dcgettext
+# define dcgettext(Domainname, Msgid, Category) \
+    ((void) (Category), dgettext (Domainname, Msgid))
+# undef ngettext
+# define ngettext(Msgid1, Msgid2, N) \
+    ((N) == 1 \
+     ? ((void) (Msgid2), (const char *) (Msgid1)) \
+     : ((void) (Msgid1), (const char *) (Msgid2)))
+# undef dngettext
+# define dngettext(Domainname, Msgid1, Msgid2, N) \
+    ((void) (Domainname), ngettext (Msgid1, Msgid2, N))
+# undef dcngettext
+# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
+    ((void) (Category), dngettext (Domainname, Msgid1, Msgid2, N))
+# undef textdomain
+# define textdomain(Domainname) ((const char *) (Domainname))
+# undef bindtextdomain
+# define bindtextdomain(Domainname, Dirname) \
+    ((void) (Domainname), (const char *) (Dirname))
+# undef bind_textdomain_codeset
+# define bind_textdomain_codeset(Domainname, Codeset) \
+    ((void) (Domainname), (const char *) (Codeset))
+
+#endif
+
+/* A pseudo function call that serves as a marker for the automated
+   extraction of messages, but does not call gettext().  The run-time
+   translation is done at a different place in the code.
+   The argument, String, should be a literal string.  Concatenated strings
+   and other string expressions won't work.
+   The macro's expansion is not parenthesized, so that it is suitable as
+   initializer for static 'char[]' or 'const char[]' variables.  */
+#define gettext_noop(String) String
+
+/* The separator between msgctxt and msgid in a .mo file.  */
+#define GETTEXT_CONTEXT_GLUE "\004"
+
+/* Pseudo function calls, taking a MSGCTXT and a MSGID instead of just a
+   MSGID.  MSGCTXT and MSGID must be string literals.  MSGCTXT should be
+   short and rarely need to change.
+   The letter 'p' stands for 'particular' or 'special'.  */
+#ifdef DEFAULT_TEXT_DOMAIN
+# define pgettext(Msgctxt, Msgid) \
+   pgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#else
+# define pgettext(Msgctxt, Msgid) \
+   pgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#endif
+#define dpgettext(Domainname, Msgctxt, Msgid) \
+  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, LC_MESSAGES)
+#define dcpgettext(Domainname, Msgctxt, Msgid, Category) \
+  pgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, Category)
+#ifdef DEFAULT_TEXT_DOMAIN
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+   npgettext_aux (DEFAULT_TEXT_DOMAIN, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#else
+# define npgettext(Msgctxt, Msgid, MsgidPlural, N) \
+   npgettext_aux (NULL, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#endif
+#define dnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dcnpgettext(Domainname, Msgctxt, Msgid, MsgidPlural, N, Category) \
+  npgettext_aux (Domainname, Msgctxt GETTEXT_CONTEXT_GLUE Msgid, Msgid, MsgidPlural, N, Category)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+pgettext_aux (const char *domain,
+              const char *msg_ctxt_id, const char *msgid,
+              int category)
+{
+  const char *translation = dcgettext (domain, msg_ctxt_id, category);
+  if (translation == msg_ctxt_id)
+    return msgid;
+  else
+    return translation;
+}
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+npgettext_aux (const char *domain,
+               const char *msg_ctxt_id, const char *msgid,
+               const char *msgid_plural, unsigned long int n,
+               int category)
+{
+  const char *translation =
+    dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+  if (translation == msg_ctxt_id || translation == msgid_plural)
+    return (n == 1 ? msgid : msgid_plural);
+  else
+    return translation;
+}
+
+/* The same thing extended for non-constant arguments.  Here MSGCTXT and MSGID
+   can be arbitrary expressions.  But for string literals these macros are
+   less efficient than those above.  */
+
+#include <string.h>
+
+#define _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS \
+  (((__GNUC__ >= 3 || __GNUG__ >= 2) && !__STRICT_ANSI__) \
+   /* || __STDC_VERSION__ >= 199901L */ )
+
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+#include <stdlib.h>
+#endif
+
+#define pgettext_expr(Msgctxt, Msgid) \
+  dcpgettext_expr (NULL, Msgctxt, Msgid, LC_MESSAGES)
+#define dpgettext_expr(Domainname, Msgctxt, Msgid) \
+  dcpgettext_expr (Domainname, Msgctxt, Msgid, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcpgettext_expr (const char *domain,
+                 const char *msgctxt, const char *msgid,
+                 int category)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = dcgettext (domain, msg_ctxt_id, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+        free (msg_ctxt_id);
+#endif
+      if (translation != msg_ctxt_id)
+        return translation;
+    }
+  return msgid;
+}
+
+#define npgettext_expr(Msgctxt, Msgid, MsgidPlural, N) \
+  dcnpgettext_expr (NULL, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+#define dnpgettext_expr(Domainname, Msgctxt, Msgid, MsgidPlural, N) \
+  dcnpgettext_expr (Domainname, Msgctxt, Msgid, MsgidPlural, N, LC_MESSAGES)
+
+#ifdef __GNUC__
+__inline
+#else
+#ifdef __cplusplus
+inline
+#endif
+#endif
+static const char *
+dcnpgettext_expr (const char *domain,
+                  const char *msgctxt, const char *msgid,
+                  const char *msgid_plural, unsigned long int n,
+                  int category)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+#if _LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+  char msg_ctxt_id[msgctxt_len + msgid_len];
+#else
+  char buf[1024];
+  char *msg_ctxt_id =
+    (msgctxt_len + msgid_len <= sizeof (buf)
+     ? buf
+     : (char *) malloc (msgctxt_len + msgid_len));
+  if (msg_ctxt_id != NULL)
+#endif
+    {
+      memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+      msg_ctxt_id[msgctxt_len - 1] = '\004';
+      memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+      translation = dcngettext (domain, msg_ctxt_id, msgid_plural, n, category);
+#if !_LIBGETTEXT_HAVE_VARIABLE_SIZE_ARRAYS
+      if (msg_ctxt_id != buf)
+        free (msg_ctxt_id);
+#endif
+      if (!(translation == msg_ctxt_id || translation == msgid_plural))
+        return translation;
+    }
+  return (n == 1 ? msgid : msgid_plural);
+}
+
+#endif /* _LIBGETTEXT_H */
diff --git a/gl/iswblank.c b/gl/iswblank.c
new file mode 100644
index 0000000..c25f9b0
--- /dev/null
+++ b/gl/iswblank.c
@@ -0,0 +1,27 @@
+/* Test wide character for being blank.
+   Copyright (C) 2008-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <wctype.h>
+
+int
+iswblank (wint_t wc)
+{
+  return wc == ' ' || wc == '\t';
+}
diff --git a/gl/langinfo.in.h b/gl/langinfo.in.h
new file mode 100644
index 0000000..f829722
--- /dev/null
+++ b/gl/langinfo.in.h
@@ -0,0 +1,174 @@
+/* Substitute for and wrapper around <langinfo.h>.
+   Copyright (C) 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/*
+ * POSIX <langinfo.h> for platforms that lack it or have an incomplete one.
+ * <http://www.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>
+ */
+
+#ifndef _GL_LANGINFO_H
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_LANGINFO_H@
+# @INCLUDE_NEXT@ @NEXT_LANGINFO_H@
+#endif
+
+#ifndef _GL_LANGINFO_H
+#define _GL_LANGINFO_H
+
+
+#if !@HAVE_LANGINFO_H@
+
+/* A platform that lacks <langinfo.h>.  */
+
+/* Assume that it also lacks <nl_types.h> and the nl_item type.  */
+typedef int nl_item;
+
+/* nl_langinfo items of the LC_CTYPE category */
+# define CODESET     10000
+/* nl_langinfo items of the LC_NUMERIC category */
+# define RADIXCHAR   10001
+# define THOUSEP     10002
+/* nl_langinfo items of the LC_TIME category */
+# define D_T_FMT     10003
+# define D_FMT       10004
+# define T_FMT       10005
+# define T_FMT_AMPM  10006
+# define AM_STR      10007
+# define PM_STR      10008
+# define DAY_1       10009
+# define DAY_2       (DAY_1 + 1)
+# define DAY_3       (DAY_1 + 2)
+# define DAY_4       (DAY_1 + 3)
+# define DAY_5       (DAY_1 + 4)
+# define DAY_6       (DAY_1 + 5)
+# define DAY_7       (DAY_1 + 6)
+# define ABDAY_1     10016
+# define ABDAY_2     (ABDAY_1 + 1)
+# define ABDAY_3     (ABDAY_1 + 2)
+# define ABDAY_4     (ABDAY_1 + 3)
+# define ABDAY_5     (ABDAY_1 + 4)
+# define ABDAY_6     (ABDAY_1 + 5)
+# define ABDAY_7     (ABDAY_1 + 6)
+# define MON_1       10023
+# define MON_2       (MON_1 + 1)
+# define MON_3       (MON_1 + 2)
+# define MON_4       (MON_1 + 3)
+# define MON_5       (MON_1 + 4)
+# define MON_6       (MON_1 + 5)
+# define MON_7       (MON_1 + 6)
+# define MON_8       (MON_1 + 7)
+# define MON_9       (MON_1 + 8)
+# define MON_10      (MON_1 + 9)
+# define MON_11      (MON_1 + 10)
+# define MON_12      (MON_1 + 11)
+# define ABMON_1     10035
+# define ABMON_2     (ABMON_1 + 1)
+# define ABMON_3     (ABMON_1 + 2)
+# define ABMON_4     (ABMON_1 + 3)
+# define ABMON_5     (ABMON_1 + 4)
+# define ABMON_6     (ABMON_1 + 5)
+# define ABMON_7     (ABMON_1 + 6)
+# define ABMON_8     (ABMON_1 + 7)
+# define ABMON_9     (ABMON_1 + 8)
+# define ABMON_10    (ABMON_1 + 9)
+# define ABMON_11    (ABMON_1 + 10)
+# define ABMON_12    (ABMON_1 + 11)
+# define ERA         10047
+# define ERA_D_FMT   10048
+# define ERA_D_T_FMT 10049
+# define ERA_T_FMT   10050
+# define ALT_DIGITS  10051
+/* nl_langinfo items of the LC_MONETARY category */
+# define CRNCYSTR    10052
+/* nl_langinfo items of the LC_MESSAGES category */
+# define YESEXPR     10053
+# define NOEXPR      10054
+
+#else
+
+/* A platform that has <langinfo.h>.  */
+
+# if !@HAVE_LANGINFO_CODESET@
+#  define CODESET     10000
+#  define GNULIB_defined_CODESET 1
+# endif
+
+# if !@HAVE_LANGINFO_T_FMT_AMPM@
+#  define T_FMT_AMPM  10006
+#  define GNULIB_defined_T_FMT_AMPM 1
+# endif
+
+# if !@HAVE_LANGINFO_ERA@
+#  define ERA         10047
+#  define ERA_D_FMT   10048
+#  define ERA_D_T_FMT 10049
+#  define ERA_T_FMT   10050
+#  define ALT_DIGITS  10051
+#  define GNULIB_defined_ERA 1
+# endif
+
+# if !@HAVE_LANGINFO_YESEXPR@
+#  define YESEXPR     10053
+#  define NOEXPR      10054
+#  define GNULIB_defined_YESEXPR 1
+# endif
+
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* Declare overridden functions.  */
+
+
+/* Return a piece of locale dependent information.
+   Note: The difference between nl_langinfo (CODESET) and locale_charset ()
+   is that the latter normalizes the encoding names to GNU conventions.  */
+
+#if @GNULIB_NL_LANGINFO@
+# if @REPLACE_NL_LANGINFO@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef nl_langinfo
+#   define nl_langinfo rpl_nl_langinfo
+#  endif
+_GL_FUNCDECL_RPL (nl_langinfo, char *, (nl_item item));
+_GL_CXXALIAS_RPL (nl_langinfo, char *, (nl_item item));
+# else
+#  if !@HAVE_NL_LANGINFO@
+_GL_FUNCDECL_SYS (nl_langinfo, char *, (nl_item item));
+#  endif
+_GL_CXXALIAS_SYS (nl_langinfo, char *, (nl_item item));
+# endif
+_GL_CXXALIASWARN (nl_langinfo);
+#elif defined GNULIB_POSIXCHECK
+# undef nl_langinfo
+# if HAVE_RAW_DECL_NL_LANGINFO
+_GL_WARN_ON_USE (nl_langinfo, "nl_langinfo is not portable - "
+                 "use gnulib module nl_langinfo for portability");
+# endif
+#endif
+
+
+#endif /* _GL_LANGINFO_H */
+#endif /* _GL_LANGINFO_H */
diff --git a/gl/localcharset.c b/gl/localcharset.c
new file mode 100644
index 0000000..6460a2d
--- /dev/null
+++ b/gl/localcharset.c
@@ -0,0 +1,548 @@
+/* Determine a canonical name for the current locale's character encoding.
+
+   Copyright (C) 2000-2006, 2008-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/* Written by Bruno Haible <bruno at clisp.org>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "localcharset.h"
+
+#include <fcntl.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET
+# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */
+#endif
+
+#if defined _WIN32 || defined __WIN32__
+# define WIN32_NATIVE
+#endif
+
+#if defined __EMX__
+/* Assume EMX program runs on OS/2, even if compiled under DOS.  */
+# ifndef OS2
+#  define OS2
+# endif
+#endif
+
+#if !defined WIN32_NATIVE
+# include <unistd.h>
+# if HAVE_LANGINFO_CODESET
+#  include <langinfo.h>
+# else
+#  if 0 /* see comment below */
+#   include <locale.h>
+#  endif
+# endif
+# ifdef __CYGWIN__
+#  define WIN32_LEAN_AND_MEAN
+#  include <windows.h>
+# endif
+#elif defined WIN32_NATIVE
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+#if defined OS2
+# define INCL_DOS
+# include <os2.h>
+#endif
+
+#if ENABLE_RELOCATABLE
+# include "relocatable.h"
+#else
+# define relocate(pathname) (pathname)
+#endif
+
+/* Get LIBDIR.  */
+#ifndef LIBDIR
+# include "configmake.h"
+#endif
+
+/* Define O_NOFOLLOW to 0 on platforms where it does not exist.  */
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
+  /* Win32, Cygwin, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#endif
+
+#ifndef DIRECTORY_SEPARATOR
+# define DIRECTORY_SEPARATOR '/'
+#endif
+
+#ifndef ISSLASH
+# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
+#endif
+
+#if HAVE_DECL_GETC_UNLOCKED
+# undef getc
+# define getc getc_unlocked
+#endif
+
+/* The following static variable is declared 'volatile' to avoid a
+   possible multithread problem in the function get_charset_aliases. If we
+   are running in a threaded environment, and if two threads initialize
+   'charset_aliases' simultaneously, both will produce the same value,
+   and everything will be ok if the two assignments to 'charset_aliases'
+   are atomic. But I don't know what will happen if the two assignments mix.  */
+#if __STDC__ != 1
+# define volatile /* empty */
+#endif
+/* Pointer to the contents of the charset.alias file, if it has already been
+   read, else NULL.  Its format is:
+   ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0'  */
+static const char * volatile charset_aliases;
+
+/* Return a pointer to the contents of the charset.alias file.  */
+static const char *
+get_charset_aliases (void)
+{
+  const char *cp;
+
+  cp = charset_aliases;
+  if (cp == NULL)
+    {
+#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__)
+      const char *dir;
+      const char *base = "charset.alias";
+      char *file_name;
+
+      /* Make it possible to override the charset.alias location.  This is
+         necessary for running the testsuite before "make install".  */
+      dir = getenv ("CHARSETALIASDIR");
+      if (dir == NULL || dir[0] == '\0')
+        dir = relocate (LIBDIR);
+
+      /* Concatenate dir and base into freshly allocated file_name.  */
+      {
+        size_t dir_len = strlen (dir);
+        size_t base_len = strlen (base);
+        int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
+        file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
+        if (file_name != NULL)
+          {
+            memcpy (file_name, dir, dir_len);
+            if (add_slash)
+              file_name[dir_len] = DIRECTORY_SEPARATOR;
+            memcpy (file_name + dir_len + add_slash, base, base_len + 1);
+          }
+      }
+
+      if (file_name == NULL)
+        /* Out of memory.  Treat the file as empty.  */
+        cp = "";
+      else
+        {
+          int fd;
+
+          /* Open the file.  Reject symbolic links on platforms that support
+             O_NOFOLLOW.  This is a security feature.  Without it, an attacker
+             could retrieve parts of the contents (namely, the tail of the
+             first line that starts with "* ") of an arbitrary file by placing
+             a symbolic link to that file under the name "charset.alias" in
+             some writable directory and defining the environment variable
+             CHARSETALIASDIR to point to that directory.  */
+          fd = open (file_name,
+                     O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0));
+          if (fd < 0)
+            /* File not found.  Treat it as empty.  */
+            cp = "";
+          else
+            {
+              FILE *fp;
+
+              fp = fdopen (fd, "r");
+              if (fp == NULL)
+                {
+                  /* Out of memory.  Treat the file as empty.  */
+                  close (fd);
+                  cp = "";
+                }
+              else
+                {
+                  /* Parse the file's contents.  */
+                  char *res_ptr = NULL;
+                  size_t res_size = 0;
+
+                  for (;;)
+                    {
+                      int c;
+                      char buf1[50+1];
+                      char buf2[50+1];
+                      size_t l1, l2;
+                      char *old_res_ptr;
+
+                      c = getc (fp);
+                      if (c == EOF)
+                        break;
+                      if (c == '\n' || c == ' ' || c == '\t')
+                        continue;
+                      if (c == '#')
+                        {
+                          /* Skip comment, to end of line.  */
+                          do
+                            c = getc (fp);
+                          while (!(c == EOF || c == '\n'));
+                          if (c == EOF)
+                            break;
+                          continue;
+                        }
+                      ungetc (c, fp);
+                      if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
+                        break;
+                      l1 = strlen (buf1);
+                      l2 = strlen (buf2);
+                      old_res_ptr = res_ptr;
+                      if (res_size == 0)
+                        {
+                          res_size = l1 + 1 + l2 + 1;
+                          res_ptr = (char *) malloc (res_size + 1);
+                        }
+                      else
+                        {
+                          res_size += l1 + 1 + l2 + 1;
+                          res_ptr = (char *) realloc (res_ptr, res_size + 1);
+                        }
+                      if (res_ptr == NULL)
+                        {
+                          /* Out of memory. */
+                          res_size = 0;
+                          if (old_res_ptr != NULL)
+                            free (old_res_ptr);
+                          break;
+                        }
+                      strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
+                      strcpy (res_ptr + res_size - (l2 + 1), buf2);
+                    }
+                  fclose (fp);
+                  if (res_size == 0)
+                    cp = "";
+                  else
+                    {
+                      *(res_ptr + res_size) = '\0';
+                      cp = res_ptr;
+                    }
+                }
+            }
+
+          free (file_name);
+        }
+
+#else
+
+# if defined DARWIN7
+      /* To avoid the trouble of installing a file that is shared by many
+         GNU packages -- many packaging systems have problems with this --,
+         simply inline the aliases here.  */
+      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
+           "ISO8859-2" "\0" "ISO-8859-2" "\0"
+           "ISO8859-4" "\0" "ISO-8859-4" "\0"
+           "ISO8859-5" "\0" "ISO-8859-5" "\0"
+           "ISO8859-7" "\0" "ISO-8859-7" "\0"
+           "ISO8859-9" "\0" "ISO-8859-9" "\0"
+           "ISO8859-13" "\0" "ISO-8859-13" "\0"
+           "ISO8859-15" "\0" "ISO-8859-15" "\0"
+           "KOI8-R" "\0" "KOI8-R" "\0"
+           "KOI8-U" "\0" "KOI8-U" "\0"
+           "CP866" "\0" "CP866" "\0"
+           "CP949" "\0" "CP949" "\0"
+           "CP1131" "\0" "CP1131" "\0"
+           "CP1251" "\0" "CP1251" "\0"
+           "eucCN" "\0" "GB2312" "\0"
+           "GB2312" "\0" "GB2312" "\0"
+           "eucJP" "\0" "EUC-JP" "\0"
+           "eucKR" "\0" "EUC-KR" "\0"
+           "Big5" "\0" "BIG5" "\0"
+           "Big5HKSCS" "\0" "BIG5-HKSCS" "\0"
+           "GBK" "\0" "GBK" "\0"
+           "GB18030" "\0" "GB18030" "\0"
+           "SJIS" "\0" "SHIFT_JIS" "\0"
+           "ARMSCII-8" "\0" "ARMSCII-8" "\0"
+           "PT154" "\0" "PT154" "\0"
+         /*"ISCII-DEV" "\0" "?" "\0"*/
+           "*" "\0" "UTF-8" "\0";
+# endif
+
+# if defined VMS
+      /* To avoid the troubles of an extra file charset.alias_vms in the
+         sources of many GNU packages, simply inline the aliases here.  */
+      /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
+         "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
+         section 10.7 "Handling Different Character Sets".  */
+      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
+           "ISO8859-2" "\0" "ISO-8859-2" "\0"
+           "ISO8859-5" "\0" "ISO-8859-5" "\0"
+           "ISO8859-7" "\0" "ISO-8859-7" "\0"
+           "ISO8859-8" "\0" "ISO-8859-8" "\0"
+           "ISO8859-9" "\0" "ISO-8859-9" "\0"
+           /* Japanese */
+           "eucJP" "\0" "EUC-JP" "\0"
+           "SJIS" "\0" "SHIFT_JIS" "\0"
+           "DECKANJI" "\0" "DEC-KANJI" "\0"
+           "SDECKANJI" "\0" "EUC-JP" "\0"
+           /* Chinese */
+           "eucTW" "\0" "EUC-TW" "\0"
+           "DECHANYU" "\0" "DEC-HANYU" "\0"
+           "DECHANZI" "\0" "GB2312" "\0"
+           /* Korean */
+           "DECKOREAN" "\0" "EUC-KR" "\0";
+# endif
+
+# if defined WIN32_NATIVE || defined __CYGWIN__
+      /* To avoid the troubles of installing a separate file in the same
+         directory as the DLL and of retrieving the DLL's directory at
+         runtime, simply inline the aliases here.  */
+
+      cp = "CP936" "\0" "GBK" "\0"
+           "CP1361" "\0" "JOHAB" "\0"
+           "CP20127" "\0" "ASCII" "\0"
+           "CP20866" "\0" "KOI8-R" "\0"
+           "CP20936" "\0" "GB2312" "\0"
+           "CP21866" "\0" "KOI8-RU" "\0"
+           "CP28591" "\0" "ISO-8859-1" "\0"
+           "CP28592" "\0" "ISO-8859-2" "\0"
+           "CP28593" "\0" "ISO-8859-3" "\0"
+           "CP28594" "\0" "ISO-8859-4" "\0"
+           "CP28595" "\0" "ISO-8859-5" "\0"
+           "CP28596" "\0" "ISO-8859-6" "\0"
+           "CP28597" "\0" "ISO-8859-7" "\0"
+           "CP28598" "\0" "ISO-8859-8" "\0"
+           "CP28599" "\0" "ISO-8859-9" "\0"
+           "CP28605" "\0" "ISO-8859-15" "\0"
+           "CP38598" "\0" "ISO-8859-8" "\0"
+           "CP51932" "\0" "EUC-JP" "\0"
+           "CP51936" "\0" "GB2312" "\0"
+           "CP51949" "\0" "EUC-KR" "\0"
+           "CP51950" "\0" "EUC-TW" "\0"
+           "CP54936" "\0" "GB18030" "\0"
+           "CP65001" "\0" "UTF-8" "\0";
+# endif
+#endif
+
+      charset_aliases = cp;
+    }
+
+  return cp;
+}
+
+/* Determine the current locale's character encoding, and canonicalize it
+   into one of the canonical names listed in config.charset.
+   The result must not be freed; it is statically allocated.
+   If the canonical name cannot be determined, the result is a non-canonical
+   name.  */
+
+#ifdef STATIC
+STATIC
+#endif
+const char *
+locale_charset (void)
+{
+  const char *codeset;
+  const char *aliases;
+
+#if !(defined WIN32_NATIVE || defined OS2)
+
+# if HAVE_LANGINFO_CODESET
+
+  /* Most systems support nl_langinfo (CODESET) nowadays.  */
+  codeset = nl_langinfo (CODESET);
+
+#  ifdef __CYGWIN__
+  /* Cygwin < 1.7 does not have locales.  nl_langinfo (CODESET) always
+     returns "US-ASCII".  Return the suffix of the locale name from the
+     environment variables (if present) or the codepage as a number.  */
+  if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
+    {
+      const char *locale;
+      static char buf[2 + 10 + 1];
+
+      locale = getenv ("LC_ALL");
+      if (locale == NULL || locale[0] == '\0')
+        {
+          locale = getenv ("LC_CTYPE");
+          if (locale == NULL || locale[0] == '\0')
+            locale = getenv ("LANG");
+        }
+      if (locale != NULL && locale[0] != '\0')
+        {
+          /* If the locale name contains an encoding after the dot, return
+             it.  */
+          const char *dot = strchr (locale, '.');
+
+          if (dot != NULL)
+            {
+              const char *modifier;
+
+              dot++;
+              /* Look for the possible @... trailer and remove it, if any.  */
+              modifier = strchr (dot, '@');
+              if (modifier == NULL)
+                return dot;
+              if (modifier - dot < sizeof (buf))
+                {
+                  memcpy (buf, dot, modifier - dot);
+                  buf [modifier - dot] = '\0';
+                  return buf;
+                }
+            }
+        }
+
+      /* Woe32 has a function returning the locale's codepage as a number:
+         GetACP().  This encoding is used by Cygwin, unless the user has set
+         the environment variable CYGWIN=codepage:oem (which very few people
+         do).
+         Output directed to console windows needs to be converted (to
+         GetOEMCP() if the console is using a raster font, or to
+         GetConsoleOutputCP() if it is using a TrueType font).  Cygwin does
+         this conversion transparently (see winsup/cygwin/fhandler_console.cc),
+         converting to GetConsoleOutputCP().  This leads to correct results,
+         except when SetConsoleOutputCP has been called and a raster font is
+         in use.  */
+      sprintf (buf, "CP%u", GetACP ());
+      codeset = buf;
+    }
+#  endif
+
+# else
+
+  /* On old systems which lack it, use setlocale or getenv.  */
+  const char *locale = NULL;
+
+  /* But most old systems don't have a complete set of locales.  Some
+     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
+     use setlocale here; it would return "C" when it doesn't support the
+     locale name the user has set.  */
+#  if 0
+  locale = setlocale (LC_CTYPE, NULL);
+#  endif
+  if (locale == NULL || locale[0] == '\0')
+    {
+      locale = getenv ("LC_ALL");
+      if (locale == NULL || locale[0] == '\0')
+        {
+          locale = getenv ("LC_CTYPE");
+          if (locale == NULL || locale[0] == '\0')
+            locale = getenv ("LANG");
+        }
+    }
+
+  /* On some old systems, one used to set locale = "iso8859_1". On others,
+     you set it to "language_COUNTRY.charset". In any case, we resolve it
+     through the charset.alias file.  */
+  codeset = locale;
+
+# endif
+
+#elif defined WIN32_NATIVE
+
+  static char buf[2 + 10 + 1];
+
+  /* Woe32 has a function returning the locale's codepage as a number:
+     GetACP().
+     When the output goes to a console window, it needs to be provided in
+     GetOEMCP() encoding if the console is using a raster font, or in
+     GetConsoleOutputCP() encoding if it is using a TrueType font.
+     But in GUI programs and for output sent to files and pipes, GetACP()
+     encoding is the best bet.  */
+  sprintf (buf, "CP%u", GetACP ());
+  codeset = buf;
+
+#elif defined OS2
+
+  const char *locale;
+  static char buf[2 + 10 + 1];
+  ULONG cp[3];
+  ULONG cplen;
+
+  /* Allow user to override the codeset, as set in the operating system,
+     with standard language environment variables.  */
+  locale = getenv ("LC_ALL");
+  if (locale == NULL || locale[0] == '\0')
+    {
+      locale = getenv ("LC_CTYPE");
+      if (locale == NULL || locale[0] == '\0')
+        locale = getenv ("LANG");
+    }
+  if (locale != NULL && locale[0] != '\0')
+    {
+      /* If the locale name contains an encoding after the dot, return it.  */
+      const char *dot = strchr (locale, '.');
+
+      if (dot != NULL)
+        {
+          const char *modifier;
+
+          dot++;
+          /* Look for the possible @... trailer and remove it, if any.  */
+          modifier = strchr (dot, '@');
+          if (modifier == NULL)
+            return dot;
+          if (modifier - dot < sizeof (buf))
+            {
+              memcpy (buf, dot, modifier - dot);
+              buf [modifier - dot] = '\0';
+              return buf;
+            }
+        }
+
+      /* Resolve through the charset.alias file.  */
+      codeset = locale;
+    }
+  else
+    {
+      /* OS/2 has a function returning the locale's codepage as a number.  */
+      if (DosQueryCp (sizeof (cp), cp, &cplen))
+        codeset = "";
+      else
+        {
+          sprintf (buf, "CP%u", cp[0]);
+          codeset = buf;
+        }
+    }
+
+#endif
+
+  if (codeset == NULL)
+    /* The canonical name cannot be determined.  */
+    codeset = "";
+
+  /* Resolve alias. */
+  for (aliases = get_charset_aliases ();
+       *aliases != '\0';
+       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
+    if (strcmp (codeset, aliases) == 0
+        || (aliases[0] == '*' && aliases[1] == '\0'))
+      {
+        codeset = aliases + strlen (aliases) + 1;
+        break;
+      }
+
+  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
+     the empty string as denoting "the locale's character encoding",
+     thus GNU libiconv would call this function a second time.  */
+  if (codeset[0] == '\0')
+    codeset = "ASCII";
+
+  return codeset;
+}
diff --git a/gl/localcharset.h b/gl/localcharset.h
new file mode 100644
index 0000000..97a43e7
--- /dev/null
+++ b/gl/localcharset.h
@@ -0,0 +1,41 @@
+/* Determine a canonical name for the current locale's character encoding.
+   Copyright (C) 2000-2003, 2009-2011 Free Software Foundation, Inc.
+   This file is part of the GNU CHARSET Library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+#ifndef _LOCALCHARSET_H
+#define _LOCALCHARSET_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Determine the current locale's character encoding, and canonicalize it
+   into one of the canonical names listed in config.charset.
+   The result must not be freed; it is statically allocated.
+   If the canonical name cannot be determined, the result is a non-canonical
+   name.  */
+extern const char * locale_charset (void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _LOCALCHARSET_H */
diff --git a/gl/m4/00gnulib.m4 b/gl/m4/00gnulib.m4
new file mode 100644
index 0000000..7feed46
--- /dev/null
+++ b/gl/m4/00gnulib.m4
@@ -0,0 +1,30 @@
+# 00gnulib.m4 serial 2
+dnl Copyright (C) 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This file must be named something that sorts before all other
+dnl gnulib-provided .m4 files.  It is needed until such time as we can
+dnl assume Autoconf 2.64, with its improved AC_DEFUN_ONCE semantics.
+
+# AC_DEFUN_ONCE([NAME], VALUE)
+# ----------------------------
+# Define NAME to expand to VALUE on the first use (whether by direct
+# expansion, or by AC_REQUIRE), and to nothing on all subsequent uses.
+# Avoid bugs in AC_REQUIRE in Autoconf 2.63 and earlier.  This
+# definition is slower than the version in Autoconf 2.64, because it
+# can only use interfaces that existed since 2.59; but it achieves the
+# same effect.  Quoting is necessary to avoid confusing Automake.
+m4_version_prereq([2.63.263], [],
+[m4_define([AC][_DEFUN_ONCE],
+  [AC][_DEFUN([$1],
+    [AC_REQUIRE([_gl_DEFUN_ONCE([$1])],
+      [m4_indir([_gl_DEFUN_ONCE([$1])])])])]dnl
+[AC][_DEFUN([_gl_DEFUN_ONCE([$1])], [$2])])])
+
+# gl_00GNULIB
+# -----------
+# Witness macro that this file has been included.  Needed to force
+# Automake to include this file prior to all other gnulib .m4 files.
+AC_DEFUN([gl_00GNULIB])
diff --git a/gl/m4/alloca.m4 b/gl/m4/alloca.m4
new file mode 100644
index 0000000..e2e8a05
--- /dev/null
+++ b/gl/m4/alloca.m4
@@ -0,0 +1,43 @@
+# alloca.m4 serial 10
+dnl Copyright (C) 2002-2004, 2006-2007, 2009-2011 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_ALLOCA],
+[
+  AC_REQUIRE([AC_FUNC_ALLOCA])
+  if test $ac_cv_func_alloca_works = no; then
+    gl_PREREQ_ALLOCA
+  fi
+
+  # Define an additional variable used in the Makefile substitution.
+  if test $ac_cv_working_alloca_h = yes; then
+    AC_CACHE_CHECK([for alloca as a compiler built-in], [gl_cv_rpl_alloca], [
+      AC_EGREP_CPP([Need own alloca], [
+#if defined __GNUC__ || defined _AIX || defined _MSC_VER
+        Need own alloca
+#endif
+        ], [gl_cv_rpl_alloca=yes], [gl_cv_rpl_alloca=no])
+    ])
+    if test $gl_cv_rpl_alloca = yes; then
+      dnl OK, alloca can be implemented through a compiler built-in.
+      AC_DEFINE([HAVE_ALLOCA], [1],
+        [Define to 1 if you have 'alloca' after including <alloca.h>,
+         a header that may be supplied by this distribution.])
+      ALLOCA_H=alloca.h
+    else
+      dnl alloca exists as a library function, i.e. it is slow and probably
+      dnl a memory leak. Don't define HAVE_ALLOCA in this case.
+      ALLOCA_H=
+    fi
+  else
+    ALLOCA_H=alloca.h
+  fi
+  AC_SUBST([ALLOCA_H])
+])
+
+# Prerequisites of lib/alloca.c.
+# STACK_DIRECTION is already handled by AC_FUNC_ALLOCA.
+AC_DEFUN([gl_PREREQ_ALLOCA], [:])
diff --git a/gl/m4/btowc.m4 b/gl/m4/btowc.m4
new file mode 100644
index 0000000..603298f
--- /dev/null
+++ b/gl/m4/btowc.m4
@@ -0,0 +1,121 @@
+# btowc.m4 serial 8
+dnl Copyright (C) 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_BTOWC],
+[
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+
+  dnl Check whether <wchar.h> is usable at all, first. Otherwise the test
+  dnl program below may lead to an endless loop. See
+  dnl <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42440>.
+  AC_REQUIRE([gl_WCHAR_H_INLINE_OK])
+
+  AC_CHECK_FUNCS_ONCE([btowc])
+  if test $ac_cv_func_btowc = no; then
+    HAVE_BTOWC=0
+  else
+
+    AC_REQUIRE([AC_PROG_CC])
+    AC_REQUIRE([gt_LOCALE_FR])
+    AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+
+    dnl Cygwin 1.7.2 btowc('\0') is WEOF, not 0.
+    AC_CACHE_CHECK([whether btowc(0) is correct],
+      [gl_cv_func_btowc_nul],
+      [
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (btowc ('\0') != 0)
+    return 1;
+  return 0;
+}]])],
+          [gl_cv_func_btowc_nul=yes],
+          [gl_cv_func_btowc_nul=no],
+          [
+changequote(,)dnl
+           case "$host_os" in
+                      # Guess no on Cygwin.
+             cygwin*) gl_cv_func_btowc_nul="guessing no" ;;
+                      # Guess yes otherwise.
+             *)       gl_cv_func_btowc_nul="guessing yes" ;;
+           esac
+changequote([,])dnl
+          ])
+      ])
+
+    dnl IRIX 6.5 btowc(EOF) is 0xFF, not WEOF.
+    AC_CACHE_CHECK([whether btowc(EOF) is correct],
+      [gl_cv_func_btowc_eof],
+      [
+        dnl Initial guess, used when cross-compiling or when no suitable locale
+        dnl is present.
+changequote(,)dnl
+        case "$host_os" in
+                 # Guess no on IRIX.
+          irix*) gl_cv_func_btowc_eof="guessing no" ;;
+                 # Guess yes otherwise.
+          *)     gl_cv_func_btowc_eof="guessing yes" ;;
+        esac
+changequote([,])dnl
+        if test $LOCALE_FR != none; then
+          AC_RUN_IFELSE(
+            [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_FR") != NULL)
+    {
+      if (btowc (EOF) != WEOF)
+        return 1;
+    }
+  return 0;
+}]])],
+            [gl_cv_func_btowc_eof=yes],
+            [gl_cv_func_btowc_eof=no],
+            [:])
+        fi
+      ])
+
+    case "$gl_cv_func_btowc_nul" in
+      *yes) ;;
+      *) REPLACE_BTOWC=1 ;;
+    esac
+    case "$gl_cv_func_btowc_eof" in
+      *yes) ;;
+      *) REPLACE_BTOWC=1 ;;
+    esac
+  fi
+  if test $HAVE_BTOWC = 0 || test $REPLACE_BTOWC = 1; then
+    gl_REPLACE_WCHAR_H
+    AC_LIBOBJ([btowc])
+    gl_PREREQ_BTOWC
+  fi
+])
+
+# Prerequisites of lib/btowc.c.
+AC_DEFUN([gl_PREREQ_BTOWC], [
+  :
+])
diff --git a/gl/m4/codeset.m4 b/gl/m4/codeset.m4
new file mode 100644
index 0000000..da73552
--- /dev/null
+++ b/gl/m4/codeset.m4
@@ -0,0 +1,23 @@
+# codeset.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 2000-2002, 2006, 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_LANGINFO_CODESET],
+[
+  AC_CACHE_CHECK([for nl_langinfo and CODESET], [am_cv_langinfo_codeset],
+    [AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <langinfo.h>]],
+          [[char* cs = nl_langinfo(CODESET); return !cs;]])],
+       [am_cv_langinfo_codeset=yes],
+       [am_cv_langinfo_codeset=no])
+    ])
+  if test $am_cv_langinfo_codeset = yes; then
+    AC_DEFINE([HAVE_LANGINFO_CODESET], [1],
+      [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
+  fi
+])
diff --git a/gl/m4/configmake.m4 b/gl/m4/configmake.m4
new file mode 100644
index 0000000..a029823
--- /dev/null
+++ b/gl/m4/configmake.m4
@@ -0,0 +1,50 @@
+# configmake.m4 serial 1
+dnl Copyright (C) 2010-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# gl_CONFIGMAKE_PREP
+# ------------------
+# Guarantee all of the standard directory variables, even when used with
+# autoconf 2.59 (datarootdir wasn't supported until 2.59c) or automake
+# 1.9.6 (pkglibexecdir wasn't supported until 1.10b.).
+AC_DEFUN([gl_CONFIGMAKE_PREP],
+[
+  dnl Technically, datadir should default to datarootdir.  But if
+  dnl autoconf is too old to provide datarootdir, then reversing the
+  dnl definition is a reasonable compromise.  Only AC_SUBST a variable
+  dnl if it was not already defined earlier by autoconf.
+  if test "x$datarootdir" = x; then
+    AC_SUBST([datarootdir], ['${datadir}'])
+  fi
+  dnl Copy the approach used in autoconf 2.60.
+  if test "x$docdir" = x; then
+    AC_SUBST([docdir], [m4_ifset([AC_PACKAGE_TARNAME],
+      ['${datarootdir}/doc/${PACKAGE_TARNAME}'],
+      ['${datarootdir}/doc/${PACKAGE}'])])
+  fi
+  dnl The remaining variables missing from autoconf 2.59 are easier.
+  if test "x$htmldir" = x; then
+    AC_SUBST([htmldir], ['${docdir}'])
+  fi
+  if test "x$dvidir" = x; then
+    AC_SUBST([dvidir], ['${docdir}'])
+  fi
+  if test "x$pdfdir" = x; then
+    AC_SUBST([pdfdir], ['${docdir}'])
+  fi
+  if test "x$psdir" = x; then
+    AC_SUBST([psdir], ['${docdir}'])
+  fi
+  if test "x$lispdir" = x; then
+    AC_SUBST([lispdir], ['${datarootdir}/emacs/site-lisp'])
+  fi
+  if test "x$localedir" = x; then
+    AC_SUBST([localedir], ['${datarootdir}/locale'])
+  fi
+
+  dnl Automake 1.9.6 only lacks pkglibexecdir; and since 1.11 merely
+  dnl provides it without AC_SUBST, this blind use of AC_SUBST is safe.
+  AC_SUBST([pkglibexecdir], ['${libexecdir}/${PACKAGE}'])
+])
diff --git a/gl/m4/extensions.m4 b/gl/m4/extensions.m4
new file mode 100644
index 0000000..1330503
--- /dev/null
+++ b/gl/m4/extensions.m4
@@ -0,0 +1,118 @@
+# serial 9  -*- Autoconf -*-
+# Enable extensions on systems that normally disable them.
+
+# Copyright (C) 2003, 2006-2011 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This definition of AC_USE_SYSTEM_EXTENSIONS is stolen from CVS
+# Autoconf.  Perhaps we can remove this once we can assume Autoconf
+# 2.62 or later everywhere, but since CVS Autoconf mutates rapidly
+# enough in this area it's likely we'll need to redefine
+# AC_USE_SYSTEM_EXTENSIONS for quite some time.
+
+# If autoconf reports a warning
+#     warning: AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
+# or  warning: AC_RUN_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS
+# the fix is
+#   1) to ensure that AC_USE_SYSTEM_EXTENSIONS is never directly invoked
+#      but always AC_REQUIREd,
+#   2) to ensure that for each occurrence of
+#        AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+#      or
+#        AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+#      the corresponding gnulib module description has 'extensions' among
+#      its dependencies. This will ensure that the gl_USE_SYSTEM_EXTENSIONS
+#      invocation occurs in gl_EARLY, not in gl_INIT.
+
+# AC_USE_SYSTEM_EXTENSIONS
+# ------------------------
+# Enable extensions on systems that normally disable them,
+# typically due to standards-conformance issues.
+# Remember that #undef in AH_VERBATIM gets replaced with #define by
+# AC_DEFINE.  The goal here is to define all known feature-enabling
+# macros, then, if reports of conflicts are made, disable macros that
+# cause problems on some platforms (such as __EXTENSIONS__).
+AC_DEFUN_ONCE([AC_USE_SYSTEM_EXTENSIONS],
+[AC_BEFORE([$0], [AC_COMPILE_IFELSE])dnl
+AC_BEFORE([$0], [AC_RUN_IFELSE])dnl
+
+  AC_REQUIRE([AC_CANONICAL_HOST])
+
+  AC_CHECK_HEADER([minix/config.h], [MINIX=yes], [MINIX=])
+  if test "$MINIX" = yes; then
+    AC_DEFINE([_POSIX_SOURCE], [1],
+      [Define to 1 if you need to in order for `stat' and other
+       things to work.])
+    AC_DEFINE([_POSIX_1_SOURCE], [2],
+      [Define to 2 if the system does not provide POSIX.1 features
+       except with this defined.])
+    AC_DEFINE([_MINIX], [1],
+      [Define to 1 if on MINIX.])
+  fi
+
+  dnl HP-UX 11.11 defines mbstate_t only if _XOPEN_SOURCE is defined to 500,
+  dnl regardless of whether the flags -Ae or _D_HPUX_SOURCE=1 are already
+  dnl provided.
+  case "$host_os" in
+    hpux*)
+      AC_DEFINE([_XOPEN_SOURCE], [500],
+        [Define to 500 only on HP-UX.])
+      ;;
+  esac
+
+  AH_VERBATIM([__EXTENSIONS__],
+[/* Enable extensions on AIX 3, Interix.  */
+#ifndef _ALL_SOURCE
+# undef _ALL_SOURCE
+#endif
+/* Enable GNU extensions on systems that have them.  */
+#ifndef _GNU_SOURCE
+# undef _GNU_SOURCE
+#endif
+/* Enable threading extensions on Solaris.  */
+#ifndef _POSIX_PTHREAD_SEMANTICS
+# undef _POSIX_PTHREAD_SEMANTICS
+#endif
+/* Enable extensions on HP NonStop.  */
+#ifndef _TANDEM_SOURCE
+# undef _TANDEM_SOURCE
+#endif
+/* Enable general extensions on Solaris.  */
+#ifndef __EXTENSIONS__
+# undef __EXTENSIONS__
+#endif
+])
+  AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__],
+    [ac_cv_safe_to_define___extensions__],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM([[
+#         define __EXTENSIONS__ 1
+          ]AC_INCLUDES_DEFAULT])],
+       [ac_cv_safe_to_define___extensions__=yes],
+       [ac_cv_safe_to_define___extensions__=no])])
+  test $ac_cv_safe_to_define___extensions__ = yes &&
+    AC_DEFINE([__EXTENSIONS__])
+  AC_DEFINE([_ALL_SOURCE])
+  AC_DEFINE([_GNU_SOURCE])
+  AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
+  AC_DEFINE([_TANDEM_SOURCE])
+])# AC_USE_SYSTEM_EXTENSIONS
+
+# gl_USE_SYSTEM_EXTENSIONS
+# ------------------------
+# Enable extensions on systems that normally disable them,
+# typically due to standards-conformance issues.
+AC_DEFUN_ONCE([gl_USE_SYSTEM_EXTENSIONS],
+[
+  dnl Require this macro before AC_USE_SYSTEM_EXTENSIONS.
+  dnl gnulib does not need it. But if it gets required by third-party macros
+  dnl after AC_USE_SYSTEM_EXTENSIONS is required, autoconf 2.62..2.63 emit a
+  dnl warning: "AC_COMPILE_IFELSE was called before AC_USE_SYSTEM_EXTENSIONS".
+  dnl Note: We can do this only for one of the macros AC_AIX, AC_GNU_SOURCE,
+  dnl AC_MINIX. If people still use AC_AIX or AC_MINIX, they are out of luck.
+  AC_REQUIRE([AC_GNU_SOURCE])
+
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+])
diff --git a/gl/m4/fcntl-o.m4 b/gl/m4/fcntl-o.m4
new file mode 100644
index 0000000..88db07e
--- /dev/null
+++ b/gl/m4/fcntl-o.m4
@@ -0,0 +1,112 @@
+# fcntl-o.m4 serial 3
+dnl Copyright (C) 2006, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Paul Eggert.
+
+# Test whether the flags O_NOATIME and O_NOFOLLOW actually work.
+# Define HAVE_WORKING_O_NOATIME to 1 if O_NOATIME works, or to 0 otherwise.
+# Define HAVE_WORKING_O_NOFOLLOW to 1 if O_NOFOLLOW works, or to 0 otherwise.
+AC_DEFUN([gl_FCNTL_O_FLAGS],
+[
+  dnl Persuade glibc <fcntl.h> to define O_NOATIME and O_NOFOLLOW.
+  dnl AC_USE_SYSTEM_EXTENSIONS was introduced in autoconf 2.60 and obsoletes
+  dnl AC_GNU_SOURCE.
+  m4_ifdef([AC_USE_SYSTEM_EXTENSIONS],
+    [AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])],
+    [AC_REQUIRE([AC_GNU_SOURCE])])
+  AC_CACHE_CHECK([for working fcntl.h], [gl_cv_header_working_fcntl_h],
+    [AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <sys/types.h>
+           #include <sys/stat.h>
+           #include <unistd.h>
+           #include <fcntl.h>
+           #ifndef O_NOATIME
+            #define O_NOATIME 0
+           #endif
+           #ifndef O_NOFOLLOW
+            #define O_NOFOLLOW 0
+           #endif
+           static int const constants[] =
+            {
+              O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC, O_APPEND,
+              O_NONBLOCK, O_SYNC, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY
+            };
+          ]],
+          [[
+            int result = !constants;
+            {
+              static char const sym[] = "conftest.sym";
+              if (symlink (".", sym) != 0)
+                result |= 2;
+              else
+                {
+                  int fd = open (sym, O_RDONLY | O_NOFOLLOW);
+                  if (fd >= 0)
+                    {
+                      close (fd);
+                      result |= 4;
+                    }
+                }
+              unlink (sym);
+            }
+            {
+              static char const file[] = "confdefs.h";
+              int fd = open (file, O_RDONLY | O_NOATIME);
+              if (fd < 0)
+                result |= 8;
+              else
+                {
+                  struct stat st0;
+                  if (fstat (fd, &st0) != 0)
+                    result |= 16;
+                  else
+                    {
+                      char c;
+                      sleep (1);
+                      if (read (fd, &c, 1) != 1)
+                        result |= 24;
+                      else
+                        {
+                          if (close (fd) != 0)
+                            result |= 32;
+                          else
+                            {
+                              struct stat st1;
+                              if (stat (file, &st1) != 0)
+                                result |= 40;
+                              else
+                                if (st0.st_atime != st1.st_atime)
+                                  result |= 64;
+                            }
+                        }
+                    }
+                }
+            }
+            return result;]])],
+       [gl_cv_header_working_fcntl_h=yes],
+       [case $? in #(
+        4) gl_cv_header_working_fcntl_h='no (bad O_NOFOLLOW)';; #(
+        64) gl_cv_header_working_fcntl_h='no (bad O_NOATIME)';; #(
+        68) gl_cv_header_working_fcntl_h='no (bad O_NOATIME, O_NOFOLLOW)';; #(
+         *) gl_cv_header_working_fcntl_h='no';;
+        esac],
+       [gl_cv_header_working_fcntl_h=cross-compiling])])
+
+  case $gl_cv_header_working_fcntl_h in #(
+  *O_NOATIME* | no | cross-compiling) ac_val=0;; #(
+  *) ac_val=1;;
+  esac
+  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOATIME], [$ac_val],
+    [Define to 1 if O_NOATIME works.])
+
+  case $gl_cv_header_working_fcntl_h in #(
+  *O_NOFOLLOW* | no | cross-compiling) ac_val=0;; #(
+  *) ac_val=1;;
+  esac
+  AC_DEFINE_UNQUOTED([HAVE_WORKING_O_NOFOLLOW], [$ac_val],
+    [Define to 1 if O_NOFOLLOW works.])
+])
diff --git a/gl/m4/glibc21.m4 b/gl/m4/glibc21.m4
new file mode 100644
index 0000000..bc81c11
--- /dev/null
+++ b/gl/m4/glibc21.m4
@@ -0,0 +1,34 @@
+# glibc21.m4 serial 5
+dnl Copyright (C) 2000-2002, 2004, 2008, 2010-2011 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Test for the GNU C Library, version 2.1 or newer, or uClibc.
+# From Bruno Haible.
+
+AC_DEFUN([gl_GLIBC21],
+  [
+    AC_CACHE_CHECK([whether we are using the GNU C Library >= 2.1 or uClibc],
+      [ac_cv_gnu_library_2_1],
+      [AC_EGREP_CPP([Lucky],
+        [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
+  Lucky GNU user
+ #endif
+#endif
+#ifdef __UCLIBC__
+ Lucky user
+#endif
+        ],
+        [ac_cv_gnu_library_2_1=yes],
+        [ac_cv_gnu_library_2_1=no])
+      ]
+    )
+    AC_SUBST([GLIBC21])
+    GLIBC21="$ac_cv_gnu_library_2_1"
+  ]
+)
diff --git a/gl/m4/gnulib-cache.m4 b/gl/m4/gnulib-cache.m4
new file mode 100644
index 0000000..fd7e050
--- /dev/null
+++ b/gl/m4/gnulib-cache.m4
@@ -0,0 +1,36 @@
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License.  As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+#
+# This file represents the specification of how gnulib-tool is used.
+# It acts as a cache: It is written and read by gnulib-tool.
+# In projects that use version control, this file is meant to be put under
+# version control, like the configure.ac and various Makefile.am files.
+
+
+# Specification in the form of a command-line invocation:
+#   gnulib-tool --import --dir=. --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=gl/doc --tests-base=tests --aux-dir=conf --lgpl --libtool --macro-prefix=gl regex
+
+# Specification in the form of a few gnulib-tool.m4 macro invocations:
+gl_LOCAL_DIR([])
+gl_MODULES([
+  regex
+])
+gl_AVOID([])
+gl_SOURCE_BASE([gl])
+gl_M4_BASE([gl/m4])
+gl_PO_BASE([])
+gl_DOC_BASE([gl/doc])
+gl_TESTS_BASE([tests])
+gl_LIB([libgnu])
+gl_LGPL
+gl_MAKEFILE_NAME([])
+gl_LIBTOOL
+gl_MACRO_PREFIX([gl])
+gl_PO_DOMAIN([])
diff --git a/gl/m4/gnulib-common.m4 b/gl/m4/gnulib-common.m4
new file mode 100644
index 0000000..ecbf336
--- /dev/null
+++ b/gl/m4/gnulib-common.m4
@@ -0,0 +1,234 @@
+# gnulib-common.m4 serial 23
+dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# gl_COMMON
+# is expanded unconditionally through gnulib-tool magic.
+AC_DEFUN([gl_COMMON], [
+  dnl Use AC_REQUIRE here, so that the code is expanded once only.
+  AC_REQUIRE([gl_00GNULIB])
+  AC_REQUIRE([gl_COMMON_BODY])
+])
+AC_DEFUN([gl_COMMON_BODY], [
+  AH_VERBATIM([isoc99_inline],
+[/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports
+   the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of
+   earlier versions), but does not display it by setting __GNUC_STDC_INLINE__.
+   __APPLE__ && __MACH__ test for MacOS X.
+   __APPLE_CC__ tests for the Apple compiler and its version.
+   __STDC_VERSION__ tests for the C99 mode.  */
+#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__
+# define __GNUC_STDC_INLINE__ 1
+#endif])
+  AH_VERBATIM([unused_parameter],
+[/* Define as a marker that can be attached to declarations that might not
+    be used.  This helps to reduce warnings, such as from
+    GCC -Wunused-parameter.  */
+#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
+# define _GL_UNUSED __attribute__ ((__unused__))
+#else
+# define _GL_UNUSED
+#endif
+/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name
+   is a misnomer outside of parameter lists.  */
+#define _UNUSED_PARAMETER_ _GL_UNUSED
+])
+  dnl Preparation for running test programs:
+  dnl Tell glibc to write diagnostics from -D_FORTIFY_SOURCE=2 to stderr, not
+  dnl to /dev/tty, so they can be redirected to log files.  Such diagnostics
+  dnl arise e.g., in the macros gl_PRINTF_DIRECTIVE_N, gl_SNPRINTF_DIRECTIVE_N.
+  LIBC_FATAL_STDERR_=1
+  export LIBC_FATAL_STDERR_
+])
+
+# gl_MODULE_INDICATOR_CONDITION
+# expands to a C preprocessor expression that evaluates to 1 or 0, depending
+# whether a gnulib module that has been requested shall be considered present
+# or not.
+AC_DEFUN([gl_MODULE_INDICATOR_CONDITION], [1])
+
+# gl_MODULE_INDICATOR_SET_VARIABLE([modulename])
+# sets the shell variable that indicates the presence of the given module to
+# a C preprocessor expression that will evaluate to 1.
+AC_DEFUN([gl_MODULE_INDICATOR_SET_VARIABLE],
+[
+  GNULIB_[]m4_translit([[$1]],
+    [abcdefghijklmnopqrstuvwxyz./-],
+    [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])=gl_MODULE_INDICATOR_CONDITION
+])
+
+# gl_MODULE_INDICATOR([modulename])
+# defines a C macro indicating the presence of the given module
+# in a location where it can be used.
+#                                             |  Value  |   Value   |
+#                                             | in lib/ | in tests/ |
+# --------------------------------------------+---------+-----------+
+# Module present among main modules:          |    1    |     1     |
+# --------------------------------------------+---------+-----------+
+# Module present among tests-related modules: |    0    |     1     |
+# --------------------------------------------+---------+-----------+
+# Module not present at all:                  |    0    |     0     |
+# --------------------------------------------+---------+-----------+
+AC_DEFUN([gl_MODULE_INDICATOR],
+[
+  AC_DEFINE_UNQUOTED([GNULIB_]m4_translit([[$1]],
+      [abcdefghijklmnopqrstuvwxyz./-],
+      [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]),
+    [gl_MODULE_INDICATOR_CONDITION],
+    [Define to a C preprocessor expression that evaluates to 1 or 0,
+     depending whether the gnulib module $1 shall be considered present.])
+])
+
+# gl_MODULE_INDICATOR_FOR_TESTS([modulename])
+# defines a C macro indicating the presence of the given module
+# in lib or tests. This is useful to determine whether the module
+# should be tested.
+#                                             |  Value  |   Value   |
+#                                             | in lib/ | in tests/ |
+# --------------------------------------------+---------+-----------+
+# Module present among main modules:          |    1    |     1     |
+# --------------------------------------------+---------+-----------+
+# Module present among tests-related modules: |    1    |     1     |
+# --------------------------------------------+---------+-----------+
+# Module not present at all:                  |    0    |     0     |
+# --------------------------------------------+---------+-----------+
+AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS],
+[
+  AC_DEFINE([GNULIB_TEST_]m4_translit([[$1]],
+      [abcdefghijklmnopqrstuvwxyz./-],
+      [ABCDEFGHIJKLMNOPQRSTUVWXYZ___]), [1],
+    [Define to 1 when the gnulib module $1 should be tested.])
+])
+
+# gl_ASSERT_NO_GNULIB_POSIXCHECK
+# asserts that there will never be a need to #define GNULIB_POSIXCHECK.
+# and thereby enables an optimization of configure and config.h.
+# Used by Emacs.
+AC_DEFUN([gl_ASSERT_NO_GNULIB_POSIXCHECK],
+[
+  dnl Override gl_WARN_ON_USE_PREPARE.
+  AC_DEFUN([gl_WARN_ON_USE_PREPARE], [])
+])
+
+# gl_ASSERT_NO_GNULIB_TESTS
+# asserts that there will be no gnulib tests in the scope of the configure.ac
+# and thereby enables an optimization of config.h.
+# Used by Emacs.
+AC_DEFUN([gl_ASSERT_NO_GNULIB_TESTS],
+[
+  dnl Override gl_MODULE_INDICATOR_FOR_TESTS.
+  AC_DEFUN([gl_MODULE_INDICATOR_FOR_TESTS], [])
+])
+
+# Test whether <features.h> exists.
+# Set HAVE_FEATURES_H.
+AC_DEFUN([gl_FEATURES_H],
+[
+  AC_CHECK_HEADERS_ONCE([features.h])
+  if test $ac_cv_header_features_h = yes; then
+    HAVE_FEATURES_H=1
+  else
+    HAVE_FEATURES_H=0
+  fi
+  AC_SUBST([HAVE_FEATURES_H])
+])
+
+# m4_foreach_w
+# is a backport of autoconf-2.59c's m4_foreach_w.
+# Remove this macro when we can assume autoconf >= 2.60.
+m4_ifndef([m4_foreach_w],
+  [m4_define([m4_foreach_w],
+    [m4_foreach([$1], m4_split(m4_normalize([$2]), [ ]), [$3])])])
+
+# AS_VAR_IF(VAR, VALUE, [IF-MATCH], [IF-NOT-MATCH])
+# ----------------------------------------------------
+# Backport of autoconf-2.63b's macro.
+# Remove this macro when we can assume autoconf >= 2.64.
+m4_ifndef([AS_VAR_IF],
+[m4_define([AS_VAR_IF],
+[AS_IF([test x"AS_VAR_GET([$1])" = x""$2], [$3], [$4])])])
+
+# AC_PROG_MKDIR_P
+# is a backport of autoconf-2.60's AC_PROG_MKDIR_P, with a fix
+# for interoperability with automake-1.9.6 from autoconf-2.62.
+# Remove this macro when we can assume autoconf >= 2.62 or
+# autoconf >= 2.60 && automake >= 1.10.
+m4_ifdef([AC_PROG_MKDIR_P], [
+  dnl For automake-1.9.6 && autoconf < 2.62: Ensure MKDIR_P is AC_SUBSTed.
+  m4_define([AC_PROG_MKDIR_P],
+    m4_defn([AC_PROG_MKDIR_P])[
+    AC_SUBST([MKDIR_P])])], [
+  dnl For autoconf < 2.60: Backport of AC_PROG_MKDIR_P.
+  AC_DEFUN_ONCE([AC_PROG_MKDIR_P],
+    [AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
+     MKDIR_P='$(mkdir_p)'
+     AC_SUBST([MKDIR_P])])])
+
+# AC_C_RESTRICT
+# This definition overrides the AC_C_RESTRICT macro from autoconf 2.60..2.61,
+# so that mixed use of GNU C and GNU C++ and mixed use of Sun C and Sun C++
+# works.
+# This definition can be removed once autoconf >= 2.62 can be assumed.
+m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.62]),[-1],[
+AC_DEFUN([AC_C_RESTRICT],
+[AC_CACHE_CHECK([for C/C++ restrict keyword], [ac_cv_c_restrict],
+  [ac_cv_c_restrict=no
+   # The order here caters to the fact that C++ does not require restrict.
+   for ac_kw in __restrict __restrict__ _Restrict restrict; do
+     AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
+      [[typedef int * int_ptr;
+        int foo (int_ptr $ac_kw ip) {
+        return ip[0];
+       }]],
+      [[int s[1];
+        int * $ac_kw t = s;
+        t[0] = 0;
+        return foo(t)]])],
+      [ac_cv_c_restrict=$ac_kw])
+     test "$ac_cv_c_restrict" != no && break
+   done
+  ])
+ AH_VERBATIM([restrict],
+[/* Define to the equivalent of the C99 'restrict' keyword, or to
+   nothing if this is not supported.  Do not define if restrict is
+   supported directly.  */
+#undef restrict
+/* Work around a bug in Sun C++: it does not support _Restrict, even
+   though the corresponding Sun C compiler does, which causes
+   "#define restrict _Restrict" in the previous line.  Perhaps some future
+   version of Sun C++ will work with _Restrict; if so, it'll probably
+   define __RESTRICT, just as Sun C does.  */
+#if defined __SUNPRO_CC && !defined __RESTRICT
+# define _Restrict
+#endif])
+ case $ac_cv_c_restrict in
+   restrict) ;;
+   no) AC_DEFINE([restrict], []) ;;
+   *)  AC_DEFINE_UNQUOTED([restrict], [$ac_cv_c_restrict]) ;;
+ esac
+])
+])
+
+# gl_BIGENDIAN
+# is like AC_C_BIGENDIAN, except that it can be AC_REQUIREd.
+# Note that AC_REQUIRE([AC_C_BIGENDIAN]) does not work reliably because some
+# macros invoke AC_C_BIGENDIAN with arguments.
+AC_DEFUN([gl_BIGENDIAN],
+[
+  AC_C_BIGENDIAN
+])
+
+# gl_CACHE_VAL_SILENT(cache-id, command-to-set-it)
+# is like AC_CACHE_VAL(cache-id, command-to-set-it), except that it does not
+# output a spurious "(cached)" mark in the midst of other configure output.
+# This macro should be used instead of AC_CACHE_VAL when it is not surrounded
+# by an AC_MSG_CHECKING/AC_MSG_RESULT pair.
+AC_DEFUN([gl_CACHE_VAL_SILENT],
+[
+  saved_as_echo_n="$as_echo_n"
+  as_echo_n=':'
+  AC_CACHE_VAL([$1], [$2])
+  as_echo_n="$saved_as_echo_n"
+])
diff --git a/gl/m4/gnulib-comp.m4 b/gl/m4/gnulib-comp.m4
new file mode 100644
index 0000000..f327798
--- /dev/null
+++ b/gl/m4/gnulib-comp.m4
@@ -0,0 +1,340 @@
+# DO NOT EDIT! GENERATED AUTOMATICALLY!
+# Copyright (C) 2002-2011 Free Software Foundation, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License.  As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# Generated by gnulib-tool.
+#
+# This file represents the compiled summary of the specification in
+# gnulib-cache.m4. It lists the computed macro invocations that need
+# to be invoked from configure.ac.
+# In projects that use version control, this file can be treated like
+# other built files.
+
+
+# This macro should be invoked from ./configure.ac, in the section
+# "Checks for programs", right after AC_PROG_CC, and certainly before
+# any checks for libraries, header files, types and library functions.
+AC_DEFUN([gl_EARLY],
+[
+  m4_pattern_forbid([^gl_[A-Z]])dnl the gnulib macro namespace
+  m4_pattern_allow([^gl_ES$])dnl a valid locale name
+  m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
+  m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
+  AC_REQUIRE([AC_PROG_RANLIB])
+  # Code from module alloca-opt:
+  # Code from module arg-nonnull:
+  # Code from module btowc:
+  # Code from module c++defs:
+  # Code from module configmake:
+  # Code from module extensions:
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  # Code from module gettext-h:
+  # Code from module include_next:
+  # Code from module langinfo:
+  # Code from module localcharset:
+  # Code from module malloc-gnu:
+  # Code from module malloc-posix:
+  # Code from module mbrtowc:
+  # Code from module mbsinit:
+  # Code from module multiarch:
+  # Code from module nl_langinfo:
+  # Code from module regex:
+  # Code from module ssize_t:
+  # Code from module stdbool:
+  # Code from module stddef:
+  # Code from module stdint:
+  # Code from module stdlib:
+  # Code from module streq:
+  # Code from module unistd:
+  # Code from module verify:
+  # Code from module warn-on-use:
+  # Code from module wchar:
+  # Code from module wcrtomb:
+  # Code from module wctype:
+])
+
+# This macro should be invoked from ./configure.ac, in the section
+# "Check for header files, types and library functions".
+AC_DEFUN([gl_INIT],
+[
+  AM_CONDITIONAL([GL_COND_LIBTOOL], [true])
+  gl_cond_libtool=true
+  gl_m4_base='gl/m4'
+  m4_pushdef([AC_LIBOBJ], m4_defn([gl_LIBOBJ]))
+  m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gl_REPLACE_FUNCS]))
+  m4_pushdef([AC_LIBSOURCES], m4_defn([gl_LIBSOURCES]))
+  m4_pushdef([gl_LIBSOURCES_LIST], [])
+  m4_pushdef([gl_LIBSOURCES_DIR], [])
+  gl_COMMON
+  gl_source_base='gl'
+  # Code from module alloca-opt:
+  gl_FUNC_ALLOCA
+  # Code from module arg-nonnull:
+  # Code from module btowc:
+  gl_FUNC_BTOWC
+  gl_WCHAR_MODULE_INDICATOR([btowc])
+  # Code from module c++defs:
+  # Code from module configmake:
+  gl_CONFIGMAKE_PREP
+  # Code from module extensions:
+  # Code from module gettext-h:
+  AC_SUBST([LIBINTL])
+  AC_SUBST([LTLIBINTL])
+  # Code from module include_next:
+  # Code from module langinfo:
+  gl_LANGINFO_H
+  # Code from module localcharset:
+  gl_LOCALCHARSET
+  LOCALCHARSET_TESTS_ENVIRONMENT="CHARSETALIASDIR=\"\$(top_builddir)/$gl_source_base\""
+  AC_SUBST([LOCALCHARSET_TESTS_ENVIRONMENT])
+  # Code from module malloc-gnu:
+  gl_FUNC_MALLOC_GNU
+  gl_MODULE_INDICATOR([malloc-gnu])
+  # Code from module malloc-posix:
+  gl_FUNC_MALLOC_POSIX
+  gl_STDLIB_MODULE_INDICATOR([malloc-posix])
+  # Code from module mbrtowc:
+  gl_FUNC_MBRTOWC
+  gl_WCHAR_MODULE_INDICATOR([mbrtowc])
+  # Code from module mbsinit:
+  gl_FUNC_MBSINIT
+  gl_WCHAR_MODULE_INDICATOR([mbsinit])
+  # Code from module multiarch:
+  gl_MULTIARCH
+  # Code from module nl_langinfo:
+  gl_FUNC_NL_LANGINFO
+  gl_LANGINFO_MODULE_INDICATOR([nl_langinfo])
+  # Code from module regex:
+  gl_REGEX
+  # Code from module ssize_t:
+  gt_TYPE_SSIZE_T
+  # Code from module stdbool:
+  AM_STDBOOL_H
+  # Code from module stddef:
+  gl_STDDEF_H
+  # Code from module stdint:
+  gl_STDINT_H
+  # Code from module stdlib:
+  gl_STDLIB_H
+  # Code from module streq:
+  # Code from module unistd:
+  gl_UNISTD_H
+  # Code from module verify:
+  # Code from module warn-on-use:
+  # Code from module wchar:
+  gl_WCHAR_H
+  # Code from module wcrtomb:
+  gl_FUNC_WCRTOMB
+  gl_WCHAR_MODULE_INDICATOR([wcrtomb])
+  # Code from module wctype:
+  gl_WCTYPE_H
+  # End of code from modules
+  m4_ifval(gl_LIBSOURCES_LIST, [
+    m4_syscmd([test ! -d ]m4_defn([gl_LIBSOURCES_DIR])[ ||
+      for gl_file in ]gl_LIBSOURCES_LIST[ ; do
+        if test ! -r ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file ; then
+          echo "missing file ]m4_defn([gl_LIBSOURCES_DIR])[/$gl_file" >&2
+          exit 1
+        fi
+      done])dnl
+      m4_if(m4_sysval, [0], [],
+        [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
+  ])
+  m4_popdef([gl_LIBSOURCES_DIR])
+  m4_popdef([gl_LIBSOURCES_LIST])
+  m4_popdef([AC_LIBSOURCES])
+  m4_popdef([AC_REPLACE_FUNCS])
+  m4_popdef([AC_LIBOBJ])
+  AC_CONFIG_COMMANDS_PRE([
+    gl_libobjs=
+    gl_ltlibobjs=
+    if test -n "$gl_LIBOBJS"; then
+      # Remove the extension.
+      sed_drop_objext='s/\.o$//;s/\.obj$//'
+      for i in `for i in $gl_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+        gl_libobjs="$gl_libobjs $i.$ac_objext"
+        gl_ltlibobjs="$gl_ltlibobjs $i.lo"
+      done
+    fi
+    AC_SUBST([gl_LIBOBJS], [$gl_libobjs])
+    AC_SUBST([gl_LTLIBOBJS], [$gl_ltlibobjs])
+  ])
+  gltests_libdeps=
+  gltests_ltlibdeps=
+  m4_pushdef([AC_LIBOBJ], m4_defn([gltests_LIBOBJ]))
+  m4_pushdef([AC_REPLACE_FUNCS], m4_defn([gltests_REPLACE_FUNCS]))
+  m4_pushdef([AC_LIBSOURCES], m4_defn([gltests_LIBSOURCES]))
+  m4_pushdef([gltests_LIBSOURCES_LIST], [])
+  m4_pushdef([gltests_LIBSOURCES_DIR], [])
+  gl_COMMON
+  gl_source_base='tests'
+changequote(,)dnl
+  gltests_WITNESS=IN_`echo "${PACKAGE-$PACKAGE_TARNAME}" | LC_ALL=C tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | LC_ALL=C sed -e 's/[^A-Z0-9_]/_/g'`_GNULIB_TESTS
+changequote([, ])dnl
+  AC_SUBST([gltests_WITNESS])
+  gl_module_indicator_condition=$gltests_WITNESS
+  m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [$gl_module_indicator_condition])
+  m4_popdef([gl_MODULE_INDICATOR_CONDITION])
+  m4_ifval(gltests_LIBSOURCES_LIST, [
+    m4_syscmd([test ! -d ]m4_defn([gltests_LIBSOURCES_DIR])[ ||
+      for gl_file in ]gltests_LIBSOURCES_LIST[ ; do
+        if test ! -r ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file ; then
+          echo "missing file ]m4_defn([gltests_LIBSOURCES_DIR])[/$gl_file" >&2
+          exit 1
+        fi
+      done])dnl
+      m4_if(m4_sysval, [0], [],
+        [AC_FATAL([expected source file, required through AC_LIBSOURCES, not found])])
+  ])
+  m4_popdef([gltests_LIBSOURCES_DIR])
+  m4_popdef([gltests_LIBSOURCES_LIST])
+  m4_popdef([AC_LIBSOURCES])
+  m4_popdef([AC_REPLACE_FUNCS])
+  m4_popdef([AC_LIBOBJ])
+  AC_CONFIG_COMMANDS_PRE([
+    gltests_libobjs=
+    gltests_ltlibobjs=
+    if test -n "$gltests_LIBOBJS"; then
+      # Remove the extension.
+      sed_drop_objext='s/\.o$//;s/\.obj$//'
+      for i in `for i in $gltests_LIBOBJS; do echo "$i"; done | sed -e "$sed_drop_objext" | sort | uniq`; do
+        gltests_libobjs="$gltests_libobjs $i.$ac_objext"
+        gltests_ltlibobjs="$gltests_ltlibobjs $i.lo"
+      done
+    fi
+    AC_SUBST([gltests_LIBOBJS], [$gltests_libobjs])
+    AC_SUBST([gltests_LTLIBOBJS], [$gltests_ltlibobjs])
+  ])
+])
+
+# Like AC_LIBOBJ, except that the module name goes
+# into gl_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gl_LIBOBJ], [
+  AS_LITERAL_IF([$1], [gl_LIBSOURCES([$1.c])])dnl
+  gl_LIBOBJS="$gl_LIBOBJS $1.$ac_objext"
+])
+
+# Like AC_REPLACE_FUNCS, except that the module name goes
+# into gl_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gl_REPLACE_FUNCS], [
+  m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
+  AC_CHECK_FUNCS([$1], , [gl_LIBOBJ($ac_func)])
+])
+
+# Like AC_LIBSOURCES, except the directory where the source file is
+# expected is derived from the gnulib-tool parameterization,
+# and alloca is special cased (for the alloca-opt module).
+# We could also entirely rely on EXTRA_lib..._SOURCES.
+AC_DEFUN([gl_LIBSOURCES], [
+  m4_foreach([_gl_NAME], [$1], [
+    m4_if(_gl_NAME, [alloca.c], [], [
+      m4_define([gl_LIBSOURCES_DIR], [gl])
+      m4_append([gl_LIBSOURCES_LIST], _gl_NAME, [ ])
+    ])
+  ])
+])
+
+# Like AC_LIBOBJ, except that the module name goes
+# into gltests_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gltests_LIBOBJ], [
+  AS_LITERAL_IF([$1], [gltests_LIBSOURCES([$1.c])])dnl
+  gltests_LIBOBJS="$gltests_LIBOBJS $1.$ac_objext"
+])
+
+# Like AC_REPLACE_FUNCS, except that the module name goes
+# into gltests_LIBOBJS instead of into LIBOBJS.
+AC_DEFUN([gltests_REPLACE_FUNCS], [
+  m4_foreach_w([gl_NAME], [$1], [AC_LIBSOURCES(gl_NAME[.c])])dnl
+  AC_CHECK_FUNCS([$1], , [gltests_LIBOBJ($ac_func)])
+])
+
+# Like AC_LIBSOURCES, except the directory where the source file is
+# expected is derived from the gnulib-tool parameterization,
+# and alloca is special cased (for the alloca-opt module).
+# We could also entirely rely on EXTRA_lib..._SOURCES.
+AC_DEFUN([gltests_LIBSOURCES], [
+  m4_foreach([_gl_NAME], [$1], [
+    m4_if(_gl_NAME, [alloca.c], [], [
+      m4_define([gltests_LIBSOURCES_DIR], [tests])
+      m4_append([gltests_LIBSOURCES_LIST], _gl_NAME, [ ])
+    ])
+  ])
+])
+
+# This macro records the list of files which have been installed by
+# gnulib-tool and may be removed by future gnulib-tool invocations.
+AC_DEFUN([gl_FILE_LIST], [
+  build-aux/arg-nonnull.h
+  build-aux/c++defs.h
+  build-aux/warn-on-use.h
+  lib/alloca.in.h
+  lib/btowc.c
+  lib/config.charset
+  lib/gettext.h
+  lib/iswblank.c
+  lib/langinfo.in.h
+  lib/localcharset.c
+  lib/localcharset.h
+  lib/malloc.c
+  lib/mbrtowc.c
+  lib/mbsinit.c
+  lib/nl_langinfo.c
+  lib/ref-add.sin
+  lib/ref-del.sin
+  lib/regcomp.c
+  lib/regex.c
+  lib/regex.h
+  lib/regex_internal.c
+  lib/regex_internal.h
+  lib/regexec.c
+  lib/stdbool.in.h
+  lib/stddef.in.h
+  lib/stdint.in.h
+  lib/stdlib.in.h
+  lib/streq.h
+  lib/unistd.in.h
+  lib/verify.h
+  lib/wchar.in.h
+  lib/wcrtomb.c
+  lib/wctype.in.h
+  m4/00gnulib.m4
+  m4/alloca.m4
+  m4/btowc.m4
+  m4/codeset.m4
+  m4/configmake.m4
+  m4/extensions.m4
+  m4/fcntl-o.m4
+  m4/glibc21.m4
+  m4/gnulib-common.m4
+  m4/include_next.m4
+  m4/langinfo_h.m4
+  m4/localcharset.m4
+  m4/locale-fr.m4
+  m4/locale-ja.m4
+  m4/locale-zh.m4
+  m4/longlong.m4
+  m4/malloc.m4
+  m4/mbrtowc.m4
+  m4/mbsinit.m4
+  m4/mbstate_t.m4
+  m4/multiarch.m4
+  m4/nl_langinfo.m4
+  m4/regex.m4
+  m4/ssize_t.m4
+  m4/stdbool.m4
+  m4/stddef_h.m4
+  m4/stdint.m4
+  m4/stdlib_h.m4
+  m4/unistd_h.m4
+  m4/warn-on-use.m4
+  m4/wchar_h.m4
+  m4/wchar_t.m4
+  m4/wcrtomb.m4
+  m4/wctype_h.m4
+  m4/wint_t.m4
+])
diff --git a/gl/m4/gnulib-tool.m4 b/gl/m4/gnulib-tool.m4
new file mode 100644
index 0000000..ed41e9d
--- /dev/null
+++ b/gl/m4/gnulib-tool.m4
@@ -0,0 +1,57 @@
+# gnulib-tool.m4 serial 2
+dnl Copyright (C) 2004-2005, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl The following macros need not be invoked explicitly.
+dnl Invoking them does nothing except to declare default arguments
+dnl for "gnulib-tool --import".
+
+dnl Usage: gl_LOCAL_DIR([DIR])
+AC_DEFUN([gl_LOCAL_DIR], [])
+
+dnl Usage: gl_MODULES([module1 module2 ...])
+AC_DEFUN([gl_MODULES], [])
+
+dnl Usage: gl_AVOID([module1 module2 ...])
+AC_DEFUN([gl_AVOID], [])
+
+dnl Usage: gl_SOURCE_BASE([DIR])
+AC_DEFUN([gl_SOURCE_BASE], [])
+
+dnl Usage: gl_M4_BASE([DIR])
+AC_DEFUN([gl_M4_BASE], [])
+
+dnl Usage: gl_PO_BASE([DIR])
+AC_DEFUN([gl_PO_BASE], [])
+
+dnl Usage: gl_DOC_BASE([DIR])
+AC_DEFUN([gl_DOC_BASE], [])
+
+dnl Usage: gl_TESTS_BASE([DIR])
+AC_DEFUN([gl_TESTS_BASE], [])
+
+dnl Usage: gl_WITH_TESTS
+AC_DEFUN([gl_WITH_TESTS], [])
+
+dnl Usage: gl_LIB([LIBNAME])
+AC_DEFUN([gl_LIB], [])
+
+dnl Usage: gl_LGPL or gl_LGPL([VERSION])
+AC_DEFUN([gl_LGPL], [])
+
+dnl Usage: gl_MAKEFILE_NAME([FILENAME])
+AC_DEFUN([gl_MAKEFILE_NAME], [])
+
+dnl Usage: gl_LIBTOOL
+AC_DEFUN([gl_LIBTOOL], [])
+
+dnl Usage: gl_MACRO_PREFIX([PREFIX])
+AC_DEFUN([gl_MACRO_PREFIX], [])
+
+dnl Usage: gl_PO_DOMAIN([DOMAIN])
+AC_DEFUN([gl_PO_DOMAIN], [])
+
+dnl Usage: gl_VC_FILES([BOOLEAN])
+AC_DEFUN([gl_VC_FILES], [])
diff --git a/gl/m4/include_next.m4 b/gl/m4/include_next.m4
new file mode 100644
index 0000000..b3c7849
--- /dev/null
+++ b/gl/m4/include_next.m4
@@ -0,0 +1,244 @@
+# include_next.m4 serial 18
+dnl Copyright (C) 2006-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert and Derek Price.
+
+dnl Sets INCLUDE_NEXT and PRAGMA_SYSTEM_HEADER.
+dnl
+dnl INCLUDE_NEXT expands to 'include_next' if the compiler supports it, or to
+dnl 'include' otherwise.
+dnl
+dnl INCLUDE_NEXT_AS_FIRST_DIRECTIVE expands to 'include_next' if the compiler
+dnl supports it in the special case that it is the first include directive in
+dnl the given file, or to 'include' otherwise.
+dnl
+dnl PRAGMA_SYSTEM_HEADER can be used in files that contain #include_next,
+dnl so as to avoid GCC warnings when the gcc option -pedantic is used.
+dnl '#pragma GCC system_header' has the same effect as if the file was found
+dnl through the include search path specified with '-isystem' options (as
+dnl opposed to the search path specified with '-I' options). Namely, gcc
+dnl does not warn about some things, and on some systems (Solaris and Interix)
+dnl __STDC__ evaluates to 0 instead of to 1. The latter is an undesired side
+dnl effect; we are therefore careful to use 'defined __STDC__' or '1' instead
+dnl of plain '__STDC__'.
+dnl
+dnl PRAGMA_COLUMNS can be used in files that override system header files, so
+dnl as to avoid compilation errors on HP NonStop systems when the gnulib file
+dnl is included by a system header file that does a "#pragma COLUMNS 80" (which
+dnl has the effect of truncating the lines of that file and all files that it
+dnl includes to 80 columns) and the gnulib file has lines longer than 80
+dnl columns.
+
+AC_DEFUN([gl_INCLUDE_NEXT],
+[
+  AC_LANG_PREPROC_REQUIRE()
+  AC_CACHE_CHECK([whether the preprocessor supports include_next],
+    [gl_cv_have_include_next],
+    [rm -rf conftestd1a conftestd1b conftestd2
+     mkdir conftestd1a conftestd1b conftestd2
+     dnl IBM C 9.0, 10.1 (original versions, prior to the 2009-01 updates) on
+     dnl AIX 6.1 support include_next when used as first preprocessor directive
+     dnl in a file, but not when preceded by another include directive. Check
+     dnl for this bug by including <stdio.h>.
+     dnl Additionally, with this same compiler, include_next is a no-op when
+     dnl used in a header file that was included by specifying its absolute
+     dnl file name. Despite these two bugs, include_next is used in the
+     dnl compiler's <math.h>. By virtue of the second bug, we need to use
+     dnl include_next as well in this case.
+     cat <<EOF > conftestd1a/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+     cat <<EOF > conftestd1b/conftest.h
+#define DEFINED_IN_CONFTESTD1
+#include <stdio.h>
+#include_next <conftest.h>
+#ifdef DEFINED_IN_CONFTESTD2
+int foo;
+#else
+#error "include_next doesn't work"
+#endif
+EOF
+     cat <<EOF > conftestd2/conftest.h
+#ifndef DEFINED_IN_CONFTESTD1
+#error "include_next test doesn't work"
+#endif
+#define DEFINED_IN_CONFTESTD2
+EOF
+     gl_save_CPPFLAGS="$CPPFLAGS"
+     CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1b -Iconftestd2"
+dnl We intentionally avoid using AC_LANG_SOURCE here.
+     AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],
+       [gl_cv_have_include_next=yes],
+       [CPPFLAGS="$gl_save_CPPFLAGS -Iconftestd1a -Iconftestd2"
+        AC_COMPILE_IFELSE([AC_LANG_DEFINES_PROVIDED[#include <conftest.h>]],
+          [gl_cv_have_include_next=buggy],
+          [gl_cv_have_include_next=no])
+       ])
+     CPPFLAGS="$gl_save_CPPFLAGS"
+     rm -rf conftestd1a conftestd1b conftestd2
+    ])
+  PRAGMA_SYSTEM_HEADER=
+  if test $gl_cv_have_include_next = yes; then
+    INCLUDE_NEXT=include_next
+    INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+    if test -n "$GCC"; then
+      PRAGMA_SYSTEM_HEADER='#pragma GCC system_header'
+    fi
+  else
+    if test $gl_cv_have_include_next = buggy; then
+      INCLUDE_NEXT=include
+      INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include_next
+    else
+      INCLUDE_NEXT=include
+      INCLUDE_NEXT_AS_FIRST_DIRECTIVE=include
+    fi
+  fi
+  AC_SUBST([INCLUDE_NEXT])
+  AC_SUBST([INCLUDE_NEXT_AS_FIRST_DIRECTIVE])
+  AC_SUBST([PRAGMA_SYSTEM_HEADER])
+  AC_CACHE_CHECK([whether system header files limit the line length],
+    [gl_cv_pragma_columns],
+    [dnl HP NonStop systems, which define __TANDEM, have this misfeature.
+     AC_EGREP_CPP([choke me],
+       [
+#ifdef __TANDEM
+choke me
+#endif
+       ],
+       [gl_cv_pragma_columns=yes],
+       [gl_cv_pragma_columns=no])
+    ])
+  if test $gl_cv_pragma_columns = yes; then
+    PRAGMA_COLUMNS="#pragma COLUMNS 10000"
+  else
+    PRAGMA_COLUMNS=
+  fi
+  AC_SUBST([PRAGMA_COLUMNS])
+])
+
+# gl_CHECK_NEXT_HEADERS(HEADER1 HEADER2 ...)
+# ------------------------------------------
+# For each arg foo.h, if #include_next works, define NEXT_FOO_H to be
+# '<foo.h>'; otherwise define it to be
+# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
+# Also, if #include_next works as first preprocessing directive in a file,
+# define NEXT_AS_FIRST_DIRECTIVE_FOO_H to be '<foo.h>'; otherwise define it to
+# be
+# '"///usr/include/foo.h"', or whatever other absolute file name is suitable.
+# That way, a header file with the following line:
+#       #@INCLUDE_NEXT@ @NEXT_FOO_H@
+# or
+#       #@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_FOO_H@
+# behaves (after sed substitution) as if it contained
+#       #include_next <foo.h>
+# even if the compiler does not support include_next.
+# The three "///" are to pacify Sun C 5.8, which otherwise would say
+# "warning: #include of /usr/include/... may be non-portable".
+# Use `""', not `<>', so that the /// cannot be confused with a C99 comment.
+# Note: This macro assumes that the header file is not empty after
+# preprocessing, i.e. it does not only define preprocessor macros but also
+# provides some type/enum definitions or function/variable declarations.
+#
+# This macro also checks whether each header exists, by invoking
+# AC_CHECK_HEADERS_ONCE or AC_CHECK_HEADERS on each argument.
+AC_DEFUN([gl_CHECK_NEXT_HEADERS],
+[
+  gl_NEXT_HEADERS_INTERNAL([$1], [check])
+])
+
+# gl_NEXT_HEADERS(HEADER1 HEADER2 ...)
+# ------------------------------------
+# Like gl_CHECK_NEXT_HEADERS, except do not check whether the headers exist.
+# This is suitable for headers like <stddef.h> that are standardized by C89
+# and therefore can be assumed to exist.
+AC_DEFUN([gl_NEXT_HEADERS],
+[
+  gl_NEXT_HEADERS_INTERNAL([$1], [assume])
+])
+
+# The guts of gl_CHECK_NEXT_HEADERS and gl_NEXT_HEADERS.
+AC_DEFUN([gl_NEXT_HEADERS_INTERNAL],
+[
+  AC_REQUIRE([gl_INCLUDE_NEXT])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+
+  m4_if([$2], [check],
+    [AC_CHECK_HEADERS_ONCE([$1])
+    ])
+
+  m4_foreach_w([gl_HEADER_NAME], [$1],
+    [AS_VAR_PUSHDEF([gl_next_header],
+                    [gl_cv_next_]m4_defn([gl_HEADER_NAME]))
+     if test $gl_cv_have_include_next = yes; then
+       AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
+     else
+       AC_CACHE_CHECK(
+         [absolute name of <]m4_defn([gl_HEADER_NAME])[>],
+         m4_defn([gl_next_header]),
+         [m4_if([$2], [check],
+            [AS_VAR_PUSHDEF([gl_header_exists],
+                            [ac_cv_header_]m4_defn([gl_HEADER_NAME]))
+             if test AS_VAR_GET(gl_header_exists) = yes; then
+             AS_VAR_POPDEF([gl_header_exists])
+            ])
+               AC_LANG_CONFTEST(
+                 [AC_LANG_SOURCE(
+                    [[#include <]]m4_dquote(m4_defn([gl_HEADER_NAME]))[[>]]
+                  )])
+               dnl AIX "xlc -E" and "cc -E" omit #line directives for header
+               dnl files that contain only a #include of other header files and
+               dnl no non-comment tokens of their own. This leads to a failure
+               dnl to detect the absolute name of <dirent.h>, <signal.h>,
+               dnl <poll.h> and others. The workaround is to force preservation
+               dnl of comments through option -C. This ensures all necessary
+               dnl #line directives are present. GCC supports option -C as well.
+               case "$host_os" in
+                 aix*) gl_absname_cpp="$ac_cpp -C" ;;
+                 *)    gl_absname_cpp="$ac_cpp" ;;
+               esac
+               dnl eval is necessary to expand gl_absname_cpp.
+               dnl Ultrix and Pyramid sh refuse to redirect output of eval,
+               dnl so use subshell.
+               AS_VAR_SET([gl_next_header],
+                 ['"'`(eval "$gl_absname_cpp conftest.$ac_ext") 2>&AS_MESSAGE_LOG_FD |
+                  sed -n '\#/]m4_defn([gl_HEADER_NAME])[#{
+                    s#.*"\(.*/]m4_defn([gl_HEADER_NAME])[\)".*#\1#
+                    s#^/[^/]#//&#
+                    p
+                    q
+                  }'`'"'])
+          m4_if([$2], [check],
+            [else
+               AS_VAR_SET([gl_next_header], ['<'gl_HEADER_NAME'>'])
+             fi
+            ])
+         ])
+     fi
+     AC_SUBST(
+       AS_TR_CPP([NEXT_]m4_defn([gl_HEADER_NAME])),
+       [AS_VAR_GET([gl_next_header])])
+     if test $gl_cv_have_include_next = yes || test $gl_cv_have_include_next = buggy; then
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include_next'
+       gl_next_as_first_directive='<'gl_HEADER_NAME'>'
+     else
+       # INCLUDE_NEXT_AS_FIRST_DIRECTIVE='include'
+       gl_next_as_first_directive=AS_VAR_GET([gl_next_header])
+     fi
+     AC_SUBST(
+       AS_TR_CPP([NEXT_AS_FIRST_DIRECTIVE_]m4_defn([gl_HEADER_NAME])),
+       [$gl_next_as_first_directive])
+     AS_VAR_POPDEF([gl_next_header])])
+])
+
+# Autoconf 2.68 added warnings for our use of AC_COMPILE_IFELSE;
+# this fallback is safe for all earlier autoconf versions.
+m4_define_default([AC_LANG_DEFINES_PROVIDED])
diff --git a/gl/m4/langinfo_h.m4 b/gl/m4/langinfo_h.m4
new file mode 100644
index 0000000..4cced8a
--- /dev/null
+++ b/gl/m4/langinfo_h.m4
@@ -0,0 +1,105 @@
+# langinfo_h.m4 serial 7
+dnl Copyright (C) 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_LANGINFO_H],
+[
+  AC_REQUIRE([gl_LANGINFO_H_DEFAULTS])
+
+  dnl Persuade glibc-2.0.6 <langinfo.h> to define CODESET.
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+
+  dnl <langinfo.h> is always overridden, because of GNULIB_POSIXCHECK.
+  gl_CHECK_NEXT_HEADERS([langinfo.h])
+
+  dnl Determine whether <langinfo.h> exists. It is missing on mingw and BeOS.
+  HAVE_LANGINFO_CODESET=0
+  HAVE_LANGINFO_T_FMT_AMPM=0
+  HAVE_LANGINFO_ERA=0
+  HAVE_LANGINFO_YESEXPR=0
+  AC_CHECK_HEADERS_ONCE([langinfo.h])
+  if test $ac_cv_header_langinfo_h = yes; then
+    HAVE_LANGINFO_H=1
+    dnl Determine what <langinfo.h> defines. CODESET and ERA etc. are missing
+    dnl on OpenBSD 3.8. T_FMT_AMPM and YESEXPR, NOEXPR are missing on IRIX 5.3.
+    AC_CACHE_CHECK([whether langinfo.h defines CODESET],
+      [gl_cv_header_langinfo_codeset],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[#include <langinfo.h>
+int a = CODESET;
+]])],
+         [gl_cv_header_langinfo_codeset=yes],
+         [gl_cv_header_langinfo_codeset=no])
+      ])
+    if test $gl_cv_header_langinfo_codeset = yes; then
+      HAVE_LANGINFO_CODESET=1
+    fi
+    AC_CACHE_CHECK([whether langinfo.h defines T_FMT_AMPM],
+      [gl_cv_header_langinfo_t_fmt_ampm],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[#include <langinfo.h>
+int a = T_FMT_AMPM;
+]])],
+         [gl_cv_header_langinfo_t_fmt_ampm=yes],
+         [gl_cv_header_langinfo_t_fmt_ampm=no])
+      ])
+    if test $gl_cv_header_langinfo_t_fmt_ampm = yes; then
+      HAVE_LANGINFO_T_FMT_AMPM=1
+    fi
+    AC_CACHE_CHECK([whether langinfo.h defines ERA],
+      [gl_cv_header_langinfo_era],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[#include <langinfo.h>
+int a = ERA;
+]])],
+         [gl_cv_header_langinfo_era=yes],
+         [gl_cv_header_langinfo_era=no])
+      ])
+    if test $gl_cv_header_langinfo_era = yes; then
+      HAVE_LANGINFO_ERA=1
+    fi
+    AC_CACHE_CHECK([whether langinfo.h defines YESEXPR],
+      [gl_cv_header_langinfo_yesexpr],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([[#include <langinfo.h>
+int a = YESEXPR;
+]])],
+         [gl_cv_header_langinfo_yesexpr=yes],
+         [gl_cv_header_langinfo_yesexpr=no])
+      ])
+    if test $gl_cv_header_langinfo_yesexpr = yes; then
+      HAVE_LANGINFO_YESEXPR=1
+    fi
+  else
+    HAVE_LANGINFO_H=0
+  fi
+  AC_SUBST([HAVE_LANGINFO_H])
+  AC_SUBST([HAVE_LANGINFO_CODESET])
+  AC_SUBST([HAVE_LANGINFO_T_FMT_AMPM])
+  AC_SUBST([HAVE_LANGINFO_ERA])
+  AC_SUBST([HAVE_LANGINFO_YESEXPR])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use.
+  gl_WARN_ON_USE_PREPARE([[#include <langinfo.h>
+    ]], [nl_langinfo])
+])
+
+AC_DEFUN([gl_LANGINFO_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_LANGINFO_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_LANGINFO_H_DEFAULTS],
+[
+  GNULIB_NL_LANGINFO=0;  AC_SUBST([GNULIB_NL_LANGINFO])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_NL_LANGINFO=1;    AC_SUBST([HAVE_NL_LANGINFO])
+  REPLACE_NL_LANGINFO=0; AC_SUBST([REPLACE_NL_LANGINFO])
+])
diff --git a/gl/m4/localcharset.m4 b/gl/m4/localcharset.m4
new file mode 100644
index 0000000..6801ca9
--- /dev/null
+++ b/gl/m4/localcharset.m4
@@ -0,0 +1,17 @@
+# localcharset.m4 serial 7
+dnl Copyright (C) 2002, 2004, 2006, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_LOCALCHARSET],
+[
+  dnl Prerequisites of lib/localcharset.c.
+  AC_REQUIRE([AM_LANGINFO_CODESET])
+  AC_REQUIRE([gl_FCNTL_O_FLAGS])
+  AC_CHECK_DECLS_ONCE([getc_unlocked])
+
+  dnl Prerequisites of the lib/Makefile.am snippet.
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([gl_GLIBC21])
+])
diff --git a/gl/m4/locale-fr.m4 b/gl/m4/locale-fr.m4
new file mode 100644
index 0000000..2616f91
--- /dev/null
+++ b/gl/m4/locale-fr.m4
@@ -0,0 +1,188 @@
+# locale-fr.m4 serial 12
+dnl Copyright (C) 2003, 2005-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl Determine the name of a french locale with traditional encoding.
+AC_DEFUN([gt_LOCALE_FR],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AM_LANGINFO_CODESET])
+  AC_CACHE_CHECK([for a traditional french locale], [gt_cv_locale_fr], [
+    AC_LANG_CONFTEST([AC_LANG_SOURCE([
+changequote(,)dnl
+#include <locale.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main () {
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.
+     On MirBSD 10, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "UTF-8".  */
+#if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0
+        || strcmp (cs, "UTF-8") == 0)
+      return 1;
+  }
+#endif
+#ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+#endif
+  /* Check whether in the abbreviation of the second month, the second
+     character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is only
+     one byte long. This excludes the UTF-8 encoding.  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%b", &t) < 3 || buf[2] != 'v') return 1;
+  /* Check whether the decimal separator is a comma.
+     On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point
+     are nl_langinfo(RADIXCHAR) are both ".".  */
+  if (localeconv () ->decimal_point[0] != ',') return 1;
+  return 0;
+}
+changequote([,])dnl
+      ])])
+    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the usual locale name.
+      if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_fr=fr_FR
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=fr_FR.ISO-8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_fr=fr_FR.ISO-8859-1
+        else
+          # Test for the AIX, OSF/1, FreeBSD, NetBSD, OpenBSD locale name.
+          if (LC_ALL=fr_FR.ISO8859-1 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+            gt_cv_locale_fr=fr_FR.ISO8859-1
+          else
+            # Test for the HP-UX locale name.
+            if (LC_ALL=fr_FR.iso88591 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+              gt_cv_locale_fr=fr_FR.iso88591
+            else
+              # Test for the Solaris 7 locale name.
+              if (LC_ALL=fr LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+                gt_cv_locale_fr=fr
+              else
+                # None found.
+                gt_cv_locale_fr=none
+              fi
+            fi
+          fi
+        fi
+      fi
+    fi
+    rm -fr conftest*
+  ])
+  LOCALE_FR=$gt_cv_locale_fr
+  AC_SUBST([LOCALE_FR])
+])
+
+dnl Determine the name of a french locale with UTF-8 encoding.
+AC_DEFUN([gt_LOCALE_FR_UTF8],
+[
+  AC_REQUIRE([AM_LANGINFO_CODESET])
+  AC_CACHE_CHECK([for a french Unicode locale], [gt_cv_locale_fr_utf8], [
+    AC_LANG_CONFTEST([AC_LANG_SOURCE([
+changequote(,)dnl
+#include <locale.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main () {
+  /* On BeOS and Haiku, locales are not implemented in libc.  Rather, libintl
+     imitates locale dependent behaviour by looking at the environment
+     variables, and all locales use the UTF-8 encoding.  */
+#if !(defined __BEOS__ || defined __HAIKU__)
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.  */
+# if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0)
+      return 1;
+  }
+# endif
+# ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+# endif
+  /* Check whether in the abbreviation of the second month, the second
+     character (should be U+00E9: LATIN SMALL LETTER E WITH ACUTE) is
+     two bytes long, with UTF-8 encoding.  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%b", &t) < 4
+      || buf[1] != (char) 0xc3 || buf[2] != (char) 0xa9 || buf[3] != 'v')
+    return 1;
+#endif
+  /* Check whether the decimal separator is a comma.
+     On NetBSD 3.0 in the fr_FR.ISO8859-1 locale, localeconv()->decimal_point
+     are nl_langinfo(RADIXCHAR) are both ".".  */
+  if (localeconv () ->decimal_point[0] != ',') return 1;
+  return 0;
+}
+changequote([,])dnl
+      ])])
+    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the usual locale name.
+      if (LC_ALL=fr_FR LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_fr_utf8=fr_FR
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=fr_FR.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_fr_utf8=fr_FR.UTF-8
+        else
+          # Test for the Solaris 7 locale name.
+          if (LC_ALL=fr.UTF-8 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+            gt_cv_locale_fr_utf8=fr.UTF-8
+          else
+            # None found.
+            gt_cv_locale_fr_utf8=none
+          fi
+        fi
+      fi
+    fi
+    rm -fr conftest*
+  ])
+  LOCALE_FR_UTF8=$gt_cv_locale_fr_utf8
+  AC_SUBST([LOCALE_FR_UTF8])
+])
diff --git a/gl/m4/locale-ja.m4 b/gl/m4/locale-ja.m4
new file mode 100644
index 0000000..40b4d65
--- /dev/null
+++ b/gl/m4/locale-ja.m4
@@ -0,0 +1,110 @@
+# locale-ja.m4 serial 8
+dnl Copyright (C) 2003, 2005-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl Determine the name of a japanese locale with EUC-JP encoding.
+AC_DEFUN([gt_LOCALE_JA],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AM_LANGINFO_CODESET])
+  AC_CACHE_CHECK([for a traditional japanese locale], [gt_cv_locale_ja], [
+    AC_LANG_CONFTEST([AC_LANG_SOURCE([
+changequote(,)dnl
+#include <locale.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main ()
+{
+  const char *p;
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.
+     On MirBSD 10, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "UTF-8".  */
+#if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0
+        || strcmp (cs, "UTF-8") == 0)
+      return 1;
+  }
+#endif
+#ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+#endif
+  /* Check whether MB_CUR_MAX is > 1.  This excludes the dysfunctional locales
+     on Cygwin 1.5.x.  */
+  if (MB_CUR_MAX == 1)
+    return 1;
+  /* Check whether in a month name, no byte in the range 0x80..0x9F occurs.
+     This excludes the UTF-8 encoding (except on MirBSD).  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1;
+  for (p = buf; *p != '\0'; p++)
+    if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0)
+      return 1;
+  return 0;
+}
+changequote([,])dnl
+      ])])
+    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the AIX locale name.
+      if (LC_ALL=ja_JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_ja=ja_JP
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=ja_JP.EUC-JP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_ja=ja_JP.EUC-JP
+        else
+          # Test for the HP-UX, OSF/1, NetBSD locale name.
+          if (LC_ALL=ja_JP.eucJP LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+            gt_cv_locale_ja=ja_JP.eucJP
+          else
+            # Test for the IRIX, FreeBSD locale name.
+            if (LC_ALL=ja_JP.EUC LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+              gt_cv_locale_ja=ja_JP.EUC
+            else
+              # Test for the Solaris 7 locale name.
+              if (LC_ALL=ja LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+                gt_cv_locale_ja=ja
+              else
+                # Special test for NetBSD 1.6.
+                if test -f /usr/share/locale/ja_JP.eucJP/LC_CTYPE; then
+                  gt_cv_locale_ja=ja_JP.eucJP
+                else
+                  # None found.
+                  gt_cv_locale_ja=none
+                fi
+              fi
+            fi
+          fi
+        fi
+      fi
+    fi
+    rm -fr conftest*
+  ])
+  LOCALE_JA=$gt_cv_locale_ja
+  AC_SUBST([LOCALE_JA])
+])
diff --git a/gl/m4/locale-zh.m4 b/gl/m4/locale-zh.m4
new file mode 100644
index 0000000..81c2e2b
--- /dev/null
+++ b/gl/m4/locale-zh.m4
@@ -0,0 +1,95 @@
+# locale-zh.m4 serial 7
+dnl Copyright (C) 2003, 2005-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+dnl Determine the name of a chinese locale with GB18030 encoding.
+AC_DEFUN([gt_LOCALE_ZH_CN],
+[
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_REQUIRE([AM_LANGINFO_CODESET])
+  AC_CACHE_CHECK([for a transitional chinese locale], [gt_cv_locale_zh_CN], [
+    AC_LANG_CONFTEST([AC_LANG_SOURCE([
+changequote(,)dnl
+#include <locale.h>
+#include <stdlib.h>
+#include <time.h>
+#if HAVE_LANGINFO_CODESET
+# include <langinfo.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+struct tm t;
+char buf[16];
+int main ()
+{
+  const char *p;
+  /* Check whether the given locale name is recognized by the system.  */
+  if (setlocale (LC_ALL, "") == NULL) return 1;
+  /* Check whether nl_langinfo(CODESET) is nonempty and not "ASCII" or "646".
+     On MacOS X 10.3.5 (Darwin 7.5) in the fr_FR locale, nl_langinfo(CODESET)
+     is empty, and the behaviour of Tcl 8.4 in this locale is not useful.
+     On OpenBSD 4.0, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "646". In this situation,
+     some unit tests fail.
+     On MirBSD 10, when an unsupported locale is specified, setlocale()
+     succeeds but then nl_langinfo(CODESET) is "UTF-8".  */
+#if HAVE_LANGINFO_CODESET
+  {
+    const char *cs = nl_langinfo (CODESET);
+    if (cs[0] == '\0' || strcmp (cs, "ASCII") == 0 || strcmp (cs, "646") == 0
+        || strcmp (cs, "UTF-8") == 0)
+      return 1;
+  }
+#endif
+#ifdef __CYGWIN__
+  /* On Cygwin, avoid locale names without encoding suffix, because the
+     locale_charset() function relies on the encoding suffix.  Note that
+     LC_ALL is set on the command line.  */
+  if (strchr (getenv ("LC_ALL"), '.') == NULL) return 1;
+#endif
+  /* Check whether in a month name, no byte in the range 0x80..0x9F occurs.
+     This excludes the UTF-8 encoding (except on MirBSD).  */
+  t.tm_year = 1975 - 1900; t.tm_mon = 2 - 1; t.tm_mday = 4;
+  if (strftime (buf, sizeof (buf), "%B", &t) < 2) return 1;
+  for (p = buf; *p != '\0'; p++)
+    if ((unsigned char) *p >= 0x80 && (unsigned char) *p < 0xa0)
+      return 1;
+  /* Check whether a typical GB18030 multibyte sequence is recognized as a
+     single wide character.  This excludes the GB2312 and GBK encodings.  */
+  if (mblen ("\203\062\332\066", 5) != 4)
+    return 1;
+  return 0;
+}
+changequote([,])dnl
+      ])])
+    if AC_TRY_EVAL([ac_link]) && test -s conftest$ac_exeext; then
+      # Setting LC_ALL is not enough. Need to set LC_TIME to empty, because
+      # otherwise on MacOS X 10.3.5 the LC_TIME=C from the beginning of the
+      # configure script would override the LC_ALL setting. Likewise for
+      # LC_CTYPE, which is also set at the beginning of the configure script.
+      # Test for the locale name without encoding suffix.
+      if (LC_ALL=zh_CN LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+        gt_cv_locale_zh_CN=zh_CN
+      else
+        # Test for the locale name with explicit encoding suffix.
+        if (LC_ALL=zh_CN.GB18030 LC_TIME= LC_CTYPE= ./conftest; exit) 2>/dev/null; then
+          gt_cv_locale_zh_CN=zh_CN.GB18030
+        else
+          # None found.
+          gt_cv_locale_zh_CN=none
+        fi
+      fi
+    else
+      # If there was a link error, due to mblen(), the system is so old that
+      # it certainly doesn't have a chinese locale.
+      gt_cv_locale_zh_CN=none
+    fi
+    rm -fr conftest*
+  ])
+  LOCALE_ZH_CN=$gt_cv_locale_zh_CN
+  AC_SUBST([LOCALE_ZH_CN])
+])
diff --git a/gl/m4/longlong.m4 b/gl/m4/longlong.m4
new file mode 100644
index 0000000..a4d95aa
--- /dev/null
+++ b/gl/m4/longlong.m4
@@ -0,0 +1,106 @@
+# longlong.m4 serial 14
+dnl Copyright (C) 1999-2007, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert.
+
+# Define HAVE_LONG_LONG_INT if 'long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'long long int' exists but is only 32 bits large
+# (as on some very old compilers), HAVE_LONG_LONG_INT will not be
+# defined. In this case you can treat 'long long int' like 'long int'.
+
+AC_DEFUN([AC_TYPE_LONG_LONG_INT],
+[
+  AC_CACHE_CHECK([for long long int], [ac_cv_type_long_long_int],
+    [AC_LINK_IFELSE(
+       [_AC_TYPE_LONG_LONG_SNIPPET],
+       [dnl This catches a bug in Tandem NonStop Kernel (OSS) cc -O circa 2004.
+        dnl If cross compiling, assume the bug isn't important, since
+        dnl nobody cross compiles for this platform as far as we know.
+        AC_RUN_IFELSE(
+          [AC_LANG_PROGRAM(
+             [[@%:@include <limits.h>
+               @%:@ifndef LLONG_MAX
+               @%:@ define HALF \
+                        (1LL << (sizeof (long long int) * CHAR_BIT - 2))
+               @%:@ define LLONG_MAX (HALF - 1 + HALF)
+               @%:@endif]],
+             [[long long int n = 1;
+               int i;
+               for (i = 0; ; i++)
+                 {
+                   long long int m = n << i;
+                   if (m >> i != n)
+                     return 1;
+                   if (LLONG_MAX / 2 < m)
+                     break;
+                 }
+               return 0;]])],
+          [ac_cv_type_long_long_int=yes],
+          [ac_cv_type_long_long_int=no],
+          [ac_cv_type_long_long_int=yes])],
+       [ac_cv_type_long_long_int=no])])
+  if test $ac_cv_type_long_long_int = yes; then
+    AC_DEFINE([HAVE_LONG_LONG_INT], [1],
+      [Define to 1 if the system has the type `long long int'.])
+  fi
+])
+
+# Define HAVE_UNSIGNED_LONG_LONG_INT if 'unsigned long long int' works.
+# This fixes a bug in Autoconf 2.61, but can be removed once we
+# assume 2.62 everywhere.
+
+# Note: If the type 'unsigned long long int' exists but is only 32 bits
+# large (as on some very old compilers), AC_TYPE_UNSIGNED_LONG_LONG_INT
+# will not be defined. In this case you can treat 'unsigned long long int'
+# like 'unsigned long int'.
+
+AC_DEFUN([AC_TYPE_UNSIGNED_LONG_LONG_INT],
+[
+  AC_CACHE_CHECK([for unsigned long long int],
+    [ac_cv_type_unsigned_long_long_int],
+    [AC_LINK_IFELSE(
+       [_AC_TYPE_LONG_LONG_SNIPPET],
+       [ac_cv_type_unsigned_long_long_int=yes],
+       [ac_cv_type_unsigned_long_long_int=no])])
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+    AC_DEFINE([HAVE_UNSIGNED_LONG_LONG_INT], [1],
+      [Define to 1 if the system has the type `unsigned long long int'.])
+  fi
+])
+
+# Expands to a C program that can be used to test for simultaneous support
+# of 'long long' and 'unsigned long long'. We don't want to say that
+# 'long long' is available if 'unsigned long long' is not, or vice versa,
+# because too many programs rely on the symmetry between signed and unsigned
+# integer types (excluding 'bool').
+AC_DEFUN([_AC_TYPE_LONG_LONG_SNIPPET],
+[
+  AC_LANG_PROGRAM(
+    [[/* For now, do not test the preprocessor; as of 2007 there are too many
+         implementations with broken preprocessors.  Perhaps this can
+         be revisited in 2012.  In the meantime, code should not expect
+         #if to work with literals wider than 32 bits.  */
+      /* Test literals.  */
+      long long int ll = 9223372036854775807ll;
+      long long int nll = -9223372036854775807LL;
+      unsigned long long int ull = 18446744073709551615ULL;
+      /* Test constant expressions.   */
+      typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
+                     ? 1 : -1)];
+      typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
+                     ? 1 : -1)];
+      int i = 63;]],
+    [[/* Test availability of runtime routines for shift and division.  */
+      long long int llmax = 9223372036854775807ll;
+      unsigned long long int ullmax = 18446744073709551615ull;
+      return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
+              | (llmax / ll) | (llmax % ll)
+              | (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
+              | (ullmax / ull) | (ullmax % ull));]])
+])
diff --git a/gl/m4/malloc.m4 b/gl/m4/malloc.m4
new file mode 100644
index 0000000..8094444
--- /dev/null
+++ b/gl/m4/malloc.m4
@@ -0,0 +1,66 @@
+# malloc.m4 serial 12
+dnl Copyright (C) 2007, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# gl_FUNC_MALLOC_GNU
+# ------------------
+# Test whether 'malloc (0)' is handled like in GNU libc, and replace malloc if
+# it is not.
+AC_DEFUN([gl_FUNC_MALLOC_GNU],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  dnl _AC_FUNC_MALLOC_IF is defined in Autoconf.
+  _AC_FUNC_MALLOC_IF(
+    [AC_DEFINE([HAVE_MALLOC_GNU], [1],
+               [Define to 1 if your system has a GNU libc compatible 'malloc'
+                function, and to 0 otherwise.])],
+    [AC_DEFINE([HAVE_MALLOC_GNU], [0])
+     gl_REPLACE_MALLOC
+    ])
+])
+
+# gl_FUNC_MALLOC_POSIX
+# --------------------
+# Test whether 'malloc' is POSIX compliant (sets errno to ENOMEM when it
+# fails), and replace malloc if it is not.
+AC_DEFUN([gl_FUNC_MALLOC_POSIX],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  AC_REQUIRE([gl_CHECK_MALLOC_POSIX])
+  if test $gl_cv_func_malloc_posix = yes; then
+    AC_DEFINE([HAVE_MALLOC_POSIX], [1],
+      [Define if the 'malloc' function is POSIX compliant.])
+  else
+    gl_REPLACE_MALLOC
+  fi
+])
+
+# Test whether malloc, realloc, calloc are POSIX compliant,
+# Set gl_cv_func_malloc_posix to yes or no accordingly.
+AC_DEFUN([gl_CHECK_MALLOC_POSIX],
+[
+  AC_CACHE_CHECK([whether malloc, realloc, calloc are POSIX compliant],
+    [gl_cv_func_malloc_posix],
+    [
+      dnl It is too dangerous to try to allocate a large amount of memory:
+      dnl some systems go to their knees when you do that. So assume that
+      dnl all Unix implementations of the function are POSIX compliant.
+      AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[]],
+           [[#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+             choke me
+             #endif
+            ]])],
+        [gl_cv_func_malloc_posix=yes],
+        [gl_cv_func_malloc_posix=no])
+    ])
+])
+
+AC_DEFUN([gl_REPLACE_MALLOC],
+[
+  AC_LIBOBJ([malloc])
+  REPLACE_MALLOC=1
+])
diff --git a/gl/m4/mbrtowc.m4 b/gl/m4/mbrtowc.m4
new file mode 100644
index 0000000..c07da11
--- /dev/null
+++ b/gl/m4/mbrtowc.m4
@@ -0,0 +1,511 @@
+# mbrtowc.m4 serial 21
+dnl Copyright (C) 2001-2002, 2004-2005, 2008-2011 Free Software Foundation,
+dnl Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_MBRTOWC],
+[
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+
+  AC_REQUIRE([AC_TYPE_MBSTATE_T])
+  gl_MBSTATE_T_BROKEN
+
+  AC_CHECK_FUNCS_ONCE([mbrtowc])
+  if test $ac_cv_func_mbrtowc = no; then
+    HAVE_MBRTOWC=0
+  else
+    if test $REPLACE_MBSTATE_T = 1; then
+      REPLACE_MBRTOWC=1
+    else
+      gl_MBRTOWC_NULL_ARG1
+      gl_MBRTOWC_NULL_ARG2
+      gl_MBRTOWC_RETVAL
+      gl_MBRTOWC_NUL_RETVAL
+      case "$gl_cv_func_mbrtowc_null_arg1" in
+        *yes) ;;
+        *) AC_DEFINE([MBRTOWC_NULL_ARG1_BUG], [1],
+             [Define if the mbrtowc function has the NULL pwc argument bug.])
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+      case "$gl_cv_func_mbrtowc_null_arg2" in
+        *yes) ;;
+        *) AC_DEFINE([MBRTOWC_NULL_ARG2_BUG], [1],
+             [Define if the mbrtowc function has the NULL string argument bug.])
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+      case "$gl_cv_func_mbrtowc_retval" in
+        *yes) ;;
+        *) AC_DEFINE([MBRTOWC_RETVAL_BUG], [1],
+             [Define if the mbrtowc function returns a wrong return value.])
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+      case "$gl_cv_func_mbrtowc_nul_retval" in
+        *yes) ;;
+        *) AC_DEFINE([MBRTOWC_NUL_RETVAL_BUG], [1],
+             [Define if the mbrtowc function does not return 0 for a NUL character.])
+           REPLACE_MBRTOWC=1
+           ;;
+      esac
+    fi
+  fi
+  if test $HAVE_MBRTOWC = 0 || test $REPLACE_MBRTOWC = 1; then
+    gl_REPLACE_WCHAR_H
+    AC_LIBOBJ([mbrtowc])
+    gl_PREREQ_MBRTOWC
+  fi
+])
+
+dnl Test whether mbsinit() and mbrtowc() need to be overridden in a way that
+dnl redefines the semantics of the given mbstate_t type.
+dnl Result is REPLACE_MBSTATE_T.
+dnl When this is set to 1, we replace both mbsinit() and mbrtowc(), in order to
+dnl avoid inconsistencies.
+
+AC_DEFUN([gl_MBSTATE_T_BROKEN],
+[
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+
+  AC_REQUIRE([AC_TYPE_MBSTATE_T])
+  AC_CHECK_FUNCS_ONCE([mbsinit])
+  AC_CHECK_FUNCS_ONCE([mbrtowc])
+  if test $ac_cv_func_mbsinit = yes && test $ac_cv_func_mbrtowc = yes; then
+    gl_MBRTOWC_INCOMPLETE_STATE
+    gl_MBRTOWC_SANITYCHECK
+    REPLACE_MBSTATE_T=0
+    case "$gl_cv_func_mbrtowc_incomplete_state" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+    case "$gl_cv_func_mbrtowc_sanitycheck" in
+      *yes) ;;
+      *) REPLACE_MBSTATE_T=1 ;;
+    esac
+  else
+    REPLACE_MBSTATE_T=1
+  fi
+  if test $REPLACE_MBSTATE_T = 1; then
+    gl_REPLACE_WCHAR_H
+  fi
+])
+
+dnl Test whether mbrtowc puts the state into non-initial state when parsing an
+dnl incomplete multibyte character.
+dnl Result is gl_cv_func_mbrtowc_incomplete_state.
+
+AC_DEFUN([gl_MBRTOWC_INCOMPLETE_STATE],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_JA])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtowc handles incomplete characters],
+    [gl_cv_func_mbrtowc_incomplete_state],
+    [
+      dnl Initial guess, used when cross-compiling or when no suitable locale
+      dnl is present.
+changequote(,)dnl
+      case "$host_os" in
+                     # Guess no on AIX and OSF/1.
+        aix* | osf*) gl_cv_func_mbrtowc_incomplete_state="guessing no" ;;
+                     # Guess yes otherwise.
+        *)           gl_cv_func_mbrtowc_incomplete_state="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_JA != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      const char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        if (mbsinit (&state))
+          return 1;
+    }
+  return 0;
+}]])],
+          [gl_cv_func_mbrtowc_incomplete_state=yes],
+          [gl_cv_func_mbrtowc_incomplete_state=no],
+          [:])
+      fi
+    ])
+])
+
+dnl Test whether mbrtowc works not worse than mbtowc.
+dnl Result is gl_cv_func_mbrtowc_sanitycheck.
+
+AC_DEFUN([gl_MBRTOWC_SANITYCHECK],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_ZH_CN])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtowc works as well as mbtowc],
+    [gl_cv_func_mbrtowc_sanitycheck],
+    [
+      dnl Initial guess, used when cross-compiling or when no suitable locale
+      dnl is present.
+changequote(,)dnl
+      case "$host_os" in
+                    # Guess no on Solaris 8.
+        solaris2.8) gl_cv_func_mbrtowc_sanitycheck="guessing no" ;;
+                    # Guess yes otherwise.
+        *)          gl_cv_func_mbrtowc_sanitycheck="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_ZH_CN != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 8:
+     mbrtowc returns 2, and sets wc to 0x00F0.
+     mbtowc returns 4 (correct) and sets wc to 0x5EDC.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 3, 6, &state) != 4
+          && mbtowc (&wc, input + 3, 6) == 4)
+        return 1;
+    }
+  return 0;
+}]])],
+          [gl_cv_func_mbrtowc_sanitycheck=yes],
+          [gl_cv_func_mbrtowc_sanitycheck=no],
+          [:])
+      fi
+    ])
+])
+
+dnl Test whether mbrtowc supports a NULL pwc argument correctly.
+dnl Result is gl_cv_func_mbrtowc_null_arg1.
+
+AC_DEFUN([gl_MBRTOWC_NULL_ARG1],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_FR_UTF8])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtowc handles a NULL pwc argument],
+    [gl_cv_func_mbrtowc_null_arg1],
+    [
+      dnl Initial guess, used when cross-compiling or when no suitable locale
+      dnl is present.
+changequote(,)dnl
+      case "$host_os" in
+                  # Guess no on Solaris.
+        solaris*) gl_cv_func_mbrtowc_null_arg1="guessing no" ;;
+                  # Guess yes otherwise.
+        *)        gl_cv_func_mbrtowc_null_arg1="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_FR_UTF8 != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  int result = 0;
+
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      char input[] = "\303\237er";
+      mbstate_t state;
+      wchar_t wc;
+      size_t ret;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      wc = (wchar_t) 0xBADFACE;
+      ret = mbrtowc (&wc, input, 5, &state);
+      if (ret != 2)
+        result |= 1;
+      if (!mbsinit (&state))
+        result |= 2;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      ret = mbrtowc (NULL, input, 5, &state);
+      if (ret != 2) /* Solaris 7 fails here: ret is -1.  */
+        result |= 4;
+      if (!mbsinit (&state))
+        result |= 8;
+    }
+  return result;
+}]])],
+          [gl_cv_func_mbrtowc_null_arg1=yes],
+          [gl_cv_func_mbrtowc_null_arg1=no],
+          [:])
+      fi
+    ])
+])
+
+dnl Test whether mbrtowc supports a NULL string argument correctly.
+dnl Result is gl_cv_func_mbrtowc_null_arg2.
+
+AC_DEFUN([gl_MBRTOWC_NULL_ARG2],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_FR_UTF8])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtowc handles a NULL string argument],
+    [gl_cv_func_mbrtowc_null_arg2],
+    [
+      dnl Initial guess, used when cross-compiling or when no suitable locale
+      dnl is present.
+changequote(,)dnl
+      case "$host_os" in
+              # Guess no on OSF/1.
+        osf*) gl_cv_func_mbrtowc_null_arg2="guessing no" ;;
+              # Guess yes otherwise.
+        *)    gl_cv_func_mbrtowc_null_arg2="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_FR_UTF8 != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      mbstate_t state;
+      wchar_t wc;
+      int ret;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      wc = (wchar_t) 0xBADFACE;
+      mbrtowc (&wc, NULL, 5, &state);
+      /* Check that wc was not modified.  */
+      if (wc != (wchar_t) 0xBADFACE)
+        return 1;
+    }
+  return 0;
+}]])],
+          [gl_cv_func_mbrtowc_null_arg2=yes],
+          [gl_cv_func_mbrtowc_null_arg2=no],
+          [:])
+      fi
+    ])
+])
+
+dnl Test whether mbrtowc, when parsing the end of a multibyte character,
+dnl correctly returns the number of bytes that were needed to complete the
+dnl character (not the total number of bytes of the multibyte character).
+dnl Result is gl_cv_func_mbrtowc_retval.
+
+AC_DEFUN([gl_MBRTOWC_RETVAL],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_FR_UTF8])
+  AC_REQUIRE([gt_LOCALE_JA])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtowc has a correct return value],
+    [gl_cv_func_mbrtowc_retval],
+    [
+      dnl Initial guess, used when cross-compiling or when no suitable locale
+      dnl is present.
+changequote(,)dnl
+      case "$host_os" in
+                          # Guess no on HP-UX and Solaris.
+        hpux* | solaris*) gl_cv_func_mbrtowc_retval="guessing no" ;;
+                          # Guess yes otherwise.
+        *)                gl_cv_func_mbrtowc_retval="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  int result = 0;
+  /* This fails on Solaris.  */
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      char input[] = "B\303\274\303\237er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        {
+          input[1] = '\0';
+          if (mbrtowc (&wc, input + 2, 5, &state) != 1)
+            result |= 1;
+        }
+    }
+  /* This fails on HP-UX 11.11.  */
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      char input[] = "B\217\253\344\217\251\316er"; /* "Büßer" */
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, input + 1, 1, &state) == (size_t)(-2))
+        {
+          input[1] = '\0';
+          if (mbrtowc (&wc, input + 2, 5, &state) != 2)
+            result |= 2;
+        }
+    }
+  return result;
+}]])],
+          [gl_cv_func_mbrtowc_retval=yes],
+          [gl_cv_func_mbrtowc_retval=no],
+          [:])
+      fi
+    ])
+])
+
+dnl Test whether mbrtowc, when parsing a NUL character, correctly returns 0.
+dnl Result is gl_cv_func_mbrtowc_nul_retval.
+
+AC_DEFUN([gl_MBRTOWC_NUL_RETVAL],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([gt_LOCALE_ZH_CN])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  AC_CACHE_CHECK([whether mbrtowc returns 0 when parsing a NUL character],
+    [gl_cv_func_mbrtowc_nul_retval],
+    [
+      dnl Initial guess, used when cross-compiling or when no suitable locale
+      dnl is present.
+changequote(,)dnl
+      case "$host_os" in
+                       # Guess no on Solaris 8 and 9.
+        solaris2.[89]) gl_cv_func_mbrtowc_nul_retval="guessing no" ;;
+                       # Guess yes otherwise.
+        *)             gl_cv_func_mbrtowc_nul_retval="guessing yes" ;;
+      esac
+changequote([,])dnl
+      if test $LOCALE_ZH_CN != none; then
+        AC_RUN_IFELSE(
+          [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  /* This fails on Solaris 8 and 9.  */
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      mbstate_t state;
+      wchar_t wc;
+
+      memset (&state, '\0', sizeof (mbstate_t));
+      if (mbrtowc (&wc, "", 1, &state) != 0)
+        return 1;
+    }
+  return 0;
+}]])],
+          [gl_cv_func_mbrtowc_nul_retval=yes],
+          [gl_cv_func_mbrtowc_nul_retval=no],
+          [:])
+      fi
+    ])
+])
+
+# Prerequisites of lib/mbrtowc.c.
+AC_DEFUN([gl_PREREQ_MBRTOWC], [
+  :
+])
+
+
+dnl From Paul Eggert
+
+dnl This is an override of an autoconf macro.
+
+AC_DEFUN([AC_FUNC_MBRTOWC],
+[
+  dnl Same as AC_FUNC_MBRTOWC in autoconf-2.60.
+  AC_CACHE_CHECK([whether mbrtowc and mbstate_t are properly declared],
+    gl_cv_func_mbrtowc,
+    [AC_LINK_IFELSE(
+       [AC_LANG_PROGRAM(
+            [[/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be
+                 included before <wchar.h>.
+                 BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h>
+                 must be included before <wchar.h>.  */
+              #include <stddef.h>
+              #include <stdio.h>
+              #include <time.h>
+              #include <wchar.h>]],
+            [[wchar_t wc;
+              char const s[] = "";
+              size_t n = 1;
+              mbstate_t state;
+              return ! (sizeof state && (mbrtowc) (&wc, s, n, &state));]])],
+       gl_cv_func_mbrtowc=yes,
+       gl_cv_func_mbrtowc=no)])
+  if test $gl_cv_func_mbrtowc = yes; then
+    AC_DEFINE([HAVE_MBRTOWC], [1],
+      [Define to 1 if mbrtowc and mbstate_t are properly declared.])
+  fi
+])
diff --git a/gl/m4/mbsinit.m4 b/gl/m4/mbsinit.m4
new file mode 100644
index 0000000..03b3144
--- /dev/null
+++ b/gl/m4/mbsinit.m4
@@ -0,0 +1,32 @@
+# mbsinit.m4 serial 4
+dnl Copyright (C) 2008, 2010-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_MBSINIT],
+[
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+
+  AC_REQUIRE([AC_TYPE_MBSTATE_T])
+  gl_MBSTATE_T_BROKEN
+
+  AC_CHECK_FUNCS_ONCE([mbsinit])
+  if test $ac_cv_func_mbsinit = no; then
+    HAVE_MBSINIT=0
+  else
+    if test $REPLACE_MBSTATE_T = 1; then
+      REPLACE_MBSINIT=1
+    fi
+  fi
+  if test $HAVE_MBSINIT = 0 || test $REPLACE_MBSINIT = 1; then
+    gl_REPLACE_WCHAR_H
+    AC_LIBOBJ([mbsinit])
+    gl_PREREQ_MBSINIT
+  fi
+])
+
+# Prerequisites of lib/mbsinit.c.
+AC_DEFUN([gl_PREREQ_MBSINIT], [
+  :
+])
diff --git a/gl/m4/mbstate_t.m4 b/gl/m4/mbstate_t.m4
new file mode 100644
index 0000000..f7c46b8
--- /dev/null
+++ b/gl/m4/mbstate_t.m4
@@ -0,0 +1,41 @@
+# mbstate_t.m4 serial 13
+dnl Copyright (C) 2000-2002, 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# From Paul Eggert.
+
+# BeOS 5 has <wchar.h> but does not define mbstate_t,
+# so you can't declare an object of that type.
+# Check for this incompatibility with Standard C.
+
+# AC_TYPE_MBSTATE_T
+# -----------------
+AC_DEFUN([AC_TYPE_MBSTATE_T],
+[
+   AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS]) dnl for HP-UX 11.11
+
+   AC_CACHE_CHECK([for mbstate_t], [ac_cv_type_mbstate_t],
+     [AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [AC_INCLUDES_DEFAULT[
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>]],
+           [[mbstate_t x; return sizeof x;]])],
+        [ac_cv_type_mbstate_t=yes],
+        [ac_cv_type_mbstate_t=no])])
+   if test $ac_cv_type_mbstate_t = yes; then
+     AC_DEFINE([HAVE_MBSTATE_T], [1],
+               [Define to 1 if <wchar.h> declares mbstate_t.])
+   else
+     AC_DEFINE([mbstate_t], [int],
+               [Define to a type if <wchar.h> does not define.])
+   fi
+])
diff --git a/gl/m4/multiarch.m4 b/gl/m4/multiarch.m4
new file mode 100644
index 0000000..691d892
--- /dev/null
+++ b/gl/m4/multiarch.m4
@@ -0,0 +1,62 @@
+# multiarch.m4 serial 6
+dnl Copyright (C) 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Determine whether the compiler is or may be producing universal binaries.
+#
+# On MacOS X 10.5 and later systems, the user can create libraries and
+# executables that work on multiple system types--known as "fat" or
+# "universal" binaries--by specifying multiple '-arch' options to the
+# compiler but only a single '-arch' option to the preprocessor.  Like
+# this:
+#
+#     ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+#                 CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
+#                 CPP="gcc -E" CXXCPP="g++ -E"
+#
+# Detect this situation and set APPLE_UNIVERSAL_BUILD accordingly.
+
+AC_DEFUN_ONCE([gl_MULTIARCH],
+[
+  dnl Code similar to autoconf-2.63 AC_C_BIGENDIAN.
+  gl_cv_c_multiarch=no
+  AC_COMPILE_IFELSE(
+    [AC_LANG_SOURCE(
+      [[#ifndef __APPLE_CC__
+         not a universal capable compiler
+        #endif
+        typedef int dummy;
+      ]])],
+    [
+     dnl Check for potential -arch flags.  It is not universal unless
+     dnl there are at least two -arch flags with different values.
+     arch=
+     prev=
+     for word in ${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}; do
+       if test -n "$prev"; then
+         case $word in
+           i?86 | x86_64 | ppc | ppc64)
+             if test -z "$arch" || test "$arch" = "$word"; then
+               arch="$word"
+             else
+               gl_cv_c_multiarch=yes
+             fi
+             ;;
+         esac
+         prev=
+       else
+         if test "x$word" = "x-arch"; then
+           prev=arch
+         fi
+       fi
+     done
+    ])
+  if test $gl_cv_c_multiarch = yes; then
+    APPLE_UNIVERSAL_BUILD=1
+  else
+    APPLE_UNIVERSAL_BUILD=0
+  fi
+  AC_SUBST([APPLE_UNIVERSAL_BUILD])
+])
diff --git a/gl/m4/nl_langinfo.m4 b/gl/m4/nl_langinfo.m4
new file mode 100644
index 0000000..ca9d28d
--- /dev/null
+++ b/gl/m4/nl_langinfo.m4
@@ -0,0 +1,52 @@
+# nl_langinfo.m4 serial 4
+dnl Copyright (C) 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_NL_LANGINFO],
+[
+  AC_REQUIRE([gl_LANGINFO_H_DEFAULTS])
+  AC_REQUIRE([gl_LANGINFO_H])
+  AC_CHECK_FUNCS_ONCE([nl_langinfo])
+  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+  if test $ac_cv_func_nl_langinfo = yes; then
+    # On Irix 6.5, YESEXPR is defined, but nl_langinfo(YESEXPR) is broken.
+    AC_CACHE_CHECK([whether YESEXPR works],
+      [gl_cv_func_nl_langinfo_yesexpr_works],
+      [AC_RUN_IFELSE(
+         [AC_LANG_PROGRAM([[#include <langinfo.h>
+]], [[return !*nl_langinfo(YESEXPR);
+]])],
+         [gl_cv_func_nl_langinfo_yesexpr_works=yes],
+         [gl_cv_func_nl_langinfo_yesexpr_works=no],
+         [
+         case "$host_os" in
+                   # Guess no on irix systems.
+           irix*)  gl_cv_func_nl_langinfo_yesexpr_works="guessing no";;
+                   # Guess yes elsewhere.
+           *)      gl_cv_func_nl_langinfo_yesexpr_works="guessing yes";;
+         esac
+         ])
+      ])
+    case $gl_cv_func_nl_langinfo_yesexpr_works in
+      *yes) FUNC_NL_LANGINFO_YESEXPR_WORKS=1 ;;
+      *)    FUNC_NL_LANGINFO_YESEXPR_WORKS=0 ;;
+    esac
+    AC_DEFINE_UNQUOTED([FUNC_NL_LANGINFO_YESEXPR_WORKS],
+      [$FUNC_NL_LANGINFO_YESEXPR_WORKS],
+      [Define to 1 if nl_langinfo (YESEXPR) returns a non-empty string.])
+    if test $HAVE_LANGINFO_CODESET = 1 && test $HAVE_LANGINFO_ERA = 1 \
+        && test $FUNC_NL_LANGINFO_YESEXPR_WORKS = 1; then
+      :
+    else
+      REPLACE_NL_LANGINFO=1
+      AC_DEFINE([REPLACE_NL_LANGINFO], [1],
+        [Define if nl_langinfo exists but is overridden by gnulib.])
+      AC_LIBOBJ([nl_langinfo])
+    fi
+  else
+    HAVE_NL_LANGINFO=0
+    AC_LIBOBJ([nl_langinfo])
+  fi
+])
diff --git a/gl/m4/regex.m4 b/gl/m4/regex.m4
new file mode 100644
index 0000000..24198b5
--- /dev/null
+++ b/gl/m4/regex.m4
@@ -0,0 +1,225 @@
+# serial 58
+
+# Copyright (C) 1996-2001, 2003-2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+dnl Initially derived from code in GNU grep.
+dnl Mostly written by Jim Meyering.
+
+AC_PREREQ([2.50])
+
+AC_DEFUN([gl_REGEX],
+[
+  AC_ARG_WITH([included-regex],
+    [AS_HELP_STRING([--without-included-regex],
+                    [don't compile regex; this is the default on systems
+                     with recent-enough versions of the GNU C Library
+                     (use with caution on other systems).])])
+
+  case $with_included_regex in #(
+  yes|no) ac_use_included_regex=$with_included_regex
+        ;;
+  '')
+    # If the system regex support is good enough that it passes the
+    # following run test, then default to *not* using the included regex.c.
+    # If cross compiling, assume the test would fail and use the included
+    # regex.c.
+    AC_CACHE_CHECK([for working re_compile_pattern],
+                   [gl_cv_func_re_compile_pattern_working],
+      [AC_RUN_IFELSE(
+        [AC_LANG_PROGRAM(
+          [AC_INCLUDES_DEFAULT[
+           #include <locale.h>
+           #include <limits.h>
+           #include <regex.h>
+           ]],
+          [[int result = 0;
+            static struct re_pattern_buffer regex;
+            unsigned char folded_chars[UCHAR_MAX + 1];
+            int i;
+            const char *s;
+            struct re_registers regs;
+
+            /* http://sourceware.org/ml/libc-hacker/2006-09/msg00008.html
+               This test needs valgrind to catch the bug on Debian
+               GNU/Linux 3.1 x86, but it might catch the bug better
+               on other platforms and it shouldn't hurt to try the
+               test here.  */
+            if (setlocale (LC_ALL, "en_US.UTF-8"))
+              {
+                static char const pat[] = "insert into";
+                static char const data[] =
+                  "\xFF\0\x12\xA2\xAA\xC4\xB1,K\x12\xC4\xB1*\xACK";
+                re_set_syntax (RE_SYNTAX_GREP | RE_HAT_LISTS_NOT_NEWLINE
+                               | RE_ICASE);
+                memset (&regex, 0, sizeof regex);
+                s = re_compile_pattern (pat, sizeof pat - 1, &regex);
+                if (s)
+                  result |= 1;
+                else if (re_search (&regex, data, sizeof data - 1,
+                                    0, sizeof data - 1, &regs)
+                         != -1)
+                  result |= 1;
+                if (! setlocale (LC_ALL, "C"))
+                  return 1;
+              }
+
+            /* This test is from glibc bug 3957, reported by Andrew Mackey.  */
+            re_set_syntax (RE_SYNTAX_EGREP | RE_HAT_LISTS_NOT_NEWLINE);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("a[^x]b", 6, &regex);
+            if (s)
+              result |= 2;
+            /* This should fail, but succeeds for glibc-2.5.  */
+            else if (re_search (&regex, "a\nb", 3, 0, 3, &regs) != -1)
+              result |= 2;
+
+            /* This regular expression is from Spencer ere test number 75
+               in grep-2.3.  */
+            re_set_syntax (RE_SYNTAX_POSIX_EGREP);
+            memset (&regex, 0, sizeof regex);
+            for (i = 0; i <= UCHAR_MAX; i++)
+              folded_chars[i] = i;
+            regex.translate = folded_chars;
+            s = re_compile_pattern ("a[[:@:>@:]]b\n", 11, &regex);
+            /* This should fail with _Invalid character class name_ error.  */
+            if (!s)
+              result |= 4;
+
+            /* Ensure that [b-a] is diagnosed as invalid, when
+               using RE_NO_EMPTY_RANGES. */
+            re_set_syntax (RE_SYNTAX_POSIX_EGREP | RE_NO_EMPTY_RANGES);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("a[b-a]", 6, &regex);
+            if (s == 0)
+              result |= 8;
+
+            /* This should succeed, but does not for glibc-2.1.3.  */
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("{1", 2, &regex);
+            if (s)
+              result |= 8;
+
+            /* The following example is derived from a problem report
+               against gawk from Jorge Stolfi <stolfi at ic.unicamp.br>.  */
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("[an\371]*n", 7, &regex);
+            if (s)
+              result |= 8;
+            /* This should match, but does not for glibc-2.2.1.  */
+            else if (re_match (&regex, "an", 2, 0, &regs) != 2)
+              result |= 8;
+
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("x", 1, &regex);
+            if (s)
+              result |= 8;
+            /* glibc-2.2.93 does not work with a negative RANGE argument.  */
+            else if (re_search (&regex, "wxy", 3, 2, -2, &regs) != 1)
+              result |= 8;
+
+            /* The version of regex.c in older versions of gnulib
+               ignored RE_ICASE.  Detect that problem too.  */
+            re_set_syntax (RE_SYNTAX_EMACS | RE_ICASE);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("x", 1, &regex);
+            if (s)
+              result |= 16;
+            else if (re_search (&regex, "WXY", 3, 0, 3, &regs) < 0)
+              result |= 16;
+
+            /* Catch a bug reported by Vin Shelton in
+               http://lists.gnu.org/archive/html/bug-coreutils/2007-06/msg00089.html
+               */
+            re_set_syntax (RE_SYNTAX_POSIX_BASIC
+                           & ~RE_CONTEXT_INVALID_DUP
+                           & ~RE_NO_EMPTY_RANGES);
+            memset (&regex, 0, sizeof regex);
+            s = re_compile_pattern ("[[:alnum:]_-]\\\\+$", 16, &regex);
+            if (s)
+              result |= 32;
+
+            /* REG_STARTEND was added to glibc on 2004-01-15.
+               Reject older versions.  */
+            if (! REG_STARTEND)
+              result |= 64;
+
+#if 0
+            /* It would be nice to reject hosts whose regoff_t values are too
+               narrow (including glibc on hosts with 64-bit ptrdiff_t and
+               32-bit int), but we should wait until glibc implements this
+               feature.  Otherwise, support for equivalence classes and
+               multibyte collation symbols would always be broken except
+               when compiling --without-included-regex.   */
+            if (sizeof (regoff_t) < sizeof (ptrdiff_t)
+                || sizeof (regoff_t) < sizeof (ssize_t))
+              result |= 64;
+#endif
+
+            return result;
+          ]])],
+       [gl_cv_func_re_compile_pattern_working=yes],
+       [gl_cv_func_re_compile_pattern_working=no],
+       dnl When crosscompiling, assume it is not working.
+       [gl_cv_func_re_compile_pattern_working=no])])
+    case $gl_cv_func_re_compile_pattern_working in #(
+    yes) ac_use_included_regex=no;; #(
+    no) ac_use_included_regex=yes;;
+    esac
+    ;;
+  *) AC_MSG_ERROR([Invalid value for --with-included-regex: $with_included_regex])
+    ;;
+  esac
+
+  if test $ac_use_included_regex = yes; then
+    AC_DEFINE([_REGEX_LARGE_OFFSETS], [1],
+      [Define if you want regoff_t to be at least as wide POSIX requires.])
+    AC_DEFINE([re_syntax_options], [rpl_re_syntax_options],
+      [Define to rpl_re_syntax_options if the replacement should be used.])
+    AC_DEFINE([re_set_syntax], [rpl_re_set_syntax],
+      [Define to rpl_re_set_syntax if the replacement should be used.])
+    AC_DEFINE([re_compile_pattern], [rpl_re_compile_pattern],
+      [Define to rpl_re_compile_pattern if the replacement should be used.])
+    AC_DEFINE([re_compile_fastmap], [rpl_re_compile_fastmap],
+      [Define to rpl_re_compile_fastmap if the replacement should be used.])
+    AC_DEFINE([re_search], [rpl_re_search],
+      [Define to rpl_re_search if the replacement should be used.])
+    AC_DEFINE([re_search_2], [rpl_re_search_2],
+      [Define to rpl_re_search_2 if the replacement should be used.])
+    AC_DEFINE([re_match], [rpl_re_match],
+      [Define to rpl_re_match if the replacement should be used.])
+    AC_DEFINE([re_match_2], [rpl_re_match_2],
+      [Define to rpl_re_match_2 if the replacement should be used.])
+    AC_DEFINE([re_set_registers], [rpl_re_set_registers],
+      [Define to rpl_re_set_registers if the replacement should be used.])
+    AC_DEFINE([re_comp], [rpl_re_comp],
+      [Define to rpl_re_comp if the replacement should be used.])
+    AC_DEFINE([re_exec], [rpl_re_exec],
+      [Define to rpl_re_exec if the replacement should be used.])
+    AC_DEFINE([regcomp], [rpl_regcomp],
+      [Define to rpl_regcomp if the replacement should be used.])
+    AC_DEFINE([regexec], [rpl_regexec],
+      [Define to rpl_regexec if the replacement should be used.])
+    AC_DEFINE([regerror], [rpl_regerror],
+      [Define to rpl_regerror if the replacement should be used.])
+    AC_DEFINE([regfree], [rpl_regfree],
+      [Define to rpl_regfree if the replacement should be used.])
+    AC_LIBOBJ([regex])
+    gl_PREREQ_REGEX
+  fi
+])
+
+# Prerequisites of lib/regex.c and lib/regex_internal.c.
+AC_DEFUN([gl_PREREQ_REGEX],
+[
+  AC_REQUIRE([AC_USE_SYSTEM_EXTENSIONS])
+  AC_REQUIRE([AC_C_INLINE])
+  AC_REQUIRE([AC_C_RESTRICT])
+  AC_REQUIRE([AC_TYPE_MBSTATE_T])
+  AC_CHECK_HEADERS([libintl.h])
+  AC_CHECK_FUNCS_ONCE([isblank iswctype wcscoll])
+  AC_CHECK_DECLS([isblank], [], [], [#include <ctype.h>])
+])
diff --git a/gl/m4/ssize_t.m4 b/gl/m4/ssize_t.m4
new file mode 100644
index 0000000..d712752
--- /dev/null
+++ b/gl/m4/ssize_t.m4
@@ -0,0 +1,23 @@
+# ssize_t.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 2001-2003, 2006, 2010-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether ssize_t is defined.
+
+AC_DEFUN([gt_TYPE_SSIZE_T],
+[
+  AC_CACHE_CHECK([for ssize_t], [gt_cv_ssize_t],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <sys/types.h>]],
+          [[int x = sizeof (ssize_t *) + sizeof (ssize_t);
+            return !x;]])],
+       [gt_cv_ssize_t=yes], [gt_cv_ssize_t=no])])
+  if test $gt_cv_ssize_t = no; then
+    AC_DEFINE([ssize_t], [int],
+              [Define as a signed type of the same size as size_t.])
+  fi
+])
diff --git a/gl/m4/stdbool.m4 b/gl/m4/stdbool.m4
new file mode 100644
index 0000000..df10486
--- /dev/null
+++ b/gl/m4/stdbool.m4
@@ -0,0 +1,103 @@
+# Check for stdbool.h that conforms to C99.
+
+dnl Copyright (C) 2002-2006, 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+#serial 3
+
+# Prepare for substituting <stdbool.h> if it is not supported.
+
+AC_DEFUN([AM_STDBOOL_H],
+[
+  AC_REQUIRE([AC_HEADER_STDBOOL])
+
+  # Define two additional variables used in the Makefile substitution.
+
+  if test "$ac_cv_header_stdbool_h" = yes; then
+    STDBOOL_H=''
+  else
+    STDBOOL_H='stdbool.h'
+  fi
+  AC_SUBST([STDBOOL_H])
+
+  if test "$ac_cv_type__Bool" = yes; then
+    HAVE__BOOL=1
+  else
+    HAVE__BOOL=0
+  fi
+  AC_SUBST([HAVE__BOOL])
+])
+
+# AM_STDBOOL_H will be renamed to gl_STDBOOL_H in the future.
+AC_DEFUN([gl_STDBOOL_H], [AM_STDBOOL_H])
+
+# This version of the macro is needed in autoconf <= 2.67.  Autoconf has
+# it built in since 2.60, but we want the tweaks from the 2.68 version
+# to avoid rejecting xlc and clang due to relying on extensions.
+
+AC_DEFUN([AC_HEADER_STDBOOL],
+  [AC_CACHE_CHECK([for stdbool.h that conforms to C99],
+     [ac_cv_header_stdbool_h],
+     [AC_COMPILE_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[
+             #include <stdbool.h>
+             #ifndef bool
+              "error: bool is not defined"
+             #endif
+             #ifndef false
+              "error: false is not defined"
+             #endif
+             #if false
+              "error: false is not 0"
+             #endif
+             #ifndef true
+              "error: true is not defined"
+             #endif
+             #if true != 1
+              "error: true is not 1"
+             #endif
+             #ifndef __bool_true_false_are_defined
+              "error: __bool_true_false_are_defined is not defined"
+             #endif
+
+             struct s { _Bool s: 1; _Bool t; } s;
+
+             char a[true == 1 ? 1 : -1];
+             char b[false == 0 ? 1 : -1];
+             char c[__bool_true_false_are_defined == 1 ? 1 : -1];
+             char d[(bool) 0.5 == true ? 1 : -1];
+             /* See body of main program for 'e'.  */
+             char f[(_Bool) 0.0 == false ? 1 : -1];
+             char g[true];
+             char h[sizeof (_Bool)];
+             char i[sizeof s.t];
+             enum { j = false, k = true, l = false * true, m = true * 256 };
+             /* The following fails for
+                HP aC++/ANSI C B3910B A.05.55 [Dec 04 2003]. */
+             _Bool n[m];
+             char o[sizeof n == m * sizeof n[0] ? 1 : -1];
+             char p[-1 - (_Bool) 0 < 0 && -1 - (bool) 0 < 0 ? 1 : -1];
+             /* Catch a bug in an HP-UX C compiler.  See
+                http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+                http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+              */
+             _Bool q = true;
+             _Bool *pq = &q;
+           ]],
+           [[
+             bool e = &s;
+             *pq |= q;
+             *pq |= ! q;
+             /* Refer to every declared value, to avoid compiler optimizations.  */
+             return (!a + !b + !c + !d + !e + !f + !g + !h + !i + !!j + !k + !!l
+                     + !m + !n + !o + !p + !q + !pq);
+           ]])],
+        [ac_cv_header_stdbool_h=yes],
+        [ac_cv_header_stdbool_h=no])])
+   AC_CHECK_TYPES([_Bool])
+   if test $ac_cv_header_stdbool_h = yes; then
+     AC_DEFINE([HAVE_STDBOOL_H], [1], [Define to 1 if stdbool.h conforms to C99.])
+   fi])
diff --git a/gl/m4/stddef_h.m4 b/gl/m4/stddef_h.m4
new file mode 100644
index 0000000..1942b6a
--- /dev/null
+++ b/gl/m4/stddef_h.m4
@@ -0,0 +1,45 @@
+dnl A placeholder for POSIX 2008 <stddef.h>, for platforms that have issues.
+# stddef_h.m4 serial 3
+dnl Copyright (C) 2009-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_STDDEF_H],
+[
+  AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+  AC_REQUIRE([gt_TYPE_WCHAR_T])
+  if test $gt_cv_c_wchar_t = no; then
+    HAVE_WCHAR_T=0
+    STDDEF_H=stddef.h
+  fi
+  AC_CACHE_CHECK([whether NULL can be used in arbitrary expressions],
+    [gl_cv_decl_null_works],
+    [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stddef.h>
+      int test[2 * (sizeof NULL == sizeof (void *)) -1];
+]])],
+      [gl_cv_decl_null_works=yes],
+      [gl_cv_decl_null_works=no])])
+  if test $gl_cv_decl_null_works = no; then
+    REPLACE_NULL=1
+    STDDEF_H=stddef.h
+  fi
+  if test -n "$STDDEF_H"; then
+    gl_NEXT_HEADERS([stddef.h])
+  fi
+])
+
+AC_DEFUN([gl_STDDEF_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_STDDEF_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+])
+
+AC_DEFUN([gl_STDDEF_H_DEFAULTS],
+[
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  REPLACE_NULL=0;                AC_SUBST([REPLACE_NULL])
+  HAVE_WCHAR_T=1;                AC_SUBST([HAVE_WCHAR_T])
+  STDDEF_H='';                   AC_SUBST([STDDEF_H])
+])
diff --git a/gl/m4/stdint.m4 b/gl/m4/stdint.m4
new file mode 100644
index 0000000..26654c6
--- /dev/null
+++ b/gl/m4/stdint.m4
@@ -0,0 +1,474 @@
+# stdint.m4 serial 37
+dnl Copyright (C) 2001-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Paul Eggert and Bruno Haible.
+dnl Test whether <stdint.h> is supported or must be substituted.
+
+AC_DEFUN([gl_STDINT_H],
+[
+  AC_PREREQ([2.59])dnl
+
+  dnl Check for long long int and unsigned long long int.
+  AC_REQUIRE([AC_TYPE_LONG_LONG_INT])
+  if test $ac_cv_type_long_long_int = yes; then
+    HAVE_LONG_LONG_INT=1
+  else
+    HAVE_LONG_LONG_INT=0
+  fi
+  AC_SUBST([HAVE_LONG_LONG_INT])
+  AC_REQUIRE([AC_TYPE_UNSIGNED_LONG_LONG_INT])
+  if test $ac_cv_type_unsigned_long_long_int = yes; then
+    HAVE_UNSIGNED_LONG_LONG_INT=1
+  else
+    HAVE_UNSIGNED_LONG_LONG_INT=0
+  fi
+  AC_SUBST([HAVE_UNSIGNED_LONG_LONG_INT])
+
+  dnl Check for <inttypes.h>.
+  dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_inttypes_h.
+  if test $ac_cv_header_inttypes_h = yes; then
+    HAVE_INTTYPES_H=1
+  else
+    HAVE_INTTYPES_H=0
+  fi
+  AC_SUBST([HAVE_INTTYPES_H])
+
+  dnl Check for <sys/types.h>.
+  dnl AC_INCLUDES_DEFAULT defines $ac_cv_header_sys_types_h.
+  if test $ac_cv_header_sys_types_h = yes; then
+    HAVE_SYS_TYPES_H=1
+  else
+    HAVE_SYS_TYPES_H=0
+  fi
+  AC_SUBST([HAVE_SYS_TYPES_H])
+
+  gl_CHECK_NEXT_HEADERS([stdint.h])
+  if test $ac_cv_header_stdint_h = yes; then
+    HAVE_STDINT_H=1
+  else
+    HAVE_STDINT_H=0
+  fi
+  AC_SUBST([HAVE_STDINT_H])
+
+  dnl Now see whether we need a substitute <stdint.h>.
+  if test $ac_cv_header_stdint_h = yes; then
+    AC_CACHE_CHECK([whether stdint.h conforms to C99],
+      [gl_cv_header_working_stdint_h],
+      [gl_cv_header_working_stdint_h=no
+       AC_COMPILE_IFELSE([
+         AC_LANG_PROGRAM([[
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+/* Dragonfly defines WCHAR_MIN, WCHAR_MAX only in <wchar.h>.  */
+#if !(defined WCHAR_MIN && defined WCHAR_MAX)
+#error "WCHAR_MIN, WCHAR_MAX not defined in <stdint.h>"
+#endif
+]
+gl_STDINT_INCLUDES
+[
+#ifdef INT8_MAX
+int8_t a1 = INT8_MAX;
+int8_t a1min = INT8_MIN;
+#endif
+#ifdef INT16_MAX
+int16_t a2 = INT16_MAX;
+int16_t a2min = INT16_MIN;
+#endif
+#ifdef INT32_MAX
+int32_t a3 = INT32_MAX;
+int32_t a3min = INT32_MIN;
+#endif
+#ifdef INT64_MAX
+int64_t a4 = INT64_MAX;
+int64_t a4min = INT64_MIN;
+#endif
+#ifdef UINT8_MAX
+uint8_t b1 = UINT8_MAX;
+#else
+typedef int b1[(unsigned char) -1 != 255 ? 1 : -1];
+#endif
+#ifdef UINT16_MAX
+uint16_t b2 = UINT16_MAX;
+#endif
+#ifdef UINT32_MAX
+uint32_t b3 = UINT32_MAX;
+#endif
+#ifdef UINT64_MAX
+uint64_t b4 = UINT64_MAX;
+#endif
+int_least8_t c1 = INT8_C (0x7f);
+int_least8_t c1max = INT_LEAST8_MAX;
+int_least8_t c1min = INT_LEAST8_MIN;
+int_least16_t c2 = INT16_C (0x7fff);
+int_least16_t c2max = INT_LEAST16_MAX;
+int_least16_t c2min = INT_LEAST16_MIN;
+int_least32_t c3 = INT32_C (0x7fffffff);
+int_least32_t c3max = INT_LEAST32_MAX;
+int_least32_t c3min = INT_LEAST32_MIN;
+int_least64_t c4 = INT64_C (0x7fffffffffffffff);
+int_least64_t c4max = INT_LEAST64_MAX;
+int_least64_t c4min = INT_LEAST64_MIN;
+uint_least8_t d1 = UINT8_C (0xff);
+uint_least8_t d1max = UINT_LEAST8_MAX;
+uint_least16_t d2 = UINT16_C (0xffff);
+uint_least16_t d2max = UINT_LEAST16_MAX;
+uint_least32_t d3 = UINT32_C (0xffffffff);
+uint_least32_t d3max = UINT_LEAST32_MAX;
+uint_least64_t d4 = UINT64_C (0xffffffffffffffff);
+uint_least64_t d4max = UINT_LEAST64_MAX;
+int_fast8_t e1 = INT_FAST8_MAX;
+int_fast8_t e1min = INT_FAST8_MIN;
+int_fast16_t e2 = INT_FAST16_MAX;
+int_fast16_t e2min = INT_FAST16_MIN;
+int_fast32_t e3 = INT_FAST32_MAX;
+int_fast32_t e3min = INT_FAST32_MIN;
+int_fast64_t e4 = INT_FAST64_MAX;
+int_fast64_t e4min = INT_FAST64_MIN;
+uint_fast8_t f1 = UINT_FAST8_MAX;
+uint_fast16_t f2 = UINT_FAST16_MAX;
+uint_fast32_t f3 = UINT_FAST32_MAX;
+uint_fast64_t f4 = UINT_FAST64_MAX;
+#ifdef INTPTR_MAX
+intptr_t g = INTPTR_MAX;
+intptr_t gmin = INTPTR_MIN;
+#endif
+#ifdef UINTPTR_MAX
+uintptr_t h = UINTPTR_MAX;
+#endif
+intmax_t i = INTMAX_MAX;
+uintmax_t j = UINTMAX_MAX;
+
+#include <limits.h> /* for CHAR_BIT */
+#define TYPE_MINIMUM(t) \
+  ((t) ((t) 0 < (t) -1 ? (t) 0 : ~ TYPE_MAXIMUM (t)))
+#define TYPE_MAXIMUM(t) \
+  ((t) ((t) 0 < (t) -1 \
+        ? (t) -1 \
+        : ((((t) 1 << (sizeof (t) * CHAR_BIT - 2)) - 1) * 2 + 1)))
+struct s {
+  int check_PTRDIFF:
+      PTRDIFF_MIN == TYPE_MINIMUM (ptrdiff_t)
+      && PTRDIFF_MAX == TYPE_MAXIMUM (ptrdiff_t)
+      ? 1 : -1;
+  /* Detect bug in FreeBSD 6.0 / ia64.  */
+  int check_SIG_ATOMIC:
+      SIG_ATOMIC_MIN == TYPE_MINIMUM (sig_atomic_t)
+      && SIG_ATOMIC_MAX == TYPE_MAXIMUM (sig_atomic_t)
+      ? 1 : -1;
+  int check_SIZE: SIZE_MAX == TYPE_MAXIMUM (size_t) ? 1 : -1;
+  int check_WCHAR:
+      WCHAR_MIN == TYPE_MINIMUM (wchar_t)
+      && WCHAR_MAX == TYPE_MAXIMUM (wchar_t)
+      ? 1 : -1;
+  /* Detect bug in mingw.  */
+  int check_WINT:
+      WINT_MIN == TYPE_MINIMUM (wint_t)
+      && WINT_MAX == TYPE_MAXIMUM (wint_t)
+      ? 1 : -1;
+
+  /* Detect bugs in glibc 2.4 and Solaris 10 stdint.h, among others.  */
+  int check_UINT8_C:
+        (-1 < UINT8_C (0)) == (-1 < (uint_least8_t) 0) ? 1 : -1;
+  int check_UINT16_C:
+        (-1 < UINT16_C (0)) == (-1 < (uint_least16_t) 0) ? 1 : -1;
+
+  /* Detect bugs in OpenBSD 3.9 stdint.h.  */
+#ifdef UINT8_MAX
+  int check_uint8: (uint8_t) -1 == UINT8_MAX ? 1 : -1;
+#endif
+#ifdef UINT16_MAX
+  int check_uint16: (uint16_t) -1 == UINT16_MAX ? 1 : -1;
+#endif
+#ifdef UINT32_MAX
+  int check_uint32: (uint32_t) -1 == UINT32_MAX ? 1 : -1;
+#endif
+#ifdef UINT64_MAX
+  int check_uint64: (uint64_t) -1 == UINT64_MAX ? 1 : -1;
+#endif
+  int check_uint_least8: (uint_least8_t) -1 == UINT_LEAST8_MAX ? 1 : -1;
+  int check_uint_least16: (uint_least16_t) -1 == UINT_LEAST16_MAX ? 1 : -1;
+  int check_uint_least32: (uint_least32_t) -1 == UINT_LEAST32_MAX ? 1 : -1;
+  int check_uint_least64: (uint_least64_t) -1 == UINT_LEAST64_MAX ? 1 : -1;
+  int check_uint_fast8: (uint_fast8_t) -1 == UINT_FAST8_MAX ? 1 : -1;
+  int check_uint_fast16: (uint_fast16_t) -1 == UINT_FAST16_MAX ? 1 : -1;
+  int check_uint_fast32: (uint_fast32_t) -1 == UINT_FAST32_MAX ? 1 : -1;
+  int check_uint_fast64: (uint_fast64_t) -1 == UINT_FAST64_MAX ? 1 : -1;
+  int check_uintptr: (uintptr_t) -1 == UINTPTR_MAX ? 1 : -1;
+  int check_uintmax: (uintmax_t) -1 == UINTMAX_MAX ? 1 : -1;
+  int check_size: (size_t) -1 == SIZE_MAX ? 1 : -1;
+};
+         ]])],
+         [dnl Determine whether the various *_MIN, *_MAX macros are usable
+          dnl in preprocessor expression. We could do it by compiling a test
+          dnl program for each of these macros. It is faster to run a program
+          dnl that inspects the macro expansion.
+          dnl This detects a bug on HP-UX 11.23/ia64.
+          AC_RUN_IFELSE([
+            AC_LANG_PROGRAM([[
+#define __STDC_LIMIT_MACROS 1 /* to make it work also in C++ mode */
+#define __STDC_CONSTANT_MACROS 1 /* to make it work also in C++ mode */
+#define _GL_JUST_INCLUDE_SYSTEM_STDINT_H 1 /* work if build isn't clean */
+#include <stdint.h>
+]
+gl_STDINT_INCLUDES
+[
+#include <stdio.h>
+#include <string.h>
+#define MVAL(macro) MVAL1(macro)
+#define MVAL1(expression) #expression
+static const char *macro_values[] =
+  {
+#ifdef INT8_MAX
+    MVAL (INT8_MAX),
+#endif
+#ifdef INT16_MAX
+    MVAL (INT16_MAX),
+#endif
+#ifdef INT32_MAX
+    MVAL (INT32_MAX),
+#endif
+#ifdef INT64_MAX
+    MVAL (INT64_MAX),
+#endif
+#ifdef UINT8_MAX
+    MVAL (UINT8_MAX),
+#endif
+#ifdef UINT16_MAX
+    MVAL (UINT16_MAX),
+#endif
+#ifdef UINT32_MAX
+    MVAL (UINT32_MAX),
+#endif
+#ifdef UINT64_MAX
+    MVAL (UINT64_MAX),
+#endif
+    NULL
+  };
+]], [[
+  const char **mv;
+  for (mv = macro_values; *mv != NULL; mv++)
+    {
+      const char *value = *mv;
+      /* Test whether it looks like a cast expression.  */
+      if (strncmp (value, "((unsigned int)"/*)*/, 15) == 0
+          || strncmp (value, "((unsigned short)"/*)*/, 17) == 0
+          || strncmp (value, "((unsigned char)"/*)*/, 16) == 0
+          || strncmp (value, "((int)"/*)*/, 6) == 0
+          || strncmp (value, "((signed short)"/*)*/, 15) == 0
+          || strncmp (value, "((signed char)"/*)*/, 14) == 0)
+        return mv - macro_values + 1;
+    }
+  return 0;
+]])],
+              [gl_cv_header_working_stdint_h=yes],
+              [],
+              [dnl When cross-compiling, assume it works.
+               gl_cv_header_working_stdint_h=yes
+              ])
+         ])
+      ])
+  fi
+  if test "$gl_cv_header_working_stdint_h" = yes; then
+    STDINT_H=
+  else
+    dnl Check for <sys/inttypes.h>, and for
+    dnl <sys/bitypes.h> (used in Linux libc4 >= 4.6.7 and libc5).
+    AC_CHECK_HEADERS([sys/inttypes.h sys/bitypes.h])
+    if test $ac_cv_header_sys_inttypes_h = yes; then
+      HAVE_SYS_INTTYPES_H=1
+    else
+      HAVE_SYS_INTTYPES_H=0
+    fi
+    AC_SUBST([HAVE_SYS_INTTYPES_H])
+    if test $ac_cv_header_sys_bitypes_h = yes; then
+      HAVE_SYS_BITYPES_H=1
+    else
+      HAVE_SYS_BITYPES_H=0
+    fi
+    AC_SUBST([HAVE_SYS_BITYPES_H])
+
+    dnl Check for <wchar.h> (missing in Linux uClibc when built without wide
+    dnl character support).
+    AC_CHECK_HEADERS_ONCE([wchar.h])
+
+    gl_STDINT_TYPE_PROPERTIES
+    STDINT_H=stdint.h
+  fi
+  AC_SUBST([STDINT_H])
+])
+
+dnl gl_STDINT_BITSIZEOF(TYPES, INCLUDES)
+dnl Determine the size of each of the given types in bits.
+AC_DEFUN([gl_STDINT_BITSIZEOF],
+[
+  dnl Use a shell loop, to avoid bloating configure, and
+  dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+  dnl   config.h.in,
+  dnl - extra AC_SUBST calls, so that the right substitutions are made.
+  m4_foreach_w([gltype], [$1],
+    [AH_TEMPLATE([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
+       [Define to the number of bits in type ']gltype['.])])
+  for gltype in $1 ; do
+    AC_CACHE_CHECK([for bit size of $gltype], [gl_cv_bitsizeof_${gltype}],
+      [AC_COMPUTE_INT([result], [sizeof ($gltype) * CHAR_BIT],
+         [$2
+#include <limits.h>], [result=unknown])
+       eval gl_cv_bitsizeof_${gltype}=\$result
+      ])
+    eval result=\$gl_cv_bitsizeof_${gltype}
+    if test $result = unknown; then
+      dnl Use a nonempty default, because some compilers, such as IRIX 5 cc,
+      dnl do a syntax check even on unused #if conditions and give an error
+      dnl on valid C code like this:
+      dnl   #if 0
+      dnl   # if  > 32
+      dnl   # endif
+      dnl   #endif
+      result=0
+    fi
+    GLTYPE=`echo "$gltype" | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    AC_DEFINE_UNQUOTED([BITSIZEOF_${GLTYPE}], [$result])
+    eval BITSIZEOF_${GLTYPE}=\$result
+  done
+  m4_foreach_w([gltype], [$1],
+    [AC_SUBST([BITSIZEOF_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
+])
+
+dnl gl_CHECK_TYPES_SIGNED(TYPES, INCLUDES)
+dnl Determine the signedness of each of the given types.
+dnl Define HAVE_SIGNED_TYPE if type is signed.
+AC_DEFUN([gl_CHECK_TYPES_SIGNED],
+[
+  dnl Use a shell loop, to avoid bloating configure, and
+  dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+  dnl   config.h.in,
+  dnl - extra AC_SUBST calls, so that the right substitutions are made.
+  m4_foreach_w([gltype], [$1],
+    [AH_TEMPLATE([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]),
+       [Define to 1 if ']gltype[' is a signed integer type.])])
+  for gltype in $1 ; do
+    AC_CACHE_CHECK([whether $gltype is signed], [gl_cv_type_${gltype}_signed],
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([$2[
+            int verify[2 * (($gltype) -1 < ($gltype) 0) - 1];]])],
+         result=yes, result=no)
+       eval gl_cv_type_${gltype}_signed=\$result
+      ])
+    eval result=\$gl_cv_type_${gltype}_signed
+    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    if test "$result" = yes; then
+      AC_DEFINE_UNQUOTED([HAVE_SIGNED_${GLTYPE}], [1])
+      eval HAVE_SIGNED_${GLTYPE}=1
+    else
+      eval HAVE_SIGNED_${GLTYPE}=0
+    fi
+  done
+  m4_foreach_w([gltype], [$1],
+    [AC_SUBST([HAVE_SIGNED_]m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_]))])
+])
+
+dnl gl_INTEGER_TYPE_SUFFIX(TYPES, INCLUDES)
+dnl Determine the suffix to use for integer constants of the given types.
+dnl Define t_SUFFIX for each such type.
+AC_DEFUN([gl_INTEGER_TYPE_SUFFIX],
+[
+  dnl Use a shell loop, to avoid bloating configure, and
+  dnl - extra AH_TEMPLATE calls, so that autoheader knows what to put into
+  dnl   config.h.in,
+  dnl - extra AC_SUBST calls, so that the right substitutions are made.
+  m4_foreach_w([gltype], [$1],
+    [AH_TEMPLATE(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX],
+       [Define to l, ll, u, ul, ull, etc., as suitable for
+        constants of type ']gltype['.])])
+  for gltype in $1 ; do
+    AC_CACHE_CHECK([for $gltype integer literal suffix],
+      [gl_cv_type_${gltype}_suffix],
+      [eval gl_cv_type_${gltype}_suffix=no
+       eval result=\$gl_cv_type_${gltype}_signed
+       if test "$result" = yes; then
+         glsufu=
+       else
+         glsufu=u
+       fi
+       for glsuf in "$glsufu" ${glsufu}l ${glsufu}ll ${glsufu}i64; do
+         case $glsuf in
+           '')  gltype1='int';;
+           l)   gltype1='long int';;
+           ll)  gltype1='long long int';;
+           i64) gltype1='__int64';;
+           u)   gltype1='unsigned int';;
+           ul)  gltype1='unsigned long int';;
+           ull) gltype1='unsigned long long int';;
+           ui64)gltype1='unsigned __int64';;
+         esac
+         AC_COMPILE_IFELSE(
+           [AC_LANG_PROGRAM([$2[
+              extern $gltype foo;
+              extern $gltype1 foo;]])],
+           [eval gl_cv_type_${gltype}_suffix=\$glsuf])
+         eval result=\$gl_cv_type_${gltype}_suffix
+         test "$result" != no && break
+       done])
+    GLTYPE=`echo $gltype | tr 'abcdefghijklmnopqrstuvwxyz ' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_'`
+    eval result=\$gl_cv_type_${gltype}_suffix
+    test "$result" = no && result=
+    eval ${GLTYPE}_SUFFIX=\$result
+    AC_DEFINE_UNQUOTED([${GLTYPE}_SUFFIX], [$result])
+  done
+  m4_foreach_w([gltype], [$1],
+    [AC_SUBST(m4_translit(gltype,[abcdefghijklmnopqrstuvwxyz ],[ABCDEFGHIJKLMNOPQRSTUVWXYZ_])[_SUFFIX])])
+])
+
+dnl gl_STDINT_INCLUDES
+AC_DEFUN([gl_STDINT_INCLUDES],
+[[
+  /* BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+     included before <wchar.h>.  */
+  #include <stddef.h>
+  #include <signal.h>
+  #if HAVE_WCHAR_H
+  # include <stdio.h>
+  # include <time.h>
+  # include <wchar.h>
+  #endif
+]])
+
+dnl gl_STDINT_TYPE_PROPERTIES
+dnl Compute HAVE_SIGNED_t, BITSIZEOF_t and t_SUFFIX, for all the types t
+dnl of interest to stdint.in.h.
+AC_DEFUN([gl_STDINT_TYPE_PROPERTIES],
+[
+  AC_REQUIRE([gl_MULTIARCH])
+  if test $APPLE_UNIVERSAL_BUILD = 0; then
+    gl_STDINT_BITSIZEOF([ptrdiff_t size_t],
+      [gl_STDINT_INCLUDES])
+  fi
+  gl_STDINT_BITSIZEOF([sig_atomic_t wchar_t wint_t],
+    [gl_STDINT_INCLUDES])
+  gl_CHECK_TYPES_SIGNED([sig_atomic_t wchar_t wint_t],
+    [gl_STDINT_INCLUDES])
+  gl_cv_type_ptrdiff_t_signed=yes
+  gl_cv_type_size_t_signed=no
+  if test $APPLE_UNIVERSAL_BUILD = 0; then
+    gl_INTEGER_TYPE_SUFFIX([ptrdiff_t size_t],
+      [gl_STDINT_INCLUDES])
+  fi
+  gl_INTEGER_TYPE_SUFFIX([sig_atomic_t wchar_t wint_t],
+    [gl_STDINT_INCLUDES])
+])
+
+dnl Autoconf >= 2.61 has AC_COMPUTE_INT built-in.
+dnl Remove this when we can assume autoconf >= 2.61.
+m4_ifdef([AC_COMPUTE_INT], [], [
+  AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])
+])
+
+# Hey Emacs!
+# Local Variables:
+# indent-tabs-mode: nil
+# End:
diff --git a/gl/m4/stdlib_h.m4 b/gl/m4/stdlib_h.m4
new file mode 100644
index 0000000..a71468f
--- /dev/null
+++ b/gl/m4/stdlib_h.m4
@@ -0,0 +1,114 @@
+# stdlib_h.m4 serial 34
+dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_STDLIB_H],
+[
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  gl_NEXT_HEADERS([stdlib.h])
+  AC_CHECK_HEADERS([random.h], [], [], [AC_INCLUDES_DEFAULT])
+  if test $ac_cv_header_random_h = yes; then
+    HAVE_RANDOM_H=1
+  else
+    HAVE_RANDOM_H=0
+  fi
+  AC_SUBST([HAVE_RANDOM_H])
+  AC_CHECK_TYPES([struct random_data],
+    [], [HAVE_STRUCT_RANDOM_DATA=0],
+    [[#include <stdlib.h>
+      #if HAVE_RANDOM_H
+      # include <random.h>
+      #endif
+    ]])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use, and which is not
+  dnl guaranteed by C89.
+  gl_WARN_ON_USE_PREPARE([[#include <stdlib.h>
+#if HAVE_SYS_LOADAVG_H
+# include <sys/loadavg.h>
+#endif
+#if HAVE_RANDOM_H
+# include <random.h>
+#endif
+    ]], [_Exit atoll canonicalize_file_name getloadavg getsubopt grantpt mkdtemp
+    mkostemp mkostemps mkstemp mkstemps ptsname random_r initstat_r srandom_r
+    setstate_r realpath rpmatch setenv strtod strtoll strtoull unlockpt
+    unsetenv])
+])
+
+AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_STDLIB_H_DEFAULTS],
+[
+  GNULIB__EXIT=0;         AC_SUBST([GNULIB__EXIT])
+  GNULIB_ATOLL=0;         AC_SUBST([GNULIB_ATOLL])
+  GNULIB_CALLOC_POSIX=0;  AC_SUBST([GNULIB_CALLOC_POSIX])
+  GNULIB_CANONICALIZE_FILE_NAME=0;  AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME])
+  GNULIB_GETLOADAVG=0;    AC_SUBST([GNULIB_GETLOADAVG])
+  GNULIB_GETSUBOPT=0;     AC_SUBST([GNULIB_GETSUBOPT])
+  GNULIB_GRANTPT=0;       AC_SUBST([GNULIB_GRANTPT])
+  GNULIB_MALLOC_POSIX=0;  AC_SUBST([GNULIB_MALLOC_POSIX])
+  GNULIB_MKDTEMP=0;       AC_SUBST([GNULIB_MKDTEMP])
+  GNULIB_MKOSTEMP=0;      AC_SUBST([GNULIB_MKOSTEMP])
+  GNULIB_MKOSTEMPS=0;     AC_SUBST([GNULIB_MKOSTEMPS])
+  GNULIB_MKSTEMP=0;       AC_SUBST([GNULIB_MKSTEMP])
+  GNULIB_MKSTEMPS=0;      AC_SUBST([GNULIB_MKSTEMPS])
+  GNULIB_PTSNAME=0;       AC_SUBST([GNULIB_PTSNAME])
+  GNULIB_PUTENV=0;        AC_SUBST([GNULIB_PUTENV])
+  GNULIB_RANDOM_R=0;      AC_SUBST([GNULIB_RANDOM_R])
+  GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
+  GNULIB_REALPATH=0;      AC_SUBST([GNULIB_REALPATH])
+  GNULIB_RPMATCH=0;       AC_SUBST([GNULIB_RPMATCH])
+  GNULIB_SETENV=0;        AC_SUBST([GNULIB_SETENV])
+  GNULIB_STRTOD=0;        AC_SUBST([GNULIB_STRTOD])
+  GNULIB_STRTOLL=0;       AC_SUBST([GNULIB_STRTOLL])
+  GNULIB_STRTOULL=0;      AC_SUBST([GNULIB_STRTOULL])
+  GNULIB_SYSTEM_POSIX=0;  AC_SUBST([GNULIB_SYSTEM_POSIX])
+  GNULIB_UNLOCKPT=0;      AC_SUBST([GNULIB_UNLOCKPT])
+  GNULIB_UNSETENV=0;      AC_SUBST([GNULIB_UNSETENV])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE__EXIT=1;              AC_SUBST([HAVE__EXIT])
+  HAVE_ATOLL=1;              AC_SUBST([HAVE_ATOLL])
+  HAVE_CANONICALIZE_FILE_NAME=1;  AC_SUBST([HAVE_CANONICALIZE_FILE_NAME])
+  HAVE_DECL_GETLOADAVG=1;    AC_SUBST([HAVE_DECL_GETLOADAVG])
+  HAVE_GETSUBOPT=1;          AC_SUBST([HAVE_GETSUBOPT])
+  HAVE_GRANTPT=1;            AC_SUBST([HAVE_GRANTPT])
+  HAVE_MKDTEMP=1;            AC_SUBST([HAVE_MKDTEMP])
+  HAVE_MKOSTEMP=1;           AC_SUBST([HAVE_MKOSTEMP])
+  HAVE_MKOSTEMPS=1;          AC_SUBST([HAVE_MKOSTEMPS])
+  HAVE_MKSTEMP=1;            AC_SUBST([HAVE_MKSTEMP])
+  HAVE_MKSTEMPS=1;           AC_SUBST([HAVE_MKSTEMPS])
+  HAVE_PTSNAME=1;            AC_SUBST([HAVE_PTSNAME])
+  HAVE_RANDOM_R=1;           AC_SUBST([HAVE_RANDOM_R])
+  HAVE_REALPATH=1;           AC_SUBST([HAVE_REALPATH])
+  HAVE_RPMATCH=1;            AC_SUBST([HAVE_RPMATCH])
+  HAVE_SETENV=1;             AC_SUBST([HAVE_SETENV])
+  HAVE_DECL_SETENV=1;        AC_SUBST([HAVE_DECL_SETENV])
+  HAVE_STRTOD=1;             AC_SUBST([HAVE_STRTOD])
+  HAVE_STRTOLL=1;            AC_SUBST([HAVE_STRTOLL])
+  HAVE_STRTOULL=1;           AC_SUBST([HAVE_STRTOULL])
+  HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA])
+  HAVE_SYS_LOADAVG_H=0;      AC_SUBST([HAVE_SYS_LOADAVG_H])
+  HAVE_UNLOCKPT=1;           AC_SUBST([HAVE_UNLOCKPT])
+  HAVE_DECL_UNSETENV=1;      AC_SUBST([HAVE_DECL_UNSETENV])
+  REPLACE_CALLOC=0;          AC_SUBST([REPLACE_CALLOC])
+  REPLACE_CANONICALIZE_FILE_NAME=0;  AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME])
+  REPLACE_MALLOC=0;          AC_SUBST([REPLACE_MALLOC])
+  REPLACE_MKSTEMP=0;         AC_SUBST([REPLACE_MKSTEMP])
+  REPLACE_PUTENV=0;          AC_SUBST([REPLACE_PUTENV])
+  REPLACE_REALLOC=0;         AC_SUBST([REPLACE_REALLOC])
+  REPLACE_REALPATH=0;        AC_SUBST([REPLACE_REALPATH])
+  REPLACE_SETENV=0;          AC_SUBST([REPLACE_SETENV])
+  REPLACE_STRTOD=0;          AC_SUBST([REPLACE_STRTOD])
+  REPLACE_UNSETENV=0;        AC_SUBST([REPLACE_UNSETENV])
+])
diff --git a/gl/m4/unistd_h.m4 b/gl/m4/unistd_h.m4
new file mode 100644
index 0000000..c81a113
--- /dev/null
+++ b/gl/m4/unistd_h.m4
@@ -0,0 +1,162 @@
+# unistd_h.m4 serial 53
+dnl Copyright (C) 2006-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Simon Josefsson, Bruno Haible.
+
+AC_DEFUN([gl_UNISTD_H],
+[
+  dnl Use AC_REQUIRE here, so that the default behavior below is expanded
+  dnl once only, before all statements that occur in other macros.
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  AC_REQUIRE([AC_C_INLINE])
+
+  gl_CHECK_NEXT_HEADERS([unistd.h])
+  if test $ac_cv_header_unistd_h = yes; then
+    HAVE_UNISTD_H=1
+  else
+    HAVE_UNISTD_H=0
+  fi
+  AC_SUBST([HAVE_UNISTD_H])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use.
+  gl_WARN_ON_USE_PREPARE([[#include <unistd.h>
+/* Some systems declare various items in the wrong headers.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <fcntl.h>
+# include <stdio.h>
+# include <stdlib.h>
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#  include <io.h>
+# endif
+#endif
+    ]], [chown dup2 dup3 environ euidaccess faccessat fchdir fchownat
+    fsync ftruncate getcwd getdomainname getdtablesize getgroups
+    gethostname getlogin getlogin_r getpagesize getusershell setusershell
+    endusershell lchown link linkat lseek pipe pipe2 pread pwrite readlink
+    readlinkat rmdir sleep symlink symlinkat ttyname_r unlink unlinkat
+    usleep])
+])
+
+AC_DEFUN([gl_UNISTD_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_UNISTD_H_DEFAULTS],
+[
+  GNULIB_CHOWN=0;            AC_SUBST([GNULIB_CHOWN])
+  GNULIB_CLOSE=0;            AC_SUBST([GNULIB_CLOSE])
+  GNULIB_DUP2=0;             AC_SUBST([GNULIB_DUP2])
+  GNULIB_DUP3=0;             AC_SUBST([GNULIB_DUP3])
+  GNULIB_ENVIRON=0;          AC_SUBST([GNULIB_ENVIRON])
+  GNULIB_EUIDACCESS=0;       AC_SUBST([GNULIB_EUIDACCESS])
+  GNULIB_FACCESSAT=0;        AC_SUBST([GNULIB_FACCESSAT])
+  GNULIB_FCHDIR=0;           AC_SUBST([GNULIB_FCHDIR])
+  GNULIB_FCHOWNAT=0;         AC_SUBST([GNULIB_FCHOWNAT])
+  GNULIB_FSYNC=0;            AC_SUBST([GNULIB_FSYNC])
+  GNULIB_FTRUNCATE=0;        AC_SUBST([GNULIB_FTRUNCATE])
+  GNULIB_GETCWD=0;           AC_SUBST([GNULIB_GETCWD])
+  GNULIB_GETDOMAINNAME=0;    AC_SUBST([GNULIB_GETDOMAINNAME])
+  GNULIB_GETDTABLESIZE=0;    AC_SUBST([GNULIB_GETDTABLESIZE])
+  GNULIB_GETGROUPS=0;        AC_SUBST([GNULIB_GETGROUPS])
+  GNULIB_GETHOSTNAME=0;      AC_SUBST([GNULIB_GETHOSTNAME])
+  GNULIB_GETLOGIN=0;         AC_SUBST([GNULIB_GETLOGIN])
+  GNULIB_GETLOGIN_R=0;       AC_SUBST([GNULIB_GETLOGIN_R])
+  GNULIB_GETPAGESIZE=0;      AC_SUBST([GNULIB_GETPAGESIZE])
+  GNULIB_GETUSERSHELL=0;     AC_SUBST([GNULIB_GETUSERSHELL])
+  GNULIB_LCHOWN=0;           AC_SUBST([GNULIB_LCHOWN])
+  GNULIB_LINK=0;             AC_SUBST([GNULIB_LINK])
+  GNULIB_LINKAT=0;           AC_SUBST([GNULIB_LINKAT])
+  GNULIB_LSEEK=0;            AC_SUBST([GNULIB_LSEEK])
+  GNULIB_PIPE=0;             AC_SUBST([GNULIB_PIPE])
+  GNULIB_PIPE2=0;            AC_SUBST([GNULIB_PIPE2])
+  GNULIB_PREAD=0;            AC_SUBST([GNULIB_PREAD])
+  GNULIB_PWRITE=0;           AC_SUBST([GNULIB_PWRITE])
+  GNULIB_READLINK=0;         AC_SUBST([GNULIB_READLINK])
+  GNULIB_READLINKAT=0;       AC_SUBST([GNULIB_READLINKAT])
+  GNULIB_RMDIR=0;            AC_SUBST([GNULIB_RMDIR])
+  GNULIB_SLEEP=0;            AC_SUBST([GNULIB_SLEEP])
+  GNULIB_SYMLINK=0;          AC_SUBST([GNULIB_SYMLINK])
+  GNULIB_SYMLINKAT=0;        AC_SUBST([GNULIB_SYMLINKAT])
+  GNULIB_TTYNAME_R=0;        AC_SUBST([GNULIB_TTYNAME_R])
+  GNULIB_UNISTD_H_GETOPT=0;  AC_SUBST([GNULIB_UNISTD_H_GETOPT])
+  GNULIB_UNISTD_H_SIGPIPE=0; AC_SUBST([GNULIB_UNISTD_H_SIGPIPE])
+  GNULIB_UNLINK=0;           AC_SUBST([GNULIB_UNLINK])
+  GNULIB_UNLINKAT=0;         AC_SUBST([GNULIB_UNLINKAT])
+  GNULIB_USLEEP=0;           AC_SUBST([GNULIB_USLEEP])
+  GNULIB_WRITE=0;            AC_SUBST([GNULIB_WRITE])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_CHOWN=1;           AC_SUBST([HAVE_CHOWN])
+  HAVE_DUP2=1;            AC_SUBST([HAVE_DUP2])
+  HAVE_DUP3=1;            AC_SUBST([HAVE_DUP3])
+  HAVE_EUIDACCESS=1;      AC_SUBST([HAVE_EUIDACCESS])
+  HAVE_FACCESSAT=1;       AC_SUBST([HAVE_FACCESSAT])
+  HAVE_FCHDIR=1;          AC_SUBST([HAVE_FCHDIR])
+  HAVE_FCHOWNAT=1;        AC_SUBST([HAVE_FCHOWNAT])
+  HAVE_FSYNC=1;           AC_SUBST([HAVE_FSYNC])
+  HAVE_FTRUNCATE=1;       AC_SUBST([HAVE_FTRUNCATE])
+  HAVE_GETDTABLESIZE=1;   AC_SUBST([HAVE_GETDTABLESIZE])
+  HAVE_GETGROUPS=1;       AC_SUBST([HAVE_GETGROUPS])
+  HAVE_GETHOSTNAME=1;     AC_SUBST([HAVE_GETHOSTNAME])
+  HAVE_GETLOGIN=1;        AC_SUBST([HAVE_GETLOGIN])
+  HAVE_GETPAGESIZE=1;     AC_SUBST([HAVE_GETPAGESIZE])
+  HAVE_LCHOWN=1;          AC_SUBST([HAVE_LCHOWN])
+  HAVE_LINK=1;            AC_SUBST([HAVE_LINK])
+  HAVE_LINKAT=1;          AC_SUBST([HAVE_LINKAT])
+  HAVE_PIPE=1;            AC_SUBST([HAVE_PIPE])
+  HAVE_PIPE2=1;           AC_SUBST([HAVE_PIPE2])
+  HAVE_PREAD=1;           AC_SUBST([HAVE_PREAD])
+  HAVE_PWRITE=1;          AC_SUBST([HAVE_PWRITE])
+  HAVE_READLINK=1;        AC_SUBST([HAVE_READLINK])
+  HAVE_READLINKAT=1;      AC_SUBST([HAVE_READLINKAT])
+  HAVE_SLEEP=1;           AC_SUBST([HAVE_SLEEP])
+  HAVE_SYMLINK=1;         AC_SUBST([HAVE_SYMLINK])
+  HAVE_SYMLINKAT=1;       AC_SUBST([HAVE_SYMLINKAT])
+  HAVE_UNLINKAT=1;        AC_SUBST([HAVE_UNLINKAT])
+  HAVE_USLEEP=1;          AC_SUBST([HAVE_USLEEP])
+  HAVE_DECL_ENVIRON=1;    AC_SUBST([HAVE_DECL_ENVIRON])
+  HAVE_DECL_FCHDIR=1;     AC_SUBST([HAVE_DECL_FCHDIR])
+  HAVE_DECL_GETDOMAINNAME=1; AC_SUBST([HAVE_DECL_GETDOMAINNAME])
+  HAVE_DECL_GETLOGIN_R=1; AC_SUBST([HAVE_DECL_GETLOGIN_R])
+  HAVE_DECL_GETPAGESIZE=1; AC_SUBST([HAVE_DECL_GETPAGESIZE])
+  HAVE_DECL_GETUSERSHELL=1; AC_SUBST([HAVE_DECL_GETUSERSHELL])
+  HAVE_DECL_TTYNAME_R=1;  AC_SUBST([HAVE_DECL_TTYNAME_R])
+  HAVE_OS_H=0;            AC_SUBST([HAVE_OS_H])
+  HAVE_SYS_PARAM_H=0;     AC_SUBST([HAVE_SYS_PARAM_H])
+  REPLACE_CHOWN=0;        AC_SUBST([REPLACE_CHOWN])
+  REPLACE_CLOSE=0;        AC_SUBST([REPLACE_CLOSE])
+  REPLACE_DUP=0;          AC_SUBST([REPLACE_DUP])
+  REPLACE_DUP2=0;         AC_SUBST([REPLACE_DUP2])
+  REPLACE_FCHOWNAT=0;     AC_SUBST([REPLACE_FCHOWNAT])
+  REPLACE_GETCWD=0;       AC_SUBST([REPLACE_GETCWD])
+  REPLACE_GETDOMAINNAME=0; AC_SUBST([REPLACE_GETDOMAINNAME])
+  REPLACE_GETLOGIN_R=0;   AC_SUBST([REPLACE_GETLOGIN_R])
+  REPLACE_GETGROUPS=0;    AC_SUBST([REPLACE_GETGROUPS])
+  REPLACE_GETPAGESIZE=0;  AC_SUBST([REPLACE_GETPAGESIZE])
+  REPLACE_LCHOWN=0;       AC_SUBST([REPLACE_LCHOWN])
+  REPLACE_LINK=0;         AC_SUBST([REPLACE_LINK])
+  REPLACE_LINKAT=0;       AC_SUBST([REPLACE_LINKAT])
+  REPLACE_LSEEK=0;        AC_SUBST([REPLACE_LSEEK])
+  REPLACE_PREAD=0;        AC_SUBST([REPLACE_PREAD])
+  REPLACE_PWRITE=0;       AC_SUBST([REPLACE_PWRITE])
+  REPLACE_READLINK=0;     AC_SUBST([REPLACE_READLINK])
+  REPLACE_RMDIR=0;        AC_SUBST([REPLACE_RMDIR])
+  REPLACE_SLEEP=0;        AC_SUBST([REPLACE_SLEEP])
+  REPLACE_SYMLINK=0;      AC_SUBST([REPLACE_SYMLINK])
+  REPLACE_TTYNAME_R=0;    AC_SUBST([REPLACE_TTYNAME_R])
+  REPLACE_UNLINK=0;       AC_SUBST([REPLACE_UNLINK])
+  REPLACE_UNLINKAT=0;     AC_SUBST([REPLACE_UNLINKAT])
+  REPLACE_USLEEP=0;       AC_SUBST([REPLACE_USLEEP])
+  REPLACE_WRITE=0;        AC_SUBST([REPLACE_WRITE])
+  UNISTD_H_HAVE_WINSOCK2_H=0; AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H])
+  UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS=0;
+                           AC_SUBST([UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS])
+])
diff --git a/gl/m4/warn-on-use.m4 b/gl/m4/warn-on-use.m4
new file mode 100644
index 0000000..e0d0f27
--- /dev/null
+++ b/gl/m4/warn-on-use.m4
@@ -0,0 +1,45 @@
+# warn-on-use.m4 serial 2
+dnl Copyright (C) 2010-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# gl_WARN_ON_USE_PREPARE(INCLUDES, NAMES)
+# ---------------------------------------
+# For each whitespace-separated element in the list of NAMES, define
+# HAVE_RAW_DECL_name if the function has a declaration among INCLUDES
+# even after being undefined as a macro.
+#
+# See warn-on-use.h for some hints on how to poison function names, as
+# well as ideas on poisoning global variables and macros.  NAMES may
+# include global variables, but remember that only functions work with
+# _GL_WARN_ON_USE.  Typically, INCLUDES only needs to list a single
+# header, but if the replacement header pulls in other headers because
+# some systems declare functions in the wrong header, then INCLUDES
+# should do likewise.
+#
+# If you assume C89, then it is generally safe to assume declarations
+# for functions declared in that standard (such as gets) without
+# needing gl_WARN_ON_USE_PREPARE.
+AC_DEFUN([gl_WARN_ON_USE_PREPARE],
+[
+  m4_foreach_w([gl_decl], [$2],
+    [AH_TEMPLATE([HAVE_RAW_DECL_]AS_TR_CPP(m4_defn([gl_decl])),
+      [Define to 1 if ]m4_defn([gl_decl])[ is declared even after
+       undefining macros.])])dnl
+  for gl_func in m4_flatten([$2]); do
+    AS_VAR_PUSHDEF([gl_Symbol], [gl_cv_have_raw_decl_$gl_func])dnl
+    AC_CACHE_CHECK([whether $gl_func is declared without a macro],
+      gl_Symbol,
+      [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([$1],
+[@%:@undef $gl_func
+  (void) $gl_func;])],
+        [AS_VAR_SET(gl_Symbol, [yes])], [AS_VAR_SET(gl_Symbol, [no])])])
+     AS_VAR_IF(gl_Symbol, [yes],
+       [AC_DEFINE_UNQUOTED(AS_TR_CPP([HAVE_RAW_DECL_$gl_func]), [1])
+       dnl shortcut - if the raw declaration exists, then set a cache
+       dnl variable to allow skipping any later AC_CHECK_DECL efforts
+       eval ac_cv_have_decl_$gl_func=yes])
+    AS_VAR_POPDEF([gl_Symbol])dnl
+  done
+])
diff --git a/gl/m4/wchar_h.m4 b/gl/m4/wchar_h.m4
new file mode 100644
index 0000000..e8adf89
--- /dev/null
+++ b/gl/m4/wchar_h.m4
@@ -0,0 +1,170 @@
+dnl A placeholder for ISO C99 <wchar.h>, for platforms that have issues.
+
+dnl Copyright (C) 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Eric Blake.
+
+# wchar_h.m4 serial 37
+
+AC_DEFUN([gl_WCHAR_H],
+[
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+  AC_REQUIRE([gl_WCHAR_H_INLINE_OK])
+  dnl Prepare for creating substitute <wchar.h>.
+  dnl Check for <wchar.h> (missing in Linux uClibc when built without wide
+  dnl character support).
+  dnl <wchar.h> is always overridden, because of GNULIB_POSIXCHECK.
+  gl_CHECK_NEXT_HEADERS([wchar.h])
+  if test $ac_cv_header_wchar_h = yes; then
+    HAVE_WCHAR_H=1
+  else
+    HAVE_WCHAR_H=0
+  fi
+  AC_SUBST([HAVE_WCHAR_H])
+
+  AC_REQUIRE([gl_FEATURES_H])
+
+  AC_REQUIRE([gt_TYPE_WINT_T])
+  if test $gt_cv_c_wint_t = yes; then
+    HAVE_WINT_T=1
+  else
+    HAVE_WINT_T=0
+  fi
+  AC_SUBST([HAVE_WINT_T])
+
+  dnl Check for declarations of anything we want to poison if the
+  dnl corresponding gnulib module is not in use.
+  gl_WARN_ON_USE_PREPARE([[
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#if !(defined __GLIBC__ && !defined __UCLIBC__)
+# include <stddef.h>
+# include <stdio.h>
+# include <time.h>
+#endif
+#include <wchar.h>
+    ]], [btowc wctob mbsinit mbrtowc mbrlen mbsrtowcs mbsnrtowcs wcrtomb
+    wcsrtombs wcsnrtombs wcwidth])
+])
+
+dnl Check whether <wchar.h> is usable at all.
+AC_DEFUN([gl_WCHAR_H_INLINE_OK],
+[
+  dnl Test whether <wchar.h> suffers due to the transition from '__inline' to
+  dnl 'gnu_inline'. See <http://sourceware.org/bugzilla/show_bug.cgi?id=4022>
+  dnl and <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42440>. In summary,
+  dnl glibc version 2.5 or older, together with gcc version 4.3 or newer and
+  dnl the option -std=c99 or -std=gnu99, leads to a broken <wchar.h>.
+  AC_CACHE_CHECK([whether <wchar.h> uses 'inline' correctly],
+    [gl_cv_header_wchar_h_correct_inline],
+    [gl_cv_header_wchar_h_correct_inline=yes
+     AC_LANG_CONFTEST([
+       AC_LANG_SOURCE([[#define wcstod renamed_wcstod
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+extern int zero (void);
+int main () { return zero(); }
+]])])
+     if AC_TRY_EVAL([ac_compile]); then
+       mv conftest.$ac_objext conftest1.$ac_objext
+       AC_LANG_CONFTEST([
+         AC_LANG_SOURCE([[#define wcstod renamed_wcstod
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int zero (void) { return 0; }
+]])])
+       if AC_TRY_EVAL([ac_compile]); then
+         mv conftest.$ac_objext conftest2.$ac_objext
+         if $CC -o conftest$ac_exeext $CFLAGS $LDFLAGS conftest1.$ac_objext conftest2.$ac_objext $LIBS >&AS_MESSAGE_LOG_FD 2>&1; then
+           :
+         else
+           gl_cv_header_wchar_h_correct_inline=no
+         fi
+       fi
+     fi
+     rm -f conftest1.$ac_objext conftest2.$ac_objext conftest$ac_exeext
+    ])
+  if test $gl_cv_header_wchar_h_correct_inline = no; then
+    AC_MSG_ERROR([<wchar.h> cannot be used with this compiler ($CC $CFLAGS $CPPFLAGS).
+This is a known interoperability problem of glibc <= 2.5 with gcc >= 4.3 in
+C99 mode. You have four options:
+  - Add the flag -fgnu89-inline to CC and reconfigure, or
+  - Fix your include files, using parts of
+    <http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=b037a293a48718af30d706c2e18c929d0e69a621>, or
+  - Use a gcc version older than 4.3, or
+  - Don't use the flags -std=c99 or -std=gnu99.
+Configuration aborted.])
+  fi
+])
+
+dnl Unconditionally enables the replacement of <wchar.h>.
+AC_DEFUN([gl_REPLACE_WCHAR_H],
+[
+  dnl This is a no-op, because <wchar.h> is always overridden.
+  :
+])
+
+AC_DEFUN([gl_WCHAR_MODULE_INDICATOR],
+[
+  dnl Use AC_REQUIRE here, so that the default settings are expanded once only.
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+  gl_MODULE_INDICATOR_SET_VARIABLE([$1])
+  dnl Define it also as a C macro, for the benefit of the unit tests.
+  gl_MODULE_INDICATOR_FOR_TESTS([$1])
+])
+
+AC_DEFUN([gl_WCHAR_H_DEFAULTS],
+[
+  GNULIB_BTOWC=0;      AC_SUBST([GNULIB_BTOWC])
+  GNULIB_WCTOB=0;      AC_SUBST([GNULIB_WCTOB])
+  GNULIB_MBSINIT=0;    AC_SUBST([GNULIB_MBSINIT])
+  GNULIB_MBRTOWC=0;    AC_SUBST([GNULIB_MBRTOWC])
+  GNULIB_MBRLEN=0;     AC_SUBST([GNULIB_MBRLEN])
+  GNULIB_MBSRTOWCS=0;  AC_SUBST([GNULIB_MBSRTOWCS])
+  GNULIB_MBSNRTOWCS=0; AC_SUBST([GNULIB_MBSNRTOWCS])
+  GNULIB_WCRTOMB=0;    AC_SUBST([GNULIB_WCRTOMB])
+  GNULIB_WCSRTOMBS=0;  AC_SUBST([GNULIB_WCSRTOMBS])
+  GNULIB_WCSNRTOMBS=0; AC_SUBST([GNULIB_WCSNRTOMBS])
+  GNULIB_WCWIDTH=0;    AC_SUBST([GNULIB_WCWIDTH])
+  dnl Assume proper GNU behavior unless another module says otherwise.
+  HAVE_BTOWC=1;         AC_SUBST([HAVE_BTOWC])
+  HAVE_MBSINIT=1;       AC_SUBST([HAVE_MBSINIT])
+  HAVE_MBRTOWC=1;       AC_SUBST([HAVE_MBRTOWC])
+  HAVE_MBRLEN=1;        AC_SUBST([HAVE_MBRLEN])
+  HAVE_MBSRTOWCS=1;     AC_SUBST([HAVE_MBSRTOWCS])
+  HAVE_MBSNRTOWCS=1;    AC_SUBST([HAVE_MBSNRTOWCS])
+  HAVE_WCRTOMB=1;       AC_SUBST([HAVE_WCRTOMB])
+  HAVE_WCSRTOMBS=1;     AC_SUBST([HAVE_WCSRTOMBS])
+  HAVE_WCSNRTOMBS=1;    AC_SUBST([HAVE_WCSNRTOMBS])
+  HAVE_DECL_WCTOB=1;    AC_SUBST([HAVE_DECL_WCTOB])
+  HAVE_DECL_WCWIDTH=1;  AC_SUBST([HAVE_DECL_WCWIDTH])
+  REPLACE_MBSTATE_T=0;  AC_SUBST([REPLACE_MBSTATE_T])
+  REPLACE_BTOWC=0;      AC_SUBST([REPLACE_BTOWC])
+  REPLACE_WCTOB=0;      AC_SUBST([REPLACE_WCTOB])
+  REPLACE_MBSINIT=0;    AC_SUBST([REPLACE_MBSINIT])
+  REPLACE_MBRTOWC=0;    AC_SUBST([REPLACE_MBRTOWC])
+  REPLACE_MBRLEN=0;     AC_SUBST([REPLACE_MBRLEN])
+  REPLACE_MBSRTOWCS=0;  AC_SUBST([REPLACE_MBSRTOWCS])
+  REPLACE_MBSNRTOWCS=0; AC_SUBST([REPLACE_MBSNRTOWCS])
+  REPLACE_WCRTOMB=0;    AC_SUBST([REPLACE_WCRTOMB])
+  REPLACE_WCSRTOMBS=0;  AC_SUBST([REPLACE_WCSRTOMBS])
+  REPLACE_WCSNRTOMBS=0; AC_SUBST([REPLACE_WCSNRTOMBS])
+  REPLACE_WCWIDTH=0;    AC_SUBST([REPLACE_WCWIDTH])
+])
diff --git a/gl/m4/wchar_t.m4 b/gl/m4/wchar_t.m4
new file mode 100644
index 0000000..d2c03c4
--- /dev/null
+++ b/gl/m4/wchar_t.m4
@@ -0,0 +1,24 @@
+# wchar_t.m4 serial 4 (gettext-0.18.2)
+dnl Copyright (C) 2002-2003, 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <stddef.h> has the 'wchar_t' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WCHAR_T],
+[
+  AC_CACHE_CHECK([for wchar_t], [gt_cv_c_wchar_t],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[#include <stddef.h>
+            wchar_t foo = (wchar_t)'\0';]],
+          [[]])],
+       [gt_cv_c_wchar_t=yes],
+       [gt_cv_c_wchar_t=no])])
+  if test $gt_cv_c_wchar_t = yes; then
+    AC_DEFINE([HAVE_WCHAR_T], [1], [Define if you have the 'wchar_t' type.])
+  fi
+])
diff --git a/gl/m4/wcrtomb.m4 b/gl/m4/wcrtomb.m4
new file mode 100644
index 0000000..2905d9b
--- /dev/null
+++ b/gl/m4/wcrtomb.m4
@@ -0,0 +1,101 @@
+# wcrtomb.m4 serial 8
+dnl Copyright (C) 2008-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+AC_DEFUN([gl_FUNC_WCRTOMB],
+[
+  AC_REQUIRE([gl_WCHAR_H_DEFAULTS])
+
+  AC_REQUIRE([AC_TYPE_MBSTATE_T])
+  gl_MBSTATE_T_BROKEN
+
+  AC_CHECK_FUNCS_ONCE([wcrtomb])
+  if test $ac_cv_func_wcrtomb = no; then
+    HAVE_WCRTOMB=0
+  else
+    if test $REPLACE_MBSTATE_T = 1; then
+      REPLACE_WCRTOMB=1
+    else
+      dnl On AIX 4.3, OSF/1 5.1 and Solaris 10, wcrtomb (NULL, 0, NULL) sometimes
+      dnl returns 0 instead of 1.
+      AC_REQUIRE([AC_PROG_CC])
+      AC_REQUIRE([gt_LOCALE_FR])
+      AC_REQUIRE([gt_LOCALE_FR_UTF8])
+      AC_REQUIRE([gt_LOCALE_JA])
+      AC_REQUIRE([gt_LOCALE_ZH_CN])
+      AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
+      AC_CACHE_CHECK([whether wcrtomb return value is correct],
+        [gl_cv_func_wcrtomb_retval],
+        [
+          dnl Initial guess, used when cross-compiling or when no suitable locale
+          dnl is present.
+changequote(,)dnl
+          case "$host_os" in
+                                     # Guess no on AIX 4, OSF/1 and Solaris.
+            aix4* | osf* | solaris*) gl_cv_func_wcrtomb_retval="guessing no" ;;
+                                     # Guess yes otherwise.
+            *)                       gl_cv_func_wcrtomb_retval="guessing yes" ;;
+          esac
+changequote([,])dnl
+          if test $LOCALE_FR != none || test $LOCALE_FR_UTF8 != none || test $LOCALE_JA != none || test $LOCALE_ZH_CN != none; then
+            AC_RUN_IFELSE(
+              [AC_LANG_SOURCE([[
+#include <locale.h>
+#include <string.h>
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+int main ()
+{
+  int result = 0;
+  if (setlocale (LC_ALL, "$LOCALE_FR") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 1;
+    }
+  if (setlocale (LC_ALL, "$LOCALE_FR_UTF8") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 2;
+    }
+  if (setlocale (LC_ALL, "$LOCALE_JA") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 4;
+    }
+  if (setlocale (LC_ALL, "$LOCALE_ZH_CN") != NULL)
+    {
+      if (wcrtomb (NULL, 0, NULL) != 1)
+        result |= 8;
+    }
+  return result;
+}]])],
+              [gl_cv_func_wcrtomb_retval=yes],
+              [gl_cv_func_wcrtomb_retval=no],
+              [:])
+          fi
+        ])
+      case "$gl_cv_func_wcrtomb_retval" in
+        *yes) ;;
+        *) REPLACE_WCRTOMB=1 ;;
+      esac
+    fi
+  fi
+  if test $HAVE_WCRTOMB = 0 || test $REPLACE_WCRTOMB = 1; then
+    gl_REPLACE_WCHAR_H
+    AC_LIBOBJ([wcrtomb])
+    gl_PREREQ_WCRTOMB
+  fi
+])
+
+# Prerequisites of lib/wcrtomb.c.
+AC_DEFUN([gl_PREREQ_WCRTOMB], [
+  :
+])
diff --git a/gl/m4/wctype_h.m4 b/gl/m4/wctype_h.m4
new file mode 100644
index 0000000..d2b37ce
--- /dev/null
+++ b/gl/m4/wctype_h.m4
@@ -0,0 +1,100 @@
+# wctype_h.m4 serial 12
+
+dnl A placeholder for ISO C99 <wctype.h>, for platforms that lack it.
+
+dnl Copyright (C) 2006-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl Written by Paul Eggert.
+
+AC_DEFUN([gl_WCTYPE_H],
+[
+  AC_REQUIRE([AC_PROG_CC])
+  AC_REQUIRE([AC_CANONICAL_HOST])
+  AC_CHECK_FUNCS_ONCE([iswcntrl])
+  if test $ac_cv_func_iswcntrl = yes; then
+    HAVE_ISWCNTRL=1
+  else
+    HAVE_ISWCNTRL=0
+  fi
+  AC_SUBST([HAVE_ISWCNTRL])
+  AC_CHECK_FUNCS_ONCE([iswblank])
+  AC_CHECK_DECLS_ONCE([iswblank])
+  if test $ac_cv_func_iswblank = yes; then
+    HAVE_ISWBLANK=1
+    REPLACE_ISWBLANK=0
+  else
+    HAVE_ISWBLANK=0
+    if test $ac_cv_have_decl_iswblank = yes; then
+      REPLACE_ISWBLANK=1
+    else
+      REPLACE_ISWBLANK=0
+    fi
+  fi
+  AC_SUBST([HAVE_ISWBLANK])
+  AC_SUBST([REPLACE_ISWBLANK])
+
+  AC_REQUIRE([AC_C_INLINE])
+
+  AC_REQUIRE([gt_TYPE_WINT_T])
+  if test $gt_cv_c_wint_t = yes; then
+    HAVE_WINT_T=1
+  else
+    HAVE_WINT_T=0
+  fi
+  AC_SUBST([HAVE_WINT_T])
+
+  gl_CHECK_NEXT_HEADERS([wctype.h])
+  if test $ac_cv_header_wctype_h = yes; then
+    if test $ac_cv_func_iswcntrl = yes; then
+      dnl Linux libc5 has an iswprint function that returns 0 for all arguments.
+      dnl The other functions are likely broken in the same way.
+      AC_CACHE_CHECK([whether iswcntrl works], [gl_cv_func_iswcntrl_works],
+        [
+          AC_RUN_IFELSE(
+            [AC_LANG_SOURCE([[
+               /* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be
+                  included before <wchar.h>.
+                  BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h>
+                  must be included before <wchar.h>.  */
+               #include <stddef.h>
+               #include <stdio.h>
+               #include <time.h>
+               #include <wchar.h>
+               #include <wctype.h>
+               int main () { return iswprint ('x') == 0; }
+            ]])],
+            [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no],
+            [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>
+                          #if __GNU_LIBRARY__ == 1
+                          Linux libc5 i18n is broken.
+                          #endif]], [])],
+              [gl_cv_func_iswcntrl_works=yes], [gl_cv_func_iswcntrl_works=no])
+            ])
+        ])
+    fi
+    HAVE_WCTYPE_H=1
+  else
+    HAVE_WCTYPE_H=0
+  fi
+  AC_SUBST([HAVE_WCTYPE_H])
+
+  if test "$gl_cv_func_iswcntrl_works" = no; then
+    REPLACE_ISWCNTRL=1
+  else
+    REPLACE_ISWCNTRL=0
+  fi
+  AC_SUBST([REPLACE_ISWCNTRL])
+
+  if test $HAVE_ISWCNTRL = 0 || test $REPLACE_ISWCNTRL = 1; then
+    dnl Redefine all of iswcntrl, ..., towupper in <wctype.h>.
+    :
+  else
+    if test $HAVE_ISWBLANK = 0 || test $REPLACE_ISWBLANK = 1; then
+      dnl Redefine only iswblank.
+      AC_LIBOBJ([iswblank])
+    fi
+  fi
+])
diff --git a/gl/m4/wint_t.m4 b/gl/m4/wint_t.m4
new file mode 100644
index 0000000..da1ce3d
--- /dev/null
+++ b/gl/m4/wint_t.m4
@@ -0,0 +1,32 @@
+# wint_t.m4 serial 5 (gettext-0.18.2)
+dnl Copyright (C) 2003, 2007-2011 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+dnl Test whether <wchar.h> has the 'wint_t' type.
+dnl Prerequisite: AC_PROG_CC
+
+AC_DEFUN([gt_TYPE_WINT_T],
+[
+  AC_CACHE_CHECK([for wint_t], [gt_cv_c_wint_t],
+    [AC_COMPILE_IFELSE(
+       [AC_LANG_PROGRAM(
+          [[
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be included
+   before <wchar.h>.  */
+#include <stddef.h>
+#include <stdio.h>
+#include <time.h>
+#include <wchar.h>
+            wint_t foo = (wchar_t)'\0';]],
+          [[]])],
+       [gt_cv_c_wint_t=yes],
+       [gt_cv_c_wint_t=no])])
+  if test $gt_cv_c_wint_t = yes; then
+    AC_DEFINE([HAVE_WINT_T], [1], [Define if you have the 'wint_t' type.])
+  fi
+])
diff --git a/gl/malloc.c b/gl/malloc.c
new file mode 100644
index 0000000..6a417c3
--- /dev/null
+++ b/gl/malloc.c
@@ -0,0 +1,60 @@
+/* malloc() function that is glibc compatible.
+
+   Copyright (C) 1997-1998, 2006-2007, 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/* written by Jim Meyering and Bruno Haible */
+
+#include <config.h>
+/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h.  */
+#ifdef malloc
+# define NEED_MALLOC_GNU 1
+# undef malloc
+/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU.  */
+#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU
+# define NEED_MALLOC_GNU 1
+#endif
+
+/* Specification.  */
+#include <stdlib.h>
+
+#include <errno.h>
+
+/* Call the system's malloc below.  */
+#undef malloc
+
+/* Allocate an N-byte block of memory from the heap.
+   If N is zero, allocate a 1-byte block.  */
+
+void *
+rpl_malloc (size_t n)
+{
+  void *result;
+
+#if NEED_MALLOC_GNU
+  if (n == 0)
+    n = 1;
+#endif
+
+  result = malloc (n);
+
+#if !HAVE_MALLOC_POSIX
+  if (result == NULL)
+    errno = ENOMEM;
+#endif
+
+  return result;
+}
diff --git a/gl/mbrtowc.c b/gl/mbrtowc.c
new file mode 100644
index 0000000..16bc228
--- /dev/null
+++ b/gl/mbrtowc.c
@@ -0,0 +1,395 @@
+/* Convert multibyte character to wide character.
+   Copyright (C) 1999-2002, 2005-2011 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno at clisp.org>, 2008.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <wchar.h>
+
+#if GNULIB_defined_mbstate_t
+/* Implement mbrtowc() on top of mbtowc().  */
+
+# include <errno.h>
+# include <stdlib.h>
+
+# include "localcharset.h"
+# include "streq.h"
+# include "verify.h"
+
+
+verify (sizeof (mbstate_t) >= 4);
+
+static char internal_state[4];
+
+size_t
+mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
+{
+  char *pstate = (char *)ps;
+
+  if (pstate == NULL)
+    pstate = internal_state;
+
+  if (s == NULL)
+    {
+      pwc = NULL;
+      s = "";
+      n = 1;
+    }
+
+  if (n == 0)
+    return (size_t)(-2);
+
+  /* Here n > 0.  */
+  {
+    size_t nstate = pstate[0];
+    char buf[4];
+    const char *p;
+    size_t m;
+
+    switch (nstate)
+      {
+      case 0:
+        p = s;
+        m = n;
+        break;
+      case 3:
+        buf[2] = pstate[3];
+        /*FALLTHROUGH*/
+      case 2:
+        buf[1] = pstate[2];
+        /*FALLTHROUGH*/
+      case 1:
+        buf[0] = pstate[1];
+        p = buf;
+        m = nstate;
+        buf[m++] = s[0];
+        if (n >= 2 && m < 4)
+          {
+            buf[m++] = s[1];
+            if (n >= 3 && m < 4)
+              buf[m++] = s[2];
+          }
+        break;
+      default:
+        errno = EINVAL;
+        return (size_t)(-1);
+      }
+
+    /* Here m > 0.  */
+
+# if __GLIBC__ || defined __UCLIBC__
+    /* Work around bug <http://sourceware.org/bugzilla/show_bug.cgi?id=9674> */
+    mbtowc (NULL, NULL, 0);
+# endif
+    {
+      int res = mbtowc (pwc, p, m);
+
+      if (res >= 0)
+        {
+          if (pwc != NULL && ((*pwc == 0) != (res == 0)))
+            abort ();
+          if (nstate >= (res > 0 ? res : 1))
+            abort ();
+          res -= nstate;
+          pstate[0] = 0;
+          return res;
+        }
+
+      /* mbtowc does not distinguish between invalid and incomplete multibyte
+         sequences.  But mbrtowc needs to make this distinction.
+         There are two possible approaches:
+           - Use iconv() and its return value.
+           - Use built-in knowledge about the possible encodings.
+         Given the low quality of implementation of iconv() on the systems that
+         lack mbrtowc(), we use the second approach.
+         The possible encodings are:
+           - 8-bit encodings,
+           - EUC-JP, EUC-KR, GB2312, EUC-TW, BIG5, GB18030, SJIS,
+           - UTF-8.
+         Use specialized code for each.  */
+      if (m >= 4 || m >= MB_CUR_MAX)
+        goto invalid;
+      /* Here MB_CUR_MAX > 1 and 0 < m < 4.  */
+      {
+        const char *encoding = locale_charset ();
+
+        if (STREQ (encoding, "UTF-8", 'U', 'T', 'F', '-', '8', 0, 0, 0, 0))
+          {
+            /* Cf. unistr/u8-mblen.c.  */
+            unsigned char c = (unsigned char) p[0];
+
+            if (c >= 0xc2)
+              {
+                if (c < 0xe0)
+                  {
+                    if (m == 1)
+                      goto incomplete;
+                  }
+                else if (c < 0xf0)
+                  {
+                    if (m == 1)
+                      goto incomplete;
+                    if (m == 2)
+                      {
+                        unsigned char c2 = (unsigned char) p[1];
+
+                        if ((c2 ^ 0x80) < 0x40
+                            && (c >= 0xe1 || c2 >= 0xa0)
+                            && (c != 0xed || c2 < 0xa0))
+                          goto incomplete;
+                      }
+                  }
+                else if (c <= 0xf4)
+                  {
+                    if (m == 1)
+                      goto incomplete;
+                    else /* m == 2 || m == 3 */
+                      {
+                        unsigned char c2 = (unsigned char) p[1];
+
+                        if ((c2 ^ 0x80) < 0x40
+                            && (c >= 0xf1 || c2 >= 0x90)
+                            && (c < 0xf4 || (c == 0xf4 && c2 < 0x90)))
+                          {
+                            if (m == 2)
+                              goto incomplete;
+                            else /* m == 3 */
+                              {
+                                unsigned char c3 = (unsigned char) p[2];
+
+                                if ((c3 ^ 0x80) < 0x40)
+                                  goto incomplete;
+                              }
+                          }
+                      }
+                  }
+              }
+            goto invalid;
+          }
+
+        /* As a reference for this code, you can use the GNU libiconv
+           implementation.  Look for uses of the RET_TOOFEW macro.  */
+
+        if (STREQ (encoding, "EUC-JP", 'E', 'U', 'C', '-', 'J', 'P', 0, 0, 0))
+          {
+            if (m == 1)
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if ((c >= 0xa1 && c < 0xff) || c == 0x8e || c == 0x8f)
+                  goto incomplete;
+              }
+            if (m == 2)
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if (c == 0x8f)
+                  {
+                    unsigned char c2 = (unsigned char) p[1];
+
+                    if (c2 >= 0xa1 && c2 < 0xff)
+                      goto incomplete;
+                  }
+              }
+            goto invalid;
+          }
+        if (STREQ (encoding, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0)
+            || STREQ (encoding, "GB2312", 'G', 'B', '2', '3', '1', '2', 0, 0, 0)
+            || STREQ (encoding, "BIG5", 'B', 'I', 'G', '5', 0, 0, 0, 0, 0))
+          {
+            if (m == 1)
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if (c >= 0xa1 && c < 0xff)
+                  goto incomplete;
+              }
+            goto invalid;
+          }
+        if (STREQ (encoding, "EUC-TW", 'E', 'U', 'C', '-', 'T', 'W', 0, 0, 0))
+          {
+            if (m == 1)
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if ((c >= 0xa1 && c < 0xff) || c == 0x8e)
+                  goto incomplete;
+              }
+            else /* m == 2 || m == 3 */
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if (c == 0x8e)
+                  goto incomplete;
+              }
+            goto invalid;
+          }
+        if (STREQ (encoding, "GB18030", 'G', 'B', '1', '8', '0', '3', '0', 0, 0))
+          {
+            if (m == 1)
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if ((c >= 0x90 && c <= 0xe3) || (c >= 0xf8 && c <= 0xfe))
+                  goto incomplete;
+              }
+            else /* m == 2 || m == 3 */
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if (c >= 0x90 && c <= 0xe3)
+                  {
+                    unsigned char c2 = (unsigned char) p[1];
+
+                    if (c2 >= 0x30 && c2 <= 0x39)
+                      {
+                        if (m == 2)
+                          goto incomplete;
+                        else /* m == 3 */
+                          {
+                            unsigned char c3 = (unsigned char) p[2];
+
+                            if (c3 >= 0x81 && c3 <= 0xfe)
+                              goto incomplete;
+                          }
+                      }
+                  }
+              }
+            goto invalid;
+          }
+        if (STREQ (encoding, "SJIS", 'S', 'J', 'I', 'S', 0, 0, 0, 0, 0))
+          {
+            if (m == 1)
+              {
+                unsigned char c = (unsigned char) p[0];
+
+                if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xea)
+                    || (c >= 0xf0 && c <= 0xf9))
+                  goto incomplete;
+              }
+            goto invalid;
+          }
+
+        /* An unknown multibyte encoding.  */
+        goto incomplete;
+      }
+
+     incomplete:
+      {
+        size_t k = nstate;
+        /* Here 0 <= k < m < 4.  */
+        pstate[++k] = s[0];
+        if (k < m)
+          {
+            pstate[++k] = s[1];
+            if (k < m)
+              pstate[++k] = s[2];
+          }
+        if (k != m)
+          abort ();
+      }
+      pstate[0] = m;
+      return (size_t)(-2);
+
+     invalid:
+      errno = EILSEQ;
+      /* The conversion state is undefined, says POSIX.  */
+      return (size_t)(-1);
+    }
+  }
+}
+
+#else
+/* Override the system's mbrtowc() function.  */
+
+# undef mbrtowc
+
+size_t
+rpl_mbrtowc (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps)
+{
+# if MBRTOWC_NULL_ARG2_BUG || MBRTOWC_RETVAL_BUG
+  if (s == NULL)
+    {
+      pwc = NULL;
+      s = "";
+      n = 1;
+    }
+# endif
+
+# if MBRTOWC_RETVAL_BUG
+  {
+    static mbstate_t internal_state;
+
+    /* Override mbrtowc's internal state.  We can not call mbsinit() on the
+       hidden internal state, but we can call it on our variable.  */
+    if (ps == NULL)
+      ps = &internal_state;
+
+    if (!mbsinit (ps))
+      {
+        /* Parse the rest of the multibyte character byte for byte.  */
+        size_t count = 0;
+        for (; n > 0; s++, n--)
+          {
+            wchar_t wc;
+            size_t ret = mbrtowc (&wc, s, 1, ps);
+
+            if (ret == (size_t)(-1))
+              return (size_t)(-1);
+            count++;
+            if (ret != (size_t)(-2))
+              {
+                /* The multibyte character has been completed.  */
+                if (pwc != NULL)
+                  *pwc = wc;
+                return (wc == 0 ? 0 : count);
+              }
+          }
+        return (size_t)(-2);
+      }
+  }
+# endif
+
+# if MBRTOWC_NUL_RETVAL_BUG
+  {
+    wchar_t wc;
+    size_t ret = mbrtowc (&wc, s, n, ps);
+
+    if (ret != (size_t)(-1) && ret != (size_t)(-2))
+      {
+        if (pwc != NULL)
+          *pwc = wc;
+        if (wc == 0)
+          ret = 0;
+      }
+    return ret;
+  }
+# else
+  {
+#   if MBRTOWC_NULL_ARG1_BUG
+    wchar_t dummy;
+
+    if (pwc == NULL)
+      pwc = &dummy;
+#   endif
+
+    return mbrtowc (pwc, s, n, ps);
+  }
+# endif
+}
+
+#endif
diff --git a/gl/mbsinit.c b/gl/mbsinit.c
new file mode 100644
index 0000000..3390f6a
--- /dev/null
+++ b/gl/mbsinit.c
@@ -0,0 +1,47 @@
+/* Test for initial conversion state.
+   Copyright (C) 2008-2011 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno at clisp.org>, 2008.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <wchar.h>
+
+#include "verify.h"
+
+/* Platforms that lack mbsinit() also lack mbrlen(), mbrtowc(), mbsrtowcs()
+   and wcrtomb(), wcsrtombs().
+   We assume that
+     - sizeof (mbstate_t) >= 4,
+     - only stateless encodings are supported (such as UTF-8 and EUC-JP, but
+       not ISO-2022 variants),
+     - for each encoding, the number of bytes for a wide character is <= 4.
+       (This maximum is attained for UTF-8, GB18030, EUC-TW.)
+   We define the meaning of mbstate_t as follows:
+     - In mb -> wc direction, mbstate_t's first byte contains the number of
+       buffered bytes (in the range 0..3), followed by up to 3 buffered bytes.
+     - In wc -> mb direction, mbstate_t contains no information. In other
+       words, it is always in the initial state.  */
+
+verify (sizeof (mbstate_t) >= 4);
+
+int
+mbsinit (const mbstate_t *ps)
+{
+  const char *pstate = (const char *)ps;
+
+  return pstate[0] == 0;
+}
diff --git a/gl/nl_langinfo.c b/gl/nl_langinfo.c
new file mode 100644
index 0000000..0754137
--- /dev/null
+++ b/gl/nl_langinfo.c
@@ -0,0 +1,270 @@
+/* nl_langinfo() replacement: query locale dependent information.
+
+   Copyright (C) 2007-2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <langinfo.h>
+
+#if REPLACE_NL_LANGINFO
+
+/* Override nl_langinfo with support for added nl_item values.  */
+
+# include <locale.h>
+# include <string.h>
+
+# undef nl_langinfo
+
+char *
+rpl_nl_langinfo (nl_item item)
+{
+  switch (item)
+    {
+# if GNULIB_defined_CODESET
+    case CODESET:
+      {
+        const char *locale;
+        static char buf[2 + 10 + 1];
+
+        locale = setlocale (LC_CTYPE, NULL);
+        if (locale != NULL && locale[0] != '\0')
+          {
+            /* If the locale name contains an encoding after the dot, return
+               it.  */
+            const char *dot = strchr (locale, '.');
+
+            if (dot != NULL)
+              {
+                const char *modifier;
+
+                dot++;
+                /* Look for the possible @... trailer and remove it, if any.  */
+                modifier = strchr (dot, '@');
+                if (modifier == NULL)
+                  return dot;
+                if (modifier - dot < sizeof (buf))
+                  {
+                    memcpy (buf, dot, modifier - dot);
+                    buf [modifier - dot] = '\0';
+                    return buf;
+                  }
+              }
+          }
+        return "";
+      }
+# endif
+# if GNULIB_defined_T_FMT_AMPM
+    case T_FMT_AMPM:
+      return "%I:%M:%S %p";
+# endif
+# if GNULIB_defined_ERA
+    case ERA:
+      /* The format is not standardized.  In glibc it is a sequence of strings
+         of the form "direction:offset:start_date:end_date:era_name:era_format"
+         with an empty string at the end.  */
+      return "";
+    case ERA_D_FMT:
+      /* The %Ex conversion in strftime behaves like %x if the locale does not
+         have an alternative time format.  */
+      item = D_FMT;
+      break;
+    case ERA_D_T_FMT:
+      /* The %Ec conversion in strftime behaves like %c if the locale does not
+         have an alternative time format.  */
+      item = D_T_FMT;
+      break;
+    case ERA_T_FMT:
+      /* The %EX conversion in strftime behaves like %X if the locale does not
+         have an alternative time format.  */
+      item = T_FMT;
+      break;
+    case ALT_DIGITS:
+      /* The format is not standardized.  In glibc it is a sequence of 10
+         strings, appended in memory.  */
+      return "\0\0\0\0\0\0\0\0\0\0";
+# endif
+# if GNULIB_defined_YESEXPR || !FUNC_NL_LANGINFO_YESEXPR_WORKS
+    case YESEXPR:
+      return "^[yY]";
+    case NOEXPR:
+      return "^[nN]";
+# endif
+    default:
+      break;
+    }
+  return nl_langinfo (item);
+}
+
+#else
+
+/* Provide nl_langinfo from scratch.  */
+
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+/* Native Windows platforms.  */
+
+#  define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#  include <windows.h>
+
+#  include <stdio.h>
+
+# else
+
+/* An old Unix platform without locales, such as Linux libc5 or BeOS.  */
+
+# endif
+
+# include <locale.h>
+
+char *
+nl_langinfo (nl_item item)
+{
+  switch (item)
+    {
+    /* nl_langinfo items of the LC_CTYPE category */
+    case CODESET:
+# if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+      {
+        static char buf[2 + 10 + 1];
+
+        /* Woe32 has a function returning the locale's codepage as a number.  */
+        sprintf (buf, "CP%u", GetACP ());
+        return buf;
+      }
+# elif defined __BEOS__
+      return "UTF-8";
+# else
+      return "ISO-8859-1";
+# endif
+    /* nl_langinfo items of the LC_NUMERIC category */
+    case RADIXCHAR:
+      return localeconv () ->decimal_point;
+    case THOUSEP:
+      return localeconv () ->thousands_sep;
+    /* nl_langinfo items of the LC_TIME category.
+       TODO: Really use the locale.  */
+    case D_T_FMT:
+    case ERA_D_T_FMT:
+      return "%a %b %e %H:%M:%S %Y";
+    case D_FMT:
+    case ERA_D_FMT:
+      return "%m/%d/%y";
+    case T_FMT:
+    case ERA_T_FMT:
+      return "%H:%M:%S";
+    case T_FMT_AMPM:
+      return "%I:%M:%S %p";
+    case AM_STR:
+      return "AM";
+    case PM_STR:
+      return "PM";
+    case DAY_1:
+      return "Sunday";
+    case DAY_2:
+      return "Monday";
+    case DAY_3:
+      return "Tuesday";
+    case DAY_4:
+      return "Wednesday";
+    case DAY_5:
+      return "Thursday";
+    case DAY_6:
+      return "Friday";
+    case DAY_7:
+      return "Saturday";
+    case ABDAY_1:
+      return "Sun";
+    case ABDAY_2:
+      return "Mon";
+    case ABDAY_3:
+      return "Tue";
+    case ABDAY_4:
+      return "Wed";
+    case ABDAY_5:
+      return "Thu";
+    case ABDAY_6:
+      return "Fri";
+    case ABDAY_7:
+      return "Sat";
+    case MON_1:
+      return "January";
+    case MON_2:
+      return "February";
+    case MON_3:
+      return "March";
+    case MON_4:
+      return "April";
+    case MON_5:
+      return "May";
+    case MON_6:
+      return "June";
+    case MON_7:
+      return "July";
+    case MON_8:
+      return "August";
+    case MON_9:
+      return "September";
+    case MON_10:
+      return "October";
+    case MON_11:
+      return "November";
+    case MON_12:
+      return "December";
+    case ABMON_1:
+      return "Jan";
+    case ABMON_2:
+      return "Feb";
+    case ABMON_3:
+      return "Mar";
+    case ABMON_4:
+      return "Apr";
+    case ABMON_5:
+      return "May";
+    case ABMON_6:
+      return "Jun";
+    case ABMON_7:
+      return "Jul";
+    case ABMON_8:
+      return "Aug";
+    case ABMON_9:
+      return "Sep";
+    case ABMON_10:
+      return "Oct";
+    case ABMON_11:
+      return "Nov";
+    case ABMON_12:
+      return "Dec";
+    case ERA:
+      return "";
+    case ALT_DIGITS:
+      return "\0\0\0\0\0\0\0\0\0\0";
+    /* nl_langinfo items of the LC_MONETARY category
+       TODO: Really use the locale. */
+    case CRNCYSTR:
+      return "-";
+    /* nl_langinfo items of the LC_MESSAGES category
+       TODO: Really use the locale. */
+    case YESEXPR:
+      return "^[yY]";
+    case NOEXPR:
+      return "^[nN]";
+    default:
+      return "";
+    }
+}
+
+#endif
diff --git a/gl/ref-add.sin b/gl/ref-add.sin
new file mode 100644
index 0000000..7a14c4d
--- /dev/null
+++ b/gl/ref-add.sin
@@ -0,0 +1,30 @@
+# Add this package to a list of references stored in a text file.
+#
+#   Copyright (C) 2000, 2009-2011 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser 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.
+#
+# Written by Bruno Haible <haible at clisp.cons.org>.
+#
+/^# Packages using this file: / {
+  s/# Packages using this file://
+  ta
+  :a
+  s/ @PACKAGE@ / @PACKAGE@ /
+  tb
+  s/ $/ @PACKAGE@ /
+  :b
+  s/^/# Packages using this file:/
+}
diff --git a/gl/ref-del.sin b/gl/ref-del.sin
new file mode 100644
index 0000000..8c8d764
--- /dev/null
+++ b/gl/ref-del.sin
@@ -0,0 +1,25 @@
+# Remove this package from a list of references stored in a text file.
+#
+#   Copyright (C) 2000, 2009-2011 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser 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.
+#
+# Written by Bruno Haible <haible at clisp.cons.org>.
+#
+/^# Packages using this file: / {
+  s/# Packages using this file://
+  s/ @PACKAGE@ / /
+  s/^/# Packages using this file:/
+}
diff --git a/gl/regcomp.c b/gl/regcomp.c
new file mode 100644
index 0000000..e631417
--- /dev/null
+++ b/gl/regcomp.c
@@ -0,0 +1,3876 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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. */
+
+static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern,
+					  size_t length, reg_syntax_t syntax);
+static void re_compile_fastmap_iter (regex_t *bufp,
+				     const re_dfastate_t *init_state,
+				     char *fastmap);
+static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len);
+#ifdef RE_ENABLE_I18N
+static void free_charset (re_charset_t *cset);
+#endif /* RE_ENABLE_I18N */
+static void free_workarea_compile (regex_t *preg);
+static reg_errcode_t create_initial_state (re_dfa_t *dfa);
+#ifdef RE_ENABLE_I18N
+static void optimize_utf8 (re_dfa_t *dfa);
+#endif
+static reg_errcode_t analyze (regex_t *preg);
+static reg_errcode_t preorder (bin_tree_t *root,
+			       reg_errcode_t (fn (void *, bin_tree_t *)),
+			       void *extra);
+static reg_errcode_t postorder (bin_tree_t *root,
+				reg_errcode_t (fn (void *, bin_tree_t *)),
+				void *extra);
+static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node);
+static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node);
+static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg,
+				 bin_tree_t *node);
+static reg_errcode_t calc_first (void *extra, bin_tree_t *node);
+static reg_errcode_t calc_next (void *extra, bin_tree_t *node);
+static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node);
+static Idx duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint);
+static Idx search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
+				   unsigned int constraint);
+static reg_errcode_t calc_eclosure (re_dfa_t *dfa);
+static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa,
+					 Idx node, bool root);
+static reg_errcode_t calc_inveclosure (re_dfa_t *dfa);
+static Idx fetch_number (re_string_t *input, re_token_t *token,
+			 reg_syntax_t syntax);
+static int peek_token (re_token_t *token, re_string_t *input,
+			reg_syntax_t syntax) internal_function;
+static bin_tree_t *parse (re_string_t *regexp, regex_t *preg,
+			  reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg,
+				  re_token_t *token, reg_syntax_t syntax,
+				  Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg,
+				 re_token_t *token, reg_syntax_t syntax,
+				 Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg,
+				     re_token_t *token, reg_syntax_t syntax,
+				     Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg,
+				  re_token_t *token, reg_syntax_t syntax,
+				  Idx nest, reg_errcode_t *err);
+static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp,
+				 re_dfa_t *dfa, re_token_t *token,
+				 reg_syntax_t syntax, reg_errcode_t *err);
+static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa,
+				      re_token_t *token, reg_syntax_t syntax,
+				      reg_errcode_t *err);
+static reg_errcode_t parse_bracket_element (bracket_elem_t *elem,
+					    re_string_t *regexp,
+					    re_token_t *token, int token_len,
+					    re_dfa_t *dfa,
+					    reg_syntax_t syntax,
+					    bool accept_hyphen);
+static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem,
+					  re_string_t *regexp,
+					  re_token_t *token);
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t build_equiv_class (bitset_t sbcset,
+					re_charset_t *mbcset,
+					Idx *equiv_class_alloc,
+					const unsigned char *name);
+static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+				      bitset_t sbcset,
+				      re_charset_t *mbcset,
+				      Idx *char_class_alloc,
+				      const unsigned char *class_name,
+				      reg_syntax_t syntax);
+#else  /* not RE_ENABLE_I18N */
+static reg_errcode_t build_equiv_class (bitset_t sbcset,
+					const unsigned char *name);
+static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans,
+				      bitset_t sbcset,
+				      const unsigned char *class_name,
+				      reg_syntax_t syntax);
+#endif /* not RE_ENABLE_I18N */
+static bin_tree_t *build_charclass_op (re_dfa_t *dfa,
+				       RE_TRANSLATE_TYPE trans,
+				       const unsigned char *class_name,
+				       const unsigned char *extra,
+				       bool non_match, reg_errcode_t *err);
+static bin_tree_t *create_tree (re_dfa_t *dfa,
+				bin_tree_t *left, bin_tree_t *right,
+				re_token_type_t type);
+static bin_tree_t *create_token_tree (re_dfa_t *dfa,
+				      bin_tree_t *left, bin_tree_t *right,
+				      const re_token_t *token);
+static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa);
+static void free_token (re_token_t *node);
+static reg_errcode_t free_tree (void *extra, bin_tree_t *node);
+static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node);
+

+/* This table gives an error message for each of the error codes listed
+   in regex.h.  Obviously the order here has to be same as there.
+   POSIX doesn't require that we do anything for REG_NOERROR,
+   but why not be nice?  */
+
+static const char __re_error_msgid[] =
+  {
+#define REG_NOERROR_IDX	0
+    gettext_noop ("Success")	/* REG_NOERROR */
+    "\0"
+#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
+    gettext_noop ("No match")	/* REG_NOMATCH */
+    "\0"
+#define REG_BADPAT_IDX	(REG_NOMATCH_IDX + sizeof "No match")
+    gettext_noop ("Invalid regular expression") /* REG_BADPAT */
+    "\0"
+#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
+    gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
+    "\0"
+#define REG_ECTYPE_IDX	(REG_ECOLLATE_IDX + sizeof "Invalid collation character")
+    gettext_noop ("Invalid character class name") /* REG_ECTYPE */
+    "\0"
+#define REG_EESCAPE_IDX	(REG_ECTYPE_IDX + sizeof "Invalid character class name")
+    gettext_noop ("Trailing backslash") /* REG_EESCAPE */
+    "\0"
+#define REG_ESUBREG_IDX	(REG_EESCAPE_IDX + sizeof "Trailing backslash")
+    gettext_noop ("Invalid back reference") /* REG_ESUBREG */
+    "\0"
+#define REG_EBRACK_IDX	(REG_ESUBREG_IDX + sizeof "Invalid back reference")
+    gettext_noop ("Unmatched [ or [^")	/* REG_EBRACK */
+    "\0"
+#define REG_EPAREN_IDX	(REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
+    gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
+    "\0"
+#define REG_EBRACE_IDX	(REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
+    gettext_noop ("Unmatched \\{") /* REG_EBRACE */
+    "\0"
+#define REG_BADBR_IDX	(REG_EBRACE_IDX + sizeof "Unmatched \\{")
+    gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
+    "\0"
+#define REG_ERANGE_IDX	(REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
+    gettext_noop ("Invalid range end")	/* REG_ERANGE */
+    "\0"
+#define REG_ESPACE_IDX	(REG_ERANGE_IDX + sizeof "Invalid range end")
+    gettext_noop ("Memory exhausted") /* REG_ESPACE */
+    "\0"
+#define REG_BADRPT_IDX	(REG_ESPACE_IDX + sizeof "Memory exhausted")
+    gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
+    "\0"
+#define REG_EEND_IDX	(REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
+    gettext_noop ("Premature end of regular expression") /* REG_EEND */
+    "\0"
+#define REG_ESIZE_IDX	(REG_EEND_IDX + sizeof "Premature end of regular expression")
+    gettext_noop ("Regular expression too big") /* REG_ESIZE */
+    "\0"
+#define REG_ERPAREN_IDX	(REG_ESIZE_IDX + sizeof "Regular expression too big")
+    gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
+  };
+
+static const size_t __re_error_msgid_idx[] =
+  {
+    REG_NOERROR_IDX,
+    REG_NOMATCH_IDX,
+    REG_BADPAT_IDX,
+    REG_ECOLLATE_IDX,
+    REG_ECTYPE_IDX,
+    REG_EESCAPE_IDX,
+    REG_ESUBREG_IDX,
+    REG_EBRACK_IDX,
+    REG_EPAREN_IDX,
+    REG_EBRACE_IDX,
+    REG_BADBR_IDX,
+    REG_ERANGE_IDX,
+    REG_ESPACE_IDX,
+    REG_BADRPT_IDX,
+    REG_EEND_IDX,
+    REG_ESIZE_IDX,
+    REG_ERPAREN_IDX
+  };
+

+/* Entry points for GNU code.  */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+   compiles PATTERN (of length LENGTH) and puts the result in BUFP.
+   Returns 0 if the pattern was valid, otherwise an error string.
+
+   Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+   are set in BUFP on entry.  */
+
+#ifdef _LIBC
+const char *
+re_compile_pattern (pattern, length, bufp)
+    const char *pattern;
+    size_t length;
+    struct re_pattern_buffer *bufp;
+#else /* size_t might promote */
+const char *
+re_compile_pattern (const char *pattern, size_t length,
+		    struct re_pattern_buffer *bufp)
+#endif
+{
+  reg_errcode_t ret;
+
+  /* And GNU code determines whether or not to get register information
+     by passing null for the REGS argument to re_match, etc., not by
+     setting no_sub, unless RE_NO_SUB is set.  */
+  bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);
+
+  /* Match anchors at newline.  */
+  bufp->newline_anchor = 1;
+
+  ret = re_compile_internal (bufp, pattern, length, re_syntax_options);
+
+  if (!ret)
+    return NULL;
+  return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+#ifdef _LIBC
+weak_alias (__re_compile_pattern, re_compile_pattern)
+#endif
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize.  Can
+   also be assigned to arbitrarily: each pattern buffer stores its own
+   syntax, so it can be changed between regex compilations.  */
+/* This has no initializer because initialized variables in Emacs
+   become read-only after dumping.  */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation.  This provides
+   for compatibility for various utilities which historically have
+   different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit mask comprised of the various bits
+   defined in regex.h.  We return the old syntax.  */
+
+reg_syntax_t
+re_set_syntax (syntax)
+    reg_syntax_t syntax;
+{
+  reg_syntax_t ret = re_syntax_options;
+
+  re_syntax_options = syntax;
+  return ret;
+}
+#ifdef _LIBC
+weak_alias (__re_set_syntax, re_set_syntax)
+#endif
+
+int
+re_compile_fastmap (bufp)
+    struct re_pattern_buffer *bufp;
+{
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+  char *fastmap = bufp->fastmap;
+
+  memset (fastmap, '\0', sizeof (char) * SBC_MAX);
+  re_compile_fastmap_iter (bufp, dfa->init_state, fastmap);
+  if (dfa->init_state != dfa->init_state_word)
+    re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap);
+  if (dfa->init_state != dfa->init_state_nl)
+    re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap);
+  if (dfa->init_state != dfa->init_state_begbuf)
+    re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap);
+  bufp->fastmap_accurate = 1;
+  return 0;
+}
+#ifdef _LIBC
+weak_alias (__re_compile_fastmap, re_compile_fastmap)
+#endif
+
+static inline void
+__attribute ((always_inline))
+re_set_fastmap (char *fastmap, bool icase, int ch)
+{
+  fastmap[ch] = 1;
+  if (icase)
+    fastmap[tolower (ch)] = 1;
+}
+
+/* Helper function for re_compile_fastmap.
+   Compile fastmap for the initial_state INIT_STATE.  */
+
+static void
+re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state,
+			 char *fastmap)
+{
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+  Idx node_cnt;
+  bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
+  for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt)
+    {
+      Idx node = init_state->nodes.elems[node_cnt];
+      re_token_type_t type = dfa->nodes[node].type;
+
+      if (type == CHARACTER)
+	{
+	  re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c);
+#ifdef RE_ENABLE_I18N
+	  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+	    {
+	      unsigned char buf[MB_LEN_MAX];
+	      unsigned char *p;
+	      wchar_t wc;
+	      mbstate_t state;
+
+	      p = buf;
+	      *p++ = dfa->nodes[node].opr.c;
+	      while (++node < dfa->nodes_len
+		     &&	dfa->nodes[node].type == CHARACTER
+		     && dfa->nodes[node].mb_partial)
+		*p++ = dfa->nodes[node].opr.c;
+	      memset (&state, '\0', sizeof (state));
+	      if (__mbrtowc (&wc, (const char *) buf, p - buf,
+			     &state) == p - buf
+		  && (__wcrtomb ((char *) buf, towlower (wc), &state)
+		      != (size_t) -1))
+		re_set_fastmap (fastmap, false, buf[0]);
+	    }
+#endif
+	}
+      else if (type == SIMPLE_BRACKET)
+	{
+	  int i, ch;
+	  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+	    {
+	      int j;
+	      bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
+	      for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+		if (w & ((bitset_word_t) 1 << j))
+		  re_set_fastmap (fastmap, icase, ch);
+	    }
+	}
+#ifdef RE_ENABLE_I18N
+      else if (type == COMPLEX_BRACKET)
+	{
+	  re_charset_t *cset = dfa->nodes[node].opr.mbcset;
+	  Idx i;
+
+# ifdef _LIBC
+	  /* See if we have to try all bytes which start multiple collation
+	     elements.
+	     e.g. In da_DK, we want to catch 'a' since "aa" is a valid
+		  collation element, and don't catch 'b' since 'b' is
+		  the only collation element which starts from 'b' (and
+		  it is caught by SIMPLE_BRACKET).  */
+	      if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0
+		  && (cset->ncoll_syms || cset->nranges))
+		{
+		  const int32_t *table = (const int32_t *)
+		    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+		  for (i = 0; i < SBC_MAX; ++i)
+		    if (table[i] < 0)
+		      re_set_fastmap (fastmap, icase, i);
+		}
+# endif /* _LIBC */
+
+	  /* See if we have to start the match at all multibyte characters,
+	     i.e. where we would not find an invalid sequence.  This only
+	     applies to multibyte character sets; for single byte character
+	     sets, the SIMPLE_BRACKET again suffices.  */
+	  if (dfa->mb_cur_max > 1
+	      && (cset->nchar_classes || cset->non_match || cset->nranges
+# ifdef _LIBC
+		  || cset->nequiv_classes
+# endif /* _LIBC */
+		 ))
+	    {
+	      unsigned char c = 0;
+	      do
+		{
+		  mbstate_t mbs;
+		  memset (&mbs, 0, sizeof (mbs));
+		  if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2)
+		    re_set_fastmap (fastmap, false, (int) c);
+		}
+	      while (++c != 0);
+	    }
+
+	  else
+	    {
+	      /* ... Else catch all bytes which can start the mbchars.  */
+	      for (i = 0; i < cset->nmbchars; ++i)
+		{
+		  char buf[256];
+		  mbstate_t state;
+		  memset (&state, '\0', sizeof (state));
+		  if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1)
+		    re_set_fastmap (fastmap, icase, *(unsigned char *) buf);
+		  if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1)
+		    {
+		      if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state)
+			  != (size_t) -1)
+			re_set_fastmap (fastmap, false, *(unsigned char *) buf);
+		    }
+		}
+	    }
+	}
+#endif /* RE_ENABLE_I18N */
+      else if (type == OP_PERIOD
+#ifdef RE_ENABLE_I18N
+	       || type == OP_UTF8_PERIOD
+#endif /* RE_ENABLE_I18N */
+	       || type == END_OF_RE)
+	{
+	  memset (fastmap, '\1', sizeof (char) * SBC_MAX);
+	  if (type == END_OF_RE)
+	    bufp->can_be_null = 1;
+	  return;
+	}
+    }
+}
+

+/* Entry point for POSIX code.  */
+/* regcomp takes a regular expression as a string and compiles it.
+
+   PREG is a regex_t *.  We do not expect any fields to be initialized,
+   since POSIX says we shouldn't.  Thus, we set
+
+     `buffer' to the compiled pattern;
+     `used' to the length of the compiled pattern;
+     `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+       REG_EXTENDED bit in CFLAGS is set; otherwise, to
+       RE_SYNTAX_POSIX_BASIC;
+     `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+     `fastmap' to an allocated space for the fastmap;
+     `fastmap_accurate' to zero;
+     `re_nsub' to the number of subexpressions in PATTERN.
+
+   PATTERN is the address of the pattern string.
+
+   CFLAGS is a series of bits which affect compilation.
+
+     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+     use POSIX basic syntax.
+
+     If REG_NEWLINE is set, then . and [^...] don't match newline.
+     Also, regexec will try a match beginning after every newline.
+
+     If REG_ICASE is set, then we considers upper- and lowercase
+     versions of letters to be equivalent when matching.
+
+     If REG_NOSUB is set, then when PREG is passed to regexec, that
+     routine will report only success or failure, and nothing about the
+     registers.
+
+   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
+   the return codes and their meanings.)  */
+
+int
+regcomp (preg, pattern, cflags)
+    regex_t *_Restrict_ preg;
+    const char *_Restrict_ pattern;
+    int cflags;
+{
+  reg_errcode_t ret;
+  reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
+			 : RE_SYNTAX_POSIX_BASIC);
+
+  preg->buffer = NULL;
+  preg->allocated = 0;
+  preg->used = 0;
+
+  /* Try to allocate space for the fastmap.  */
+  preg->fastmap = re_malloc (char, SBC_MAX);
+  if (BE (preg->fastmap == NULL, 0))
+    return REG_ESPACE;
+
+  syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
+
+  /* If REG_NEWLINE is set, newlines are treated differently.  */
+  if (cflags & REG_NEWLINE)
+    { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
+      syntax &= ~RE_DOT_NEWLINE;
+      syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+      /* It also changes the matching behavior.  */
+      preg->newline_anchor = 1;
+    }
+  else
+    preg->newline_anchor = 0;
+  preg->no_sub = !!(cflags & REG_NOSUB);
+  preg->translate = NULL;
+
+  ret = re_compile_internal (preg, pattern, strlen (pattern), syntax);
+
+  /* POSIX doesn't distinguish between an unmatched open-group and an
+     unmatched close-group: both are REG_EPAREN.  */
+  if (ret == REG_ERPAREN)
+    ret = REG_EPAREN;
+
+  /* We have already checked preg->fastmap != NULL.  */
+  if (BE (ret == REG_NOERROR, 1))
+    /* Compute the fastmap now, since regexec cannot modify the pattern
+       buffer.  This function never fails in this implementation.  */
+    (void) re_compile_fastmap (preg);
+  else
+    {
+      /* Some error occurred while compiling the expression.  */
+      re_free (preg->fastmap);
+      preg->fastmap = NULL;
+    }
+
+  return (int) ret;
+}
+#ifdef _LIBC
+weak_alias (__regcomp, regcomp)
+#endif
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+   from either regcomp or regexec.   We don't use PREG here.  */
+
+#ifdef _LIBC
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+    int errcode;
+    const regex_t *_Restrict_ preg;
+    char *_Restrict_ errbuf;
+    size_t errbuf_size;
+#else /* size_t might promote */
+size_t
+regerror (int errcode, const regex_t *_Restrict_ preg,
+	  char *_Restrict_ errbuf, size_t errbuf_size)
+#endif
+{
+  const char *msg;
+  size_t msg_size;
+
+  if (BE (errcode < 0
+	  || errcode >= (int) (sizeof (__re_error_msgid_idx)
+			       / sizeof (__re_error_msgid_idx[0])), 0))
+    /* Only error codes returned by the rest of the code should be passed
+       to this routine.  If we are given anything else, or if other regex
+       code generates an invalid error code, then the program has a bug.
+       Dump core so we can fix it.  */
+    abort ();
+
+  msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]);
+
+  msg_size = strlen (msg) + 1; /* Includes the null.  */
+
+  if (BE (errbuf_size != 0, 1))
+    {
+      size_t cpy_size = msg_size;
+      if (BE (msg_size > errbuf_size, 0))
+	{
+	  cpy_size = errbuf_size - 1;
+	  errbuf[cpy_size] = '\0';
+	}
+      memcpy (errbuf, msg, cpy_size);
+    }
+
+  return msg_size;
+}
+#ifdef _LIBC
+weak_alias (__regerror, regerror)
+#endif
+
+
+#ifdef RE_ENABLE_I18N
+/* This static array is used for the map to single-byte characters when
+   UTF-8 is used.  Otherwise we would allocate memory just to initialize
+   it the same all the time.  UTF-8 is the preferred encoding so this is
+   a worthwhile optimization.  */
+static const bitset_t utf8_sb_map =
+{
+  /* Set the first 128 bits.  */
+# if 4 * BITSET_WORD_BITS < ASCII_CHARS
+#  error "bitset_word_t is narrower than 32 bits"
+# elif 3 * BITSET_WORD_BITS < ASCII_CHARS
+  BITSET_WORD_MAX, BITSET_WORD_MAX, BITSET_WORD_MAX,
+# elif 2 * BITSET_WORD_BITS < ASCII_CHARS
+  BITSET_WORD_MAX, BITSET_WORD_MAX,
+# elif 1 * BITSET_WORD_BITS < ASCII_CHARS
+  BITSET_WORD_MAX,
+# endif
+  (BITSET_WORD_MAX
+   >> (SBC_MAX % BITSET_WORD_BITS == 0
+       ? 0
+       : BITSET_WORD_BITS - SBC_MAX % BITSET_WORD_BITS))
+};
+#endif
+
+
+static void
+free_dfa_content (re_dfa_t *dfa)
+{
+  Idx i, j;
+
+  if (dfa->nodes)
+    for (i = 0; i < dfa->nodes_len; ++i)
+      free_token (dfa->nodes + i);
+  re_free (dfa->nexts);
+  for (i = 0; i < dfa->nodes_len; ++i)
+    {
+      if (dfa->eclosures != NULL)
+	re_node_set_free (dfa->eclosures + i);
+      if (dfa->inveclosures != NULL)
+	re_node_set_free (dfa->inveclosures + i);
+      if (dfa->edests != NULL)
+	re_node_set_free (dfa->edests + i);
+    }
+  re_free (dfa->edests);
+  re_free (dfa->eclosures);
+  re_free (dfa->inveclosures);
+  re_free (dfa->nodes);
+
+  if (dfa->state_table)
+    for (i = 0; i <= dfa->state_hash_mask; ++i)
+      {
+	struct re_state_table_entry *entry = dfa->state_table + i;
+	for (j = 0; j < entry->num; ++j)
+	  {
+	    re_dfastate_t *state = entry->array[j];
+	    free_state (state);
+	  }
+	re_free (entry->array);
+      }
+  re_free (dfa->state_table);
+#ifdef RE_ENABLE_I18N
+  if (dfa->sb_char != utf8_sb_map)
+    re_free (dfa->sb_char);
+#endif
+  re_free (dfa->subexp_map);
+#ifdef DEBUG
+  re_free (dfa->re_str);
+#endif
+
+  re_free (dfa);
+}
+
+
+/* Free dynamically allocated space used by PREG.  */
+
+void
+regfree (preg)
+    regex_t *preg;
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  if (BE (dfa != NULL, 1))
+    free_dfa_content (dfa);
+  preg->buffer = NULL;
+  preg->allocated = 0;
+
+  re_free (preg->fastmap);
+  preg->fastmap = NULL;
+
+  re_free (preg->translate);
+  preg->translate = NULL;
+}
+#ifdef _LIBC
+weak_alias (__regfree, regfree)
+#endif
+

+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them unless specifically requested.  */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+
+/* BSD has one and only one pattern buffer.  */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+# ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+   these names if they don't use our functions, and still use
+   regcomp/regexec above without link errors.  */
+weak_function
+# endif
+re_comp (s)
+     const char *s;
+{
+  reg_errcode_t ret;
+  char *fastmap;
+
+  if (!s)
+    {
+      if (!re_comp_buf.buffer)
+	return gettext ("No previous regular expression");
+      return 0;
+    }
+
+  if (re_comp_buf.buffer)
+    {
+      fastmap = re_comp_buf.fastmap;
+      re_comp_buf.fastmap = NULL;
+      __regfree (&re_comp_buf);
+      memset (&re_comp_buf, '\0', sizeof (re_comp_buf));
+      re_comp_buf.fastmap = fastmap;
+    }
+
+  if (re_comp_buf.fastmap == NULL)
+    {
+      re_comp_buf.fastmap = (char *) malloc (SBC_MAX);
+      if (re_comp_buf.fastmap == NULL)
+	return (char *) gettext (__re_error_msgid
+				 + __re_error_msgid_idx[(int) REG_ESPACE]);
+    }
+
+  /* Since `re_exec' always passes NULL for the `regs' argument, we
+     don't need to initialize the pattern buffer fields which affect it.  */
+
+  /* Match anchors at newlines.  */
+  re_comp_buf.newline_anchor = 1;
+
+  ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options);
+
+  if (!ret)
+    return NULL;
+
+  /* Yes, we're discarding `const' here if !HAVE_LIBINTL.  */
+  return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+
+#ifdef _LIBC
+libc_freeres_fn (free_mem)
+{
+  __regfree (&re_comp_buf);
+}
+#endif
+
+#endif /* _REGEX_RE_COMP */
+

+/* Internal entry point.
+   Compile the regular expression PATTERN, whose length is LENGTH.
+   SYNTAX indicate regular expression's syntax.  */
+
+static reg_errcode_t
+re_compile_internal (regex_t *preg, const char * pattern, size_t length,
+		     reg_syntax_t syntax)
+{
+  reg_errcode_t err = REG_NOERROR;
+  re_dfa_t *dfa;
+  re_string_t regexp;
+
+  /* Initialize the pattern buffer.  */
+  preg->fastmap_accurate = 0;
+  preg->syntax = syntax;
+  preg->not_bol = preg->not_eol = 0;
+  preg->used = 0;
+  preg->re_nsub = 0;
+  preg->can_be_null = 0;
+  preg->regs_allocated = REGS_UNALLOCATED;
+
+  /* Initialize the dfa.  */
+  dfa = (re_dfa_t *) preg->buffer;
+  if (BE (preg->allocated < sizeof (re_dfa_t), 0))
+    {
+      /* If zero allocated, but buffer is non-null, try to realloc
+	 enough space.  This loses if buffer's address is bogus, but
+	 that is the user's responsibility.  If ->buffer is NULL this
+	 is a simple allocation.  */
+      dfa = re_realloc (preg->buffer, re_dfa_t, 1);
+      if (dfa == NULL)
+	return REG_ESPACE;
+      preg->allocated = sizeof (re_dfa_t);
+      preg->buffer = (unsigned char *) dfa;
+    }
+  preg->used = sizeof (re_dfa_t);
+
+  err = init_dfa (dfa, length);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+      return err;
+    }
+#ifdef DEBUG
+  /* Note: length+1 will not overflow since it is checked in init_dfa.  */
+  dfa->re_str = re_malloc (char, length + 1);
+  strncpy (dfa->re_str, pattern, length + 1);
+#endif
+
+  __libc_lock_init (dfa->lock);
+
+  err = re_string_construct (&regexp, pattern, length, preg->translate,
+			     (syntax & RE_ICASE) != 0, dfa);
+  if (BE (err != REG_NOERROR, 0))
+    {
+    re_compile_internal_free_return:
+      free_workarea_compile (preg);
+      re_string_destruct (&regexp);
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+      return err;
+    }
+
+  /* Parse the regular expression, and build a structure tree.  */
+  preg->re_nsub = 0;
+  dfa->str_tree = parse (&regexp, preg, syntax, &err);
+  if (BE (dfa->str_tree == NULL, 0))
+    goto re_compile_internal_free_return;
+
+  /* Analyze the tree and create the nfa.  */
+  err = analyze (preg);
+  if (BE (err != REG_NOERROR, 0))
+    goto re_compile_internal_free_return;
+
+#ifdef RE_ENABLE_I18N
+  /* If possible, do searching in single byte encoding to speed things up.  */
+  if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL)
+    optimize_utf8 (dfa);
+#endif
+
+  /* Then create the initial state of the dfa.  */
+  err = create_initial_state (dfa);
+
+  /* Release work areas.  */
+  free_workarea_compile (preg);
+  re_string_destruct (&regexp);
+
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_dfa_content (dfa);
+      preg->buffer = NULL;
+      preg->allocated = 0;
+    }
+
+  return err;
+}
+
+/* Initialize DFA.  We use the length of the regular expression PAT_LEN
+   as the initial length of some arrays.  */
+
+static reg_errcode_t
+init_dfa (re_dfa_t *dfa, size_t pat_len)
+{
+  __re_size_t table_size;
+#ifndef _LIBC
+  char *codeset_name;
+#endif
+#ifdef RE_ENABLE_I18N
+  size_t max_i18n_object_size = MAX (sizeof (wchar_t), sizeof (wctype_t));
+#else
+  size_t max_i18n_object_size = 0;
+#endif
+  size_t max_object_size =
+    MAX (sizeof (struct re_state_table_entry),
+	 MAX (sizeof (re_token_t),
+	      MAX (sizeof (re_node_set),
+		   MAX (sizeof (regmatch_t),
+			max_i18n_object_size))));
+
+  memset (dfa, '\0', sizeof (re_dfa_t));
+
+  /* Force allocation of str_tree_storage the first time.  */
+  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+
+  /* Avoid overflows.  The extra "/ 2" is for the table_size doubling
+     calculation below, and for similar doubling calculations
+     elsewhere.  And it's <= rather than <, because some of the
+     doubling calculations add 1 afterwards.  */
+  if (BE (SIZE_MAX / max_object_size / 2 <= pat_len, 0))
+    return REG_ESPACE;
+
+  dfa->nodes_alloc = pat_len + 1;
+  dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc);
+
+  /*  table_size = 2 ^ ceil(log pat_len) */
+  for (table_size = 1; ; table_size <<= 1)
+    if (table_size > pat_len)
+      break;
+
+  dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size);
+  dfa->state_hash_mask = table_size - 1;
+
+  dfa->mb_cur_max = MB_CUR_MAX;
+#ifdef _LIBC
+  if (dfa->mb_cur_max == 6
+      && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0)
+    dfa->is_utf8 = 1;
+  dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII)
+		       != 0);
+#else
+  codeset_name = nl_langinfo (CODESET);
+  if (strcasecmp (codeset_name, "UTF-8") == 0
+      || strcasecmp (codeset_name, "UTF8") == 0)
+    dfa->is_utf8 = 1;
+
+  /* We check exhaustively in the loop below if this charset is a
+     superset of ASCII.  */
+  dfa->map_notascii = 0;
+#endif
+
+#ifdef RE_ENABLE_I18N
+  if (dfa->mb_cur_max > 1)
+    {
+      if (dfa->is_utf8)
+	dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map;
+      else
+	{
+	  int i, j, ch;
+
+	  dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+	  if (BE (dfa->sb_char == NULL, 0))
+	    return REG_ESPACE;
+
+	  /* Set the bits corresponding to single byte chars.  */
+	  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+	    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+	      {
+		wint_t wch = __btowc (ch);
+		if (wch != WEOF)
+		  dfa->sb_char[i] |= (bitset_word_t) 1 << j;
+# ifndef _LIBC
+		if (isascii (ch) && wch != ch)
+		  dfa->map_notascii = 1;
+# endif
+	      }
+	}
+    }
+#endif
+
+  if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0))
+    return REG_ESPACE;
+  return REG_NOERROR;
+}
+
+/* Initialize WORD_CHAR table, which indicate which character is
+   "word".  In this case "word" means that it is the word construction
+   character used by some operators like "\<", "\>", etc.  */
+
+static void
+internal_function
+init_word_char (re_dfa_t *dfa)
+{
+  int i, j, ch;
+  dfa->word_ops_used = 1;
+  for (i = 0, ch = 0; i < BITSET_WORDS; ++i)
+    for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+      if (isalnum (ch) || ch == '_')
+	dfa->word_char[i] |= (bitset_word_t) 1 << j;
+}
+
+/* Free the work area which are only used while compiling.  */
+
+static void
+free_workarea_compile (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_storage_t *storage, *next;
+  for (storage = dfa->str_tree_storage; storage; storage = next)
+    {
+      next = storage->next;
+      re_free (storage);
+    }
+  dfa->str_tree_storage = NULL;
+  dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+  dfa->str_tree = NULL;
+  re_free (dfa->org_indices);
+  dfa->org_indices = NULL;
+}
+
+/* Create initial states for all contexts.  */
+
+static reg_errcode_t
+create_initial_state (re_dfa_t *dfa)
+{
+  Idx first, i;
+  reg_errcode_t err;
+  re_node_set init_nodes;
+
+  /* Initial states have the epsilon closure of the node which is
+     the first node of the regular expression.  */
+  first = dfa->str_tree->first->node_idx;
+  dfa->init_node = first;
+  err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  /* The back-references which are in initial states can epsilon transit,
+     since in this case all of the subexpressions can be null.
+     Then we add epsilon closures of the nodes which are the next nodes of
+     the back-references.  */
+  if (dfa->nbackref > 0)
+    for (i = 0; i < init_nodes.nelem; ++i)
+      {
+	Idx node_idx = init_nodes.elems[i];
+	re_token_type_t type = dfa->nodes[node_idx].type;
+
+	Idx clexp_idx;
+	if (type != OP_BACK_REF)
+	  continue;
+	for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx)
+	  {
+	    re_token_t *clexp_node;
+	    clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
+	    if (clexp_node->type == OP_CLOSE_SUBEXP
+		&& clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)
+	      break;
+	  }
+	if (clexp_idx == init_nodes.nelem)
+	  continue;
+
+	if (type == OP_BACK_REF)
+	  {
+	    Idx dest_idx = dfa->edests[node_idx].elems[0];
+	    if (!re_node_set_contains (&init_nodes, dest_idx))
+	      {
+		reg_errcode_t merge_err
+                  = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx);
+		if (merge_err != REG_NOERROR)
+		  return merge_err;
+		i = 0;
+	      }
+	  }
+      }
+
+  /* It must be the first time to invoke acquire_state.  */
+  dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
+  /* We don't check ERR here, since the initial state must not be NULL.  */
+  if (BE (dfa->init_state == NULL, 0))
+    return err;
+  if (dfa->init_state->has_constraint)
+    {
+      dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
+						       CONTEXT_WORD);
+      dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes,
+						     CONTEXT_NEWLINE);
+      dfa->init_state_begbuf = re_acquire_state_context (&err, dfa,
+							 &init_nodes,
+							 CONTEXT_NEWLINE
+							 | CONTEXT_BEGBUF);
+      if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+	      || dfa->init_state_begbuf == NULL, 0))
+	return err;
+    }
+  else
+    dfa->init_state_word = dfa->init_state_nl
+      = dfa->init_state_begbuf = dfa->init_state;
+
+  re_node_set_free (&init_nodes);
+  return REG_NOERROR;
+}
+

+#ifdef RE_ENABLE_I18N
+/* If it is possible to do searching in single byte encoding instead of UTF-8
+   to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change
+   DFA nodes where needed.  */
+
+static void
+optimize_utf8 (re_dfa_t *dfa)
+{
+  Idx node;
+  int i;
+  bool mb_chars = false;
+  bool has_period = false;
+
+  for (node = 0; node < dfa->nodes_len; ++node)
+    switch (dfa->nodes[node].type)
+      {
+      case CHARACTER:
+	if (dfa->nodes[node].opr.c >= ASCII_CHARS)
+	  mb_chars = true;
+	break;
+      case ANCHOR:
+	switch (dfa->nodes[node].opr.ctx_type)
+	  {
+	  case LINE_FIRST:
+	  case LINE_LAST:
+	  case BUF_FIRST:
+	  case BUF_LAST:
+	    break;
+	  default:
+	    /* Word anchors etc. cannot be handled.  It's okay to test
+	       opr.ctx_type since constraints (for all DFA nodes) are
+	       created by ORing one or more opr.ctx_type values.  */
+	    return;
+	  }
+	break;
+      case OP_PERIOD:
+	has_period = true;
+	break;
+      case OP_BACK_REF:
+      case OP_ALT:
+      case END_OF_RE:
+      case OP_DUP_ASTERISK:
+      case OP_OPEN_SUBEXP:
+      case OP_CLOSE_SUBEXP:
+	break;
+      case COMPLEX_BRACKET:
+	return;
+      case SIMPLE_BRACKET:
+	/* Just double check.  */
+	{
+	  int rshift = (ASCII_CHARS % BITSET_WORD_BITS == 0
+			? 0
+			: BITSET_WORD_BITS - ASCII_CHARS % BITSET_WORD_BITS);
+	  for (i = ASCII_CHARS / BITSET_WORD_BITS; i < BITSET_WORDS; ++i)
+	    {
+	      if (dfa->nodes[node].opr.sbcset[i] >> rshift != 0)
+		return;
+	      rshift = 0;
+	    }
+	}
+	break;
+      default:
+	abort ();
+      }
+
+  if (mb_chars || has_period)
+    for (node = 0; node < dfa->nodes_len; ++node)
+      {
+	if (dfa->nodes[node].type == CHARACTER
+	    && dfa->nodes[node].opr.c >= ASCII_CHARS)
+	  dfa->nodes[node].mb_partial = 0;
+	else if (dfa->nodes[node].type == OP_PERIOD)
+	  dfa->nodes[node].type = OP_UTF8_PERIOD;
+      }
+
+  /* The search can be in single byte locale.  */
+  dfa->mb_cur_max = 1;
+  dfa->is_utf8 = 0;
+  dfa->has_mb_node = dfa->nbackref > 0 || has_period;
+}
+#endif
+

+/* Analyze the structure tree, and calculate "first", "next", "edest",
+   "eclosure", and "inveclosure".  */
+
+static reg_errcode_t
+analyze (regex_t *preg)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  reg_errcode_t ret;
+
+  /* Allocate arrays.  */
+  dfa->nexts = re_malloc (Idx, dfa->nodes_alloc);
+  dfa->org_indices = re_malloc (Idx, dfa->nodes_alloc);
+  dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc);
+  dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc);
+  if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL
+	  || dfa->eclosures == NULL, 0))
+    return REG_ESPACE;
+
+  dfa->subexp_map = re_malloc (Idx, preg->re_nsub);
+  if (dfa->subexp_map != NULL)
+    {
+      Idx i;
+      for (i = 0; i < preg->re_nsub; i++)
+	dfa->subexp_map[i] = i;
+      preorder (dfa->str_tree, optimize_subexps, dfa);
+      for (i = 0; i < preg->re_nsub; i++)
+	if (dfa->subexp_map[i] != i)
+	  break;
+      if (i == preg->re_nsub)
+	{
+	  free (dfa->subexp_map);
+	  dfa->subexp_map = NULL;
+	}
+    }
+
+  ret = postorder (dfa->str_tree, lower_subexps, preg);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  ret = postorder (dfa->str_tree, calc_first, dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  preorder (dfa->str_tree, calc_next, dfa);
+  ret = preorder (dfa->str_tree, link_nfa_nodes, dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+  ret = calc_eclosure (dfa);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  /* We only need this during the prune_impossible_nodes pass in regexec.c;
+     skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
+  if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
+      || dfa->nbackref)
+    {
+      dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len);
+      if (BE (dfa->inveclosures == NULL, 0))
+	return REG_ESPACE;
+      ret = calc_inveclosure (dfa);
+    }
+
+  return ret;
+}
+
+/* Our parse trees are very unbalanced, so we cannot use a stack to
+   implement parse tree visits.  Instead, we use parent pointers and
+   some hairy code in these two functions.  */
+static reg_errcode_t
+postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
+	   void *extra)
+{
+  bin_tree_t *node, *prev;
+
+  for (node = root; ; )
+    {
+      /* Descend down the tree, preferably to the left (or to the right
+	 if that's the only child).  */
+      while (node->left || node->right)
+	if (node->left)
+	  node = node->left;
+	else
+	  node = node->right;
+
+      do
+	{
+	  reg_errcode_t err = fn (extra, node);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	  if (node->parent == NULL)
+	    return REG_NOERROR;
+	  prev = node;
+	  node = node->parent;
+	}
+      /* Go up while we have a node that is reached from the right.  */
+      while (node->right == prev || node->right == NULL);
+      node = node->right;
+    }
+}
+
+static reg_errcode_t
+preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)),
+	  void *extra)
+{
+  bin_tree_t *node;
+
+  for (node = root; ; )
+    {
+      reg_errcode_t err = fn (extra, node);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+
+      /* Go to the left node, or up and to the right.  */
+      if (node->left)
+	node = node->left;
+      else
+	{
+	  bin_tree_t *prev = NULL;
+	  while (node->right == prev || node->right == NULL)
+	    {
+	      prev = node;
+	      node = node->parent;
+	      if (!node)
+		return REG_NOERROR;
+	    }
+	  node = node->right;
+	}
+    }
+}
+
+/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell
+   re_search_internal to map the inner one's opr.idx to this one's.  Adjust
+   backreferences as well.  Requires a preorder visit.  */
+static reg_errcode_t
+optimize_subexps (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+
+  if (node->token.type == OP_BACK_REF && dfa->subexp_map)
+    {
+      int idx = node->token.opr.idx;
+      node->token.opr.idx = dfa->subexp_map[idx];
+      dfa->used_bkref_map |= 1 << node->token.opr.idx;
+    }
+
+  else if (node->token.type == SUBEXP
+	   && node->left && node->left->token.type == SUBEXP)
+    {
+      Idx other_idx = node->left->token.opr.idx;
+
+      node->left = node->left->left;
+      if (node->left)
+	node->left->parent = node;
+
+      dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
+      if (other_idx < BITSET_WORD_BITS)
+	dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx);
+    }
+
+  return REG_NOERROR;
+}
+
+/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
+   of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */
+static reg_errcode_t
+lower_subexps (void *extra, bin_tree_t *node)
+{
+  regex_t *preg = (regex_t *) extra;
+  reg_errcode_t err = REG_NOERROR;
+
+  if (node->left && node->left->token.type == SUBEXP)
+    {
+      node->left = lower_subexp (&err, preg, node->left);
+      if (node->left)
+	node->left->parent = node;
+    }
+  if (node->right && node->right->token.type == SUBEXP)
+    {
+      node->right = lower_subexp (&err, preg, node->right);
+      if (node->right)
+	node->right->parent = node;
+    }
+
+  return err;
+}
+
+static bin_tree_t *
+lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *body = node->left;
+  bin_tree_t *op, *cls, *tree1, *tree;
+
+  if (preg->no_sub
+      /* We do not optimize empty subexpressions, because otherwise we may
+	 have bad CONCAT nodes with NULL children.  This is obviously not
+	 very common, so we do not lose much.  An example that triggers
+	 this case is the sed "script" /\(\)/x.  */
+      && node->left != NULL
+      && (node->token.opr.idx >= BITSET_WORD_BITS
+	  || !(dfa->used_bkref_map
+	       & ((bitset_word_t) 1 << node->token.opr.idx))))
+    return node->left;
+
+  /* Convert the SUBEXP node to the concatenation of an
+     OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP.  */
+  op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP);
+  cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP);
+  tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls;
+  tree = create_tree (dfa, op, tree1, CONCAT);
+  if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;
+  op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;
+  return tree;
+}
+
+/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
+   nodes.  Requires a postorder visit.  */
+static reg_errcode_t
+calc_first (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+  if (node->token.type == CONCAT)
+    {
+      node->first = node->left->first;
+      node->node_idx = node->left->node_idx;
+    }
+  else
+    {
+      node->first = node;
+      node->node_idx = re_dfa_add_node (dfa, node->token);
+      if (BE (node->node_idx == REG_MISSING, 0))
+	return REG_ESPACE;
+      if (node->token.type == ANCHOR)
+	dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
+    }
+  return REG_NOERROR;
+}
+
+/* Pass 2: compute NEXT on the tree.  Preorder visit.  */
+static reg_errcode_t
+calc_next (void *extra, bin_tree_t *node)
+{
+  switch (node->token.type)
+    {
+    case OP_DUP_ASTERISK:
+      node->left->next = node;
+      break;
+    case CONCAT:
+      node->left->next = node->right->first;
+      node->right->next = node->next;
+      break;
+    default:
+      if (node->left)
+	node->left->next = node->next;
+      if (node->right)
+	node->right->next = node->next;
+      break;
+    }
+  return REG_NOERROR;
+}
+
+/* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */
+static reg_errcode_t
+link_nfa_nodes (void *extra, bin_tree_t *node)
+{
+  re_dfa_t *dfa = (re_dfa_t *) extra;
+  Idx idx = node->node_idx;
+  reg_errcode_t err = REG_NOERROR;
+
+  switch (node->token.type)
+    {
+    case CONCAT:
+      break;
+
+    case END_OF_RE:
+      assert (node->next == NULL);
+      break;
+
+    case OP_DUP_ASTERISK:
+    case OP_ALT:
+      {
+	Idx left, right;
+	dfa->has_plural_match = 1;
+	if (node->left != NULL)
+	  left = node->left->first->node_idx;
+	else
+	  left = node->next->node_idx;
+	if (node->right != NULL)
+	  right = node->right->first->node_idx;
+	else
+	  right = node->next->node_idx;
+	assert (REG_VALID_INDEX (left));
+	assert (REG_VALID_INDEX (right));
+	err = re_node_set_init_2 (dfa->edests + idx, left, right);
+      }
+      break;
+
+    case ANCHOR:
+    case OP_OPEN_SUBEXP:
+    case OP_CLOSE_SUBEXP:
+      err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx);
+      break;
+
+    case OP_BACK_REF:
+      dfa->nexts[idx] = node->next->node_idx;
+      if (node->token.type == OP_BACK_REF)
+	err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]);
+      break;
+
+    default:
+      assert (!IS_EPSILON_NODE (node->token.type));
+      dfa->nexts[idx] = node->next->node_idx;
+      break;
+    }
+
+  return err;
+}
+
+/* Duplicate the epsilon closure of the node ROOT_NODE.
+   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
+   to their own constraint.  */
+
+static reg_errcode_t
+internal_function
+duplicate_node_closure (re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
+			Idx root_node, unsigned int init_constraint)
+{
+  Idx org_node, clone_node;
+  bool ok;
+  unsigned int constraint = init_constraint;
+  for (org_node = top_org_node, clone_node = top_clone_node;;)
+    {
+      Idx org_dest, clone_dest;
+      if (dfa->nodes[org_node].type == OP_BACK_REF)
+	{
+	  /* If the back reference epsilon-transit, its destination must
+	     also have the constraint.  Then duplicate the epsilon closure
+	     of the destination of the back reference, and store it in
+	     edests of the back reference.  */
+	  org_dest = dfa->nexts[org_node];
+	  re_node_set_empty (dfa->edests + clone_node);
+	  clone_dest = duplicate_node (dfa, org_dest, constraint);
+	  if (BE (clone_dest == REG_MISSING, 0))
+	    return REG_ESPACE;
+	  dfa->nexts[clone_node] = dfa->nexts[org_node];
+	  ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	  if (BE (! ok, 0))
+	    return REG_ESPACE;
+	}
+      else if (dfa->edests[org_node].nelem == 0)
+	{
+	  /* In case of the node can't epsilon-transit, don't duplicate the
+	     destination and store the original destination as the
+	     destination of the node.  */
+	  dfa->nexts[clone_node] = dfa->nexts[org_node];
+	  break;
+	}
+      else if (dfa->edests[org_node].nelem == 1)
+	{
+	  /* In case of the node can epsilon-transit, and it has only one
+	     destination.  */
+	  org_dest = dfa->edests[org_node].elems[0];
+	  re_node_set_empty (dfa->edests + clone_node);
+	  /* If the node is root_node itself, it means the epsilon closure
+	     has a loop.  Then tie it to the destination of the root_node.  */
+	  if (org_node == root_node && clone_node != org_node)
+	    {
+	      ok = re_node_set_insert (dfa->edests + clone_node, org_dest);
+	      if (BE (! ok, 0))
+	        return REG_ESPACE;
+	      break;
+	    }
+	  /* In case the node has another constraint, append it.  */
+	  constraint |= dfa->nodes[org_node].constraint;
+	  clone_dest = duplicate_node (dfa, org_dest, constraint);
+	  if (BE (clone_dest == REG_MISSING, 0))
+	    return REG_ESPACE;
+	  ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	  if (BE (! ok, 0))
+	    return REG_ESPACE;
+	}
+      else /* dfa->edests[org_node].nelem == 2 */
+	{
+	  /* In case of the node can epsilon-transit, and it has two
+	     destinations. In the bin_tree_t and DFA, that's '|' and '*'.   */
+	  org_dest = dfa->edests[org_node].elems[0];
+	  re_node_set_empty (dfa->edests + clone_node);
+	  /* Search for a duplicated node which satisfies the constraint.  */
+	  clone_dest = search_duplicated_node (dfa, org_dest, constraint);
+	  if (clone_dest == REG_MISSING)
+	    {
+	      /* There is no such duplicated node, create a new one.  */
+	      reg_errcode_t err;
+	      clone_dest = duplicate_node (dfa, org_dest, constraint);
+	      if (BE (clone_dest == REG_MISSING, 0))
+		return REG_ESPACE;
+	      ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	      if (BE (! ok, 0))
+		return REG_ESPACE;
+	      err = duplicate_node_closure (dfa, org_dest, clone_dest,
+					    root_node, constraint);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	  else
+	    {
+	      /* There is a duplicated node which satisfies the constraint,
+		 use it to avoid infinite loop.  */
+	      ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	      if (BE (! ok, 0))
+		return REG_ESPACE;
+	    }
+
+	  org_dest = dfa->edests[org_node].elems[1];
+	  clone_dest = duplicate_node (dfa, org_dest, constraint);
+	  if (BE (clone_dest == REG_MISSING, 0))
+	    return REG_ESPACE;
+	  ok = re_node_set_insert (dfa->edests + clone_node, clone_dest);
+	  if (BE (! ok, 0))
+	    return REG_ESPACE;
+	}
+      org_node = org_dest;
+      clone_node = clone_dest;
+    }
+  return REG_NOERROR;
+}
+
+/* Search for a node which is duplicated from the node ORG_NODE, and
+   satisfies the constraint CONSTRAINT.  */
+
+static Idx
+search_duplicated_node (const re_dfa_t *dfa, Idx org_node,
+			unsigned int constraint)
+{
+  Idx idx;
+  for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx)
+    {
+      if (org_node == dfa->org_indices[idx]
+	  && constraint == dfa->nodes[idx].constraint)
+	return idx; /* Found.  */
+    }
+  return REG_MISSING; /* Not found.  */
+}
+
+/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
+   Return the index of the new node, or REG_MISSING if insufficient storage is
+   available.  */
+
+static Idx
+duplicate_node (re_dfa_t *dfa, Idx org_idx, unsigned int constraint)
+{
+  Idx dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]);
+  if (BE (dup_idx != REG_MISSING, 1))
+    {
+      dfa->nodes[dup_idx].constraint = constraint;
+      dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
+      dfa->nodes[dup_idx].duplicated = 1;
+
+      /* Store the index of the original node.  */
+      dfa->org_indices[dup_idx] = org_idx;
+    }
+  return dup_idx;
+}
+
+static reg_errcode_t
+calc_inveclosure (re_dfa_t *dfa)
+{
+  Idx src, idx;
+  bool ok;
+  for (idx = 0; idx < dfa->nodes_len; ++idx)
+    re_node_set_init_empty (dfa->inveclosures + idx);
+
+  for (src = 0; src < dfa->nodes_len; ++src)
+    {
+      Idx *elems = dfa->eclosures[src].elems;
+      for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx)
+	{
+	  ok = re_node_set_insert_last (dfa->inveclosures + elems[idx], src);
+	  if (BE (! ok, 0))
+	    return REG_ESPACE;
+	}
+    }
+
+  return REG_NOERROR;
+}
+
+/* Calculate "eclosure" for all the node in DFA.  */
+
+static reg_errcode_t
+calc_eclosure (re_dfa_t *dfa)
+{
+  Idx node_idx;
+  bool incomplete;
+#ifdef DEBUG
+  assert (dfa->nodes_len > 0);
+#endif
+  incomplete = false;
+  /* For each nodes, calculate epsilon closure.  */
+  for (node_idx = 0; ; ++node_idx)
+    {
+      reg_errcode_t err;
+      re_node_set eclosure_elem;
+      if (node_idx == dfa->nodes_len)
+	{
+	  if (!incomplete)
+	    break;
+	  incomplete = false;
+	  node_idx = 0;
+	}
+
+#ifdef DEBUG
+      assert (dfa->eclosures[node_idx].nelem != REG_MISSING);
+#endif
+
+      /* If we have already calculated, skip it.  */
+      if (dfa->eclosures[node_idx].nelem != 0)
+	continue;
+      /* Calculate epsilon closure of `node_idx'.  */
+      err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, true);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+
+      if (dfa->eclosures[node_idx].nelem == 0)
+	{
+	  incomplete = true;
+	  re_node_set_free (&eclosure_elem);
+	}
+    }
+  return REG_NOERROR;
+}
+
+/* Calculate epsilon closure of NODE.  */
+
+static reg_errcode_t
+calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root)
+{
+  reg_errcode_t err;
+  Idx i;
+  re_node_set eclosure;
+  bool ok;
+  bool incomplete = false;
+  err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  /* This indicates that we are calculating this node now.
+     We reference this value to avoid infinite loop.  */
+  dfa->eclosures[node].nelem = REG_MISSING;
+
+  /* If the current node has constraints, duplicate all nodes
+     since they must inherit the constraints.  */
+  if (dfa->nodes[node].constraint
+      && dfa->edests[node].nelem
+      && !dfa->nodes[dfa->edests[node].elems[0]].duplicated)
+    {
+      err = duplicate_node_closure (dfa, node, node, node,
+				    dfa->nodes[node].constraint);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+
+  /* Expand each epsilon destination nodes.  */
+  if (IS_EPSILON_NODE(dfa->nodes[node].type))
+    for (i = 0; i < dfa->edests[node].nelem; ++i)
+      {
+	re_node_set eclosure_elem;
+	Idx edest = dfa->edests[node].elems[i];
+	/* If calculating the epsilon closure of `edest' is in progress,
+	   return intermediate result.  */
+	if (dfa->eclosures[edest].nelem == REG_MISSING)
+	  {
+	    incomplete = true;
+	    continue;
+	  }
+	/* If we haven't calculated the epsilon closure of `edest' yet,
+	   calculate now. Otherwise use calculated epsilon closure.  */
+	if (dfa->eclosures[edest].nelem == 0)
+	  {
+	    err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
+	    if (BE (err != REG_NOERROR, 0))
+	      return err;
+	  }
+	else
+	  eclosure_elem = dfa->eclosures[edest];
+	/* Merge the epsilon closure of `edest'.  */
+	err = re_node_set_merge (&eclosure, &eclosure_elem);
+	if (BE (err != REG_NOERROR, 0))
+	  return err;
+	/* If the epsilon closure of `edest' is incomplete,
+	   the epsilon closure of this node is also incomplete.  */
+	if (dfa->eclosures[edest].nelem == 0)
+	  {
+	    incomplete = true;
+	    re_node_set_free (&eclosure_elem);
+	  }
+      }
+
+  /* An epsilon closure includes itself.  */
+  ok = re_node_set_insert (&eclosure, node);
+  if (BE (! ok, 0))
+    return REG_ESPACE;
+  if (incomplete && !root)
+    dfa->eclosures[node].nelem = 0;
+  else
+    dfa->eclosures[node] = eclosure;
+  *new_set = eclosure;
+  return REG_NOERROR;
+}
+

+/* Functions for token which are used in the parser.  */
+
+/* Fetch a token from INPUT.
+   We must not use this function inside bracket expressions.  */
+
+static void
+internal_function
+fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax)
+{
+  re_string_skip_bytes (input, peek_token (result, input, syntax));
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function inside bracket expressions.  */
+
+static int
+internal_function
+peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+{
+  unsigned char c;
+
+  if (re_string_eoi (input))
+    {
+      token->type = END_OF_RE;
+      return 0;
+    }
+
+  c = re_string_peek_byte (input, 0);
+  token->opr.c = c;
+
+  token->word_char = 0;
+#ifdef RE_ENABLE_I18N
+  token->mb_partial = 0;
+  if (input->mb_cur_max > 1 &&
+      !re_string_first_byte (input, re_string_cur_idx (input)))
+    {
+      token->type = CHARACTER;
+      token->mb_partial = 1;
+      return 1;
+    }
+#endif
+  if (c == '\\')
+    {
+      unsigned char c2;
+      if (re_string_cur_idx (input) + 1 >= re_string_length (input))
+	{
+	  token->type = BACK_SLASH;
+	  return 1;
+	}
+
+      c2 = re_string_peek_byte_case (input, 1);
+      token->opr.c = c2;
+      token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+      if (input->mb_cur_max > 1)
+	{
+	  wint_t wc = re_string_wchar_at (input,
+					  re_string_cur_idx (input) + 1);
+	  token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+	}
+      else
+#endif
+	token->word_char = IS_WORD_CHAR (c2) != 0;
+
+      switch (c2)
+	{
+	case '|':
+	  if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
+	    token->type = OP_ALT;
+	  break;
+	case '1': case '2': case '3': case '4': case '5':
+	case '6': case '7': case '8': case '9':
+	  if (!(syntax & RE_NO_BK_REFS))
+	    {
+	      token->type = OP_BACK_REF;
+	      token->opr.idx = c2 - '1';
+	    }
+	  break;
+	case '<':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = WORD_FIRST;
+	    }
+	  break;
+	case '>':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = WORD_LAST;
+	    }
+	  break;
+	case 'b':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = WORD_DELIM;
+	    }
+	  break;
+	case 'B':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = NOT_WORD_DELIM;
+	    }
+	  break;
+	case 'w':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_WORD;
+	  break;
+	case 'W':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_NOTWORD;
+	  break;
+	case 's':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_SPACE;
+	  break;
+	case 'S':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    token->type = OP_NOTSPACE;
+	  break;
+	case '`':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = BUF_FIRST;
+	    }
+	  break;
+	case '\'':
+	  if (!(syntax & RE_NO_GNU_OPS))
+	    {
+	      token->type = ANCHOR;
+	      token->opr.ctx_type = BUF_LAST;
+	    }
+	  break;
+	case '(':
+	  if (!(syntax & RE_NO_BK_PARENS))
+	    token->type = OP_OPEN_SUBEXP;
+	  break;
+	case ')':
+	  if (!(syntax & RE_NO_BK_PARENS))
+	    token->type = OP_CLOSE_SUBEXP;
+	  break;
+	case '+':
+	  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+	    token->type = OP_DUP_PLUS;
+	  break;
+	case '?':
+	  if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+	    token->type = OP_DUP_QUESTION;
+	  break;
+	case '{':
+	  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+	    token->type = OP_OPEN_DUP_NUM;
+	  break;
+	case '}':
+	  if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+	    token->type = OP_CLOSE_DUP_NUM;
+	  break;
+	default:
+	  break;
+	}
+      return 2;
+    }
+
+  token->type = CHARACTER;
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1)
+    {
+      wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input));
+      token->word_char = IS_WIDE_WORD_CHAR (wc) != 0;
+    }
+  else
+#endif
+    token->word_char = IS_WORD_CHAR (token->opr.c);
+
+  switch (c)
+    {
+    case '\n':
+      if (syntax & RE_NEWLINE_ALT)
+	token->type = OP_ALT;
+      break;
+    case '|':
+      if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
+	token->type = OP_ALT;
+      break;
+    case '*':
+      token->type = OP_DUP_ASTERISK;
+      break;
+    case '+':
+      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+	token->type = OP_DUP_PLUS;
+      break;
+    case '?':
+      if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+	token->type = OP_DUP_QUESTION;
+      break;
+    case '{':
+      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+	token->type = OP_OPEN_DUP_NUM;
+      break;
+    case '}':
+      if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+	token->type = OP_CLOSE_DUP_NUM;
+      break;
+    case '(':
+      if (syntax & RE_NO_BK_PARENS)
+	token->type = OP_OPEN_SUBEXP;
+      break;
+    case ')':
+      if (syntax & RE_NO_BK_PARENS)
+	token->type = OP_CLOSE_SUBEXP;
+      break;
+    case '[':
+      token->type = OP_OPEN_BRACKET;
+      break;
+    case '.':
+      token->type = OP_PERIOD;
+      break;
+    case '^':
+      if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&
+	  re_string_cur_idx (input) != 0)
+	{
+	  char prev = re_string_peek_byte (input, -1);
+	  if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')
+	    break;
+	}
+      token->type = ANCHOR;
+      token->opr.ctx_type = LINE_FIRST;
+      break;
+    case '$':
+      if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
+	  re_string_cur_idx (input) + 1 != re_string_length (input))
+	{
+	  re_token_t next;
+	  re_string_skip_bytes (input, 1);
+	  peek_token (&next, input, syntax);
+	  re_string_skip_bytes (input, -1);
+	  if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
+	    break;
+	}
+      token->type = ANCHOR;
+      token->opr.ctx_type = LINE_LAST;
+      break;
+    default:
+      break;
+    }
+  return 1;
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function out of bracket expressions.  */
+
+static int
+internal_function
+peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax)
+{
+  unsigned char c;
+  if (re_string_eoi (input))
+    {
+      token->type = END_OF_RE;
+      return 0;
+    }
+  c = re_string_peek_byte (input, 0);
+  token->opr.c = c;
+
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1 &&
+      !re_string_first_byte (input, re_string_cur_idx (input)))
+    {
+      token->type = CHARACTER;
+      return 1;
+    }
+#endif /* RE_ENABLE_I18N */
+
+  if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
+      && re_string_cur_idx (input) + 1 < re_string_length (input))
+    {
+      /* In this case, '\' escape a character.  */
+      unsigned char c2;
+      re_string_skip_bytes (input, 1);
+      c2 = re_string_peek_byte (input, 0);
+      token->opr.c = c2;
+      token->type = CHARACTER;
+      return 1;
+    }
+  if (c == '[') /* '[' is a special char in a bracket exps.  */
+    {
+      unsigned char c2;
+      int token_len;
+      if (re_string_cur_idx (input) + 1 < re_string_length (input))
+	c2 = re_string_peek_byte (input, 1);
+      else
+	c2 = 0;
+      token->opr.c = c2;
+      token_len = 2;
+      switch (c2)
+	{
+	case '.':
+	  token->type = OP_OPEN_COLL_ELEM;
+	  break;
+	case '=':
+	  token->type = OP_OPEN_EQUIV_CLASS;
+	  break;
+	case ':':
+	  if (syntax & RE_CHAR_CLASSES)
+	    {
+	      token->type = OP_OPEN_CHAR_CLASS;
+	      break;
+	    }
+	  /* else fall through.  */
+	default:
+	  token->type = CHARACTER;
+	  token->opr.c = c;
+	  token_len = 1;
+	  break;
+	}
+      return token_len;
+    }
+  switch (c)
+    {
+    case '-':
+      token->type = OP_CHARSET_RANGE;
+      break;
+    case ']':
+      token->type = OP_CLOSE_BRACKET;
+      break;
+    case '^':
+      token->type = OP_NON_MATCH_LIST;
+      break;
+    default:
+      token->type = CHARACTER;
+    }
+  return 1;
+}
+

+/* Functions for parser.  */
+
+/* Entry point of the parser.
+   Parse the regular expression REGEXP and return the structure tree.
+   If an error is occured, ERR is set by error code, and return NULL.
+   This function build the following tree, from regular expression <reg_exp>:
+	   CAT
+	   / \
+	  /   \
+   <reg_exp>  EOR
+
+   CAT means concatenation.
+   EOR means end of regular expression.  */
+
+static bin_tree_t *
+parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,
+       reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree, *eor, *root;
+  re_token_t current_token;
+  dfa->syntax = syntax;
+  fetch_token (&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+  tree = parse_reg_exp (regexp, preg, &current_token, syntax, 0, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+  eor = create_tree (dfa, NULL, NULL, END_OF_RE);
+  if (tree != NULL)
+    root = create_tree (dfa, tree, eor, CONCAT);
+  else
+    root = eor;
+  if (BE (eor == NULL || root == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+  return root;
+}
+
+/* This function build the following tree, from regular expression
+   <branch1>|<branch2>:
+	   ALT
+	   / \
+	  /   \
+   <branch1> <branch2>
+
+   ALT means alternative, which represents the operator `|'.  */
+
+static bin_tree_t *
+parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
+	       reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree, *branch = NULL;
+  tree = parse_branch (regexp, preg, token, syntax, nest, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+
+  while (token->type == OP_ALT)
+    {
+      fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+      if (token->type != OP_ALT && token->type != END_OF_RE
+	  && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+	{
+	  branch = parse_branch (regexp, preg, token, syntax, nest, err);
+	  if (BE (*err != REG_NOERROR && branch == NULL, 0))
+	    return NULL;
+	}
+      else
+	branch = NULL;
+      tree = create_tree (dfa, tree, branch, OP_ALT);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+    }
+  return tree;
+}
+
+/* This function build the following tree, from regular expression
+   <exp1><exp2>:
+	CAT
+	/ \
+       /   \
+   <exp1> <exp2>
+
+   CAT means concatenation.  */
+
+static bin_tree_t *
+parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token,
+	      reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  bin_tree_t *tree, *expr;
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  tree = parse_expression (regexp, preg, token, syntax, nest, err);
+  if (BE (*err != REG_NOERROR && tree == NULL, 0))
+    return NULL;
+
+  while (token->type != OP_ALT && token->type != END_OF_RE
+	 && (nest == 0 || token->type != OP_CLOSE_SUBEXP))
+    {
+      expr = parse_expression (regexp, preg, token, syntax, nest, err);
+      if (BE (*err != REG_NOERROR && expr == NULL, 0))
+	{
+	  return NULL;
+	}
+      if (tree != NULL && expr != NULL)
+	{
+	  tree = create_tree (dfa, tree, expr, CONCAT);
+	  if (tree == NULL)
+	    {
+	      *err = REG_ESPACE;
+	      return NULL;
+	    }
+	}
+      else if (tree == NULL)
+	tree = expr;
+      /* Otherwise expr == NULL, we don't need to create new tree.  */
+    }
+  return tree;
+}
+
+/* This function build the following tree, from regular expression a*:
+	 *
+	 |
+	 a
+*/
+
+static bin_tree_t *
+parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token,
+		  reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree;
+  switch (token->type)
+    {
+    case CHARACTER:
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+	{
+	  while (!re_string_eoi (regexp)
+		 && !re_string_first_byte (regexp, re_string_cur_idx (regexp)))
+	    {
+	      bin_tree_t *mbc_remain;
+	      fetch_token (token, regexp, syntax);
+	      mbc_remain = create_token_tree (dfa, NULL, NULL, token);
+	      tree = create_tree (dfa, tree, mbc_remain, CONCAT);
+	      if (BE (mbc_remain == NULL || tree == NULL, 0))
+		{
+		  *err = REG_ESPACE;
+		  return NULL;
+		}
+	    }
+	}
+#endif
+      break;
+    case OP_OPEN_SUBEXP:
+      tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_OPEN_BRACKET:
+      tree = parse_bracket_exp (regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_BACK_REF:
+      if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1))
+	{
+	  *err = REG_ESUBREG;
+	  return NULL;
+	}
+      dfa->used_bkref_map |= 1 << token->opr.idx;
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+      ++dfa->nbackref;
+      dfa->has_mb_node = 1;
+      break;
+    case OP_OPEN_DUP_NUM:
+      if (syntax & RE_CONTEXT_INVALID_DUP)
+	{
+	  *err = REG_BADRPT;
+	  return NULL;
+	}
+      /* FALLTHROUGH */
+    case OP_DUP_ASTERISK:
+    case OP_DUP_PLUS:
+    case OP_DUP_QUESTION:
+      if (syntax & RE_CONTEXT_INVALID_OPS)
+	{
+	  *err = REG_BADRPT;
+	  return NULL;
+	}
+      else if (syntax & RE_CONTEXT_INDEP_OPS)
+	{
+	  fetch_token (token, regexp, syntax);
+	  return parse_expression (regexp, preg, token, syntax, nest, err);
+	}
+      /* else fall through  */
+    case OP_CLOSE_SUBEXP:
+      if ((token->type == OP_CLOSE_SUBEXP) &&
+	  !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD))
+	{
+	  *err = REG_ERPAREN;
+	  return NULL;
+	}
+      /* else fall through  */
+    case OP_CLOSE_DUP_NUM:
+      /* We treat it as a normal character.  */
+
+      /* Then we can these characters as normal characters.  */
+      token->type = CHARACTER;
+      /* mb_partial and word_char bits should be initialized already
+	 by peek_token.  */
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+      break;
+    case ANCHOR:
+      if ((token->opr.ctx_type
+	   & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))
+	  && dfa->word_ops_used == 0)
+	init_word_char (dfa);
+      if (token->opr.ctx_type == WORD_DELIM
+	  || token->opr.ctx_type == NOT_WORD_DELIM)
+	{
+	  bin_tree_t *tree_first, *tree_last;
+	  if (token->opr.ctx_type == WORD_DELIM)
+	    {
+	      token->opr.ctx_type = WORD_FIRST;
+	      tree_first = create_token_tree (dfa, NULL, NULL, token);
+	      token->opr.ctx_type = WORD_LAST;
+	    }
+	  else
+	    {
+	      token->opr.ctx_type = INSIDE_WORD;
+	      tree_first = create_token_tree (dfa, NULL, NULL, token);
+	      token->opr.ctx_type = INSIDE_NOTWORD;
+	    }
+	  tree_last = create_token_tree (dfa, NULL, NULL, token);
+	  tree = create_tree (dfa, tree_first, tree_last, OP_ALT);
+	  if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0))
+	    {
+	      *err = REG_ESPACE;
+	      return NULL;
+	    }
+	}
+      else
+	{
+	  tree = create_token_tree (dfa, NULL, NULL, token);
+	  if (BE (tree == NULL, 0))
+	    {
+	      *err = REG_ESPACE;
+	      return NULL;
+	    }
+	}
+      /* We must return here, since ANCHORs can't be followed
+	 by repetition operators.
+	 eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
+	     it must not be "<ANCHOR(^)><REPEAT(*)>".  */
+      fetch_token (token, regexp, syntax);
+      return tree;
+    case OP_PERIOD:
+      tree = create_token_tree (dfa, NULL, NULL, token);
+      if (BE (tree == NULL, 0))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+      if (dfa->mb_cur_max > 1)
+	dfa->has_mb_node = 1;
+      break;
+    case OP_WORD:
+    case OP_NOTWORD:
+      tree = build_charclass_op (dfa, regexp->trans,
+				 (const unsigned char *) "alnum",
+				 (const unsigned char *) "_",
+				 token->type == OP_NOTWORD, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_SPACE:
+    case OP_NOTSPACE:
+      tree = build_charclass_op (dfa, regexp->trans,
+				 (const unsigned char *) "space",
+				 (const unsigned char *) "",
+				 token->type == OP_NOTSPACE, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      break;
+    case OP_ALT:
+    case END_OF_RE:
+      return NULL;
+    case BACK_SLASH:
+      *err = REG_EESCAPE;
+      return NULL;
+    default:
+      /* Must not happen?  */
+#ifdef DEBUG
+      assert (0);
+#endif
+      return NULL;
+    }
+  fetch_token (token, regexp, syntax);
+
+  while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
+	 || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM)
+    {
+      tree = parse_dup_op (tree, regexp, dfa, token, syntax, err);
+      if (BE (*err != REG_NOERROR && tree == NULL, 0))
+	return NULL;
+      /* In BRE consecutive duplications are not allowed.  */
+      if ((syntax & RE_CONTEXT_INVALID_DUP)
+	  && (token->type == OP_DUP_ASTERISK
+	      || token->type == OP_OPEN_DUP_NUM))
+	{
+	  *err = REG_BADRPT;
+	  return NULL;
+	}
+    }
+
+  return tree;
+}
+
+/* This function build the following tree, from regular expression
+   (<reg_exp>):
+	 SUBEXP
+	    |
+	<reg_exp>
+*/
+
+static bin_tree_t *
+parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token,
+	       reg_syntax_t syntax, Idx nest, reg_errcode_t *err)
+{
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+  bin_tree_t *tree;
+  size_t cur_nsub;
+  cur_nsub = preg->re_nsub++;
+
+  fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+
+  /* The subexpression may be a null string.  */
+  if (token->type == OP_CLOSE_SUBEXP)
+    tree = NULL;
+  else
+    {
+      tree = parse_reg_exp (regexp, preg, token, syntax, nest, err);
+      if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0))
+	*err = REG_EPAREN;
+      if (BE (*err != REG_NOERROR, 0))
+	return NULL;
+    }
+
+  if (cur_nsub <= '9' - '1')
+    dfa->completed_bkref_map |= 1 << cur_nsub;
+
+  tree = create_tree (dfa, tree, NULL, SUBEXP);
+  if (BE (tree == NULL, 0))
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+  tree->token.opr.idx = cur_nsub;
+  return tree;
+}
+
+/* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
+
+static bin_tree_t *
+parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
+	      re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err)
+{
+  bin_tree_t *tree = NULL, *old_tree = NULL;
+  Idx i, start, end, start_idx = re_string_cur_idx (regexp);
+  re_token_t start_token = *token;
+
+  if (token->type == OP_OPEN_DUP_NUM)
+    {
+      end = 0;
+      start = fetch_number (regexp, token, syntax);
+      if (start == REG_MISSING)
+	{
+	  if (token->type == CHARACTER && token->opr.c == ',')
+	    start = 0; /* We treat "{,m}" as "{0,m}".  */
+	  else
+	    {
+	      *err = REG_BADBR; /* <re>{} is invalid.  */
+	      return NULL;
+	    }
+	}
+      if (BE (start != REG_ERROR, 1))
+	{
+	  /* We treat "{n}" as "{n,n}".  */
+	  end = ((token->type == OP_CLOSE_DUP_NUM) ? start
+		 : ((token->type == CHARACTER && token->opr.c == ',')
+		    ? fetch_number (regexp, token, syntax) : REG_ERROR));
+	}
+      if (BE (start == REG_ERROR || end == REG_ERROR, 0))
+	{
+	  /* Invalid sequence.  */
+	  if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0))
+	    {
+	      if (token->type == END_OF_RE)
+		*err = REG_EBRACE;
+	      else
+		*err = REG_BADBR;
+
+	      return NULL;
+	    }
+
+	  /* If the syntax bit is set, rollback.  */
+	  re_string_set_index (regexp, start_idx);
+	  *token = start_token;
+	  token->type = CHARACTER;
+	  /* mb_partial and word_char bits should be already initialized by
+	     peek_token.  */
+	  return elem;
+	}
+
+      if (BE ((end != REG_MISSING && start > end)
+	      || token->type != OP_CLOSE_DUP_NUM, 0))
+	{
+	  /* First number greater than second.  */
+	  *err = REG_BADBR;
+	  return NULL;
+	}
+    }
+  else
+    {
+      start = (token->type == OP_DUP_PLUS) ? 1 : 0;
+      end = (token->type == OP_DUP_QUESTION) ? 1 : REG_MISSING;
+    }
+
+  fetch_token (token, regexp, syntax);
+
+  if (BE (elem == NULL, 0))
+    return NULL;
+  if (BE (start == 0 && end == 0, 0))
+    {
+      postorder (elem, free_tree, NULL);
+      return NULL;
+    }
+
+  /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
+  if (BE (start > 0, 0))
+    {
+      tree = elem;
+      for (i = 2; i <= start; ++i)
+	{
+	  elem = duplicate_tree (elem, dfa);
+	  tree = create_tree (dfa, tree, elem, CONCAT);
+	  if (BE (elem == NULL || tree == NULL, 0))
+	    goto parse_dup_op_espace;
+	}
+
+      if (start == end)
+	return tree;
+
+      /* Duplicate ELEM before it is marked optional.  */
+      elem = duplicate_tree (elem, dfa);
+      old_tree = tree;
+    }
+  else
+    old_tree = NULL;
+
+  if (elem->token.type == SUBEXP)
+    postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx);
+
+  tree = create_tree (dfa, elem, NULL,
+		      (end == REG_MISSING ? OP_DUP_ASTERISK : OP_ALT));
+  if (BE (tree == NULL, 0))
+    goto parse_dup_op_espace;
+
+/* From gnulib's "intprops.h":
+   True if the arithmetic type T is signed.  */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+  /* This loop is actually executed only when end != REG_MISSING,
+     to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have
+     already created the start+1-th copy.  */
+  if (TYPE_SIGNED (Idx) || end != REG_MISSING)
+    for (i = start + 2; i <= end; ++i)
+      {
+	elem = duplicate_tree (elem, dfa);
+	tree = create_tree (dfa, tree, elem, CONCAT);
+	if (BE (elem == NULL || tree == NULL, 0))
+	  goto parse_dup_op_espace;
+
+	tree = create_tree (dfa, tree, NULL, OP_ALT);
+	if (BE (tree == NULL, 0))
+	  goto parse_dup_op_espace;
+      }
+
+  if (old_tree)
+    tree = create_tree (dfa, old_tree, tree, CONCAT);
+
+  return tree;
+
+ parse_dup_op_espace:
+  *err = REG_ESPACE;
+  return NULL;
+}
+
+/* Size of the names for collating symbol/equivalence_class/character_class.
+   I'm not sure, but maybe enough.  */
+#define BRACKET_NAME_BUF_SIZE 32
+
+#ifndef _LIBC
+  /* Local function for parse_bracket_exp only used in case of NOT _LIBC.
+     Build the range expression which starts from START_ELEM, and ends
+     at END_ELEM.  The result are written to MBCSET and SBCSET.
+     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+     mbcset->range_ends, is a pointer argument sinse we may
+     update it.  */
+
+static reg_errcode_t
+internal_function
+# ifdef RE_ENABLE_I18N
+build_range_exp (const reg_syntax_t syntax,
+                 bitset_t sbcset,
+                 re_charset_t *mbcset,
+                 Idx *range_alloc,
+                 const bracket_elem_t *start_elem,
+                 const bracket_elem_t *end_elem)
+# else /* not RE_ENABLE_I18N */
+build_range_exp (const reg_syntax_t syntax,
+                 bitset_t sbcset,
+                 const bracket_elem_t *start_elem,
+                 const bracket_elem_t *end_elem)
+# endif /* not RE_ENABLE_I18N */
+{
+  unsigned int start_ch, end_ch;
+  /* Equivalence Classes and Character Classes can't be a range start/end.  */
+  if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+	  || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+	  0))
+    return REG_ERANGE;
+
+  /* We can handle no multi character collating elements without libc
+     support.  */
+  if (BE ((start_elem->type == COLL_SYM
+	   && strlen ((char *) start_elem->opr.name) > 1)
+	  || (end_elem->type == COLL_SYM
+	      && strlen ((char *) end_elem->opr.name) > 1), 0))
+    return REG_ECOLLATE;
+
+# ifdef RE_ENABLE_I18N
+  {
+    wchar_t wc;
+    wint_t start_wc;
+    wint_t end_wc;
+    wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+
+    start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
+		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+		   : 0));
+    end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
+	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+		 : 0));
+    start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM)
+		? __btowc (start_ch) : start_elem->opr.wch);
+    end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM)
+	      ? __btowc (end_ch) : end_elem->opr.wch);
+    if (start_wc == WEOF || end_wc == WEOF)
+      return REG_ECOLLATE;
+    cmp_buf[0] = start_wc;
+    cmp_buf[4] = end_wc;
+
+    if (BE ((syntax & RE_NO_EMPTY_RANGES)
+            && wcscoll (cmp_buf, cmp_buf + 4) > 0, 0))
+      return REG_ERANGE;
+
+    /* Got valid collation sequence values, add them as a new entry.
+       However, for !_LIBC we have no collation elements: if the
+       character set is single byte, the single byte character set
+       that we build below suffices.  parse_bracket_exp passes
+       no MBCSET if dfa->mb_cur_max == 1.  */
+    if (mbcset)
+      {
+	/* Check the space of the arrays.  */
+	if (BE (*range_alloc == mbcset->nranges, 0))
+	  {
+	    /* There is not enough space, need realloc.  */
+	    wchar_t *new_array_start, *new_array_end;
+	    Idx new_nranges;
+
+	    /* +1 in case of mbcset->nranges is 0.  */
+	    new_nranges = 2 * mbcset->nranges + 1;
+	    /* Use realloc since mbcset->range_starts and mbcset->range_ends
+	       are NULL if *range_alloc == 0.  */
+	    new_array_start = re_realloc (mbcset->range_starts, wchar_t,
+					  new_nranges);
+	    new_array_end = re_realloc (mbcset->range_ends, wchar_t,
+					new_nranges);
+
+	    if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+	      return REG_ESPACE;
+
+	    mbcset->range_starts = new_array_start;
+	    mbcset->range_ends = new_array_end;
+	    *range_alloc = new_nranges;
+	  }
+
+	mbcset->range_starts[mbcset->nranges] = start_wc;
+	mbcset->range_ends[mbcset->nranges++] = end_wc;
+      }
+
+    /* Build the table for single byte characters.  */
+    for (wc = 0; wc < SBC_MAX; ++wc)
+      {
+	cmp_buf[2] = wc;
+	if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+	    && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+	  bitset_set (sbcset, wc);
+      }
+  }
+# else /* not RE_ENABLE_I18N */
+  {
+    unsigned int ch;
+    start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch
+		: ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+		   : 0));
+    end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch
+	      : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+		 : 0));
+    if (start_ch > end_ch)
+      return REG_ERANGE;
+    /* Build the table for single byte characters.  */
+    for (ch = 0; ch < SBC_MAX; ++ch)
+      if (start_ch <= ch  && ch <= end_ch)
+	bitset_set (sbcset, ch);
+  }
+# endif /* not RE_ENABLE_I18N */
+  return REG_NOERROR;
+}
+#endif /* not _LIBC */
+
+#ifndef _LIBC
+/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+   Build the collating element which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+   pointer argument since we may update it.  */
+
+static reg_errcode_t
+internal_function
+build_collating_symbol (bitset_t sbcset,
+# ifdef RE_ENABLE_I18N
+			re_charset_t *mbcset, Idx *coll_sym_alloc,
+# endif
+			const unsigned char *name)
+{
+  size_t name_len = strlen ((const char *) name);
+  if (BE (name_len != 1, 0))
+    return REG_ECOLLATE;
+  else
+    {
+      bitset_set (sbcset, name[0]);
+      return REG_NOERROR;
+    }
+}
+#endif /* not _LIBC */
+
+/* This function parse bracket expression like "[abc]", "[a-c]",
+   "[[.a-a.]]" etc.  */
+
+static bin_tree_t *
+parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+		   reg_syntax_t syntax, reg_errcode_t *err)
+{
+#ifdef _LIBC
+  const unsigned char *collseqmb;
+  const char *collseqwc;
+  uint32_t nrules;
+  int32_t table_size;
+  const int32_t *symb_table;
+  const unsigned char *extra;
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Seek the collating symbol entry correspondings to NAME.
+     Return the index of the symbol in the SYMB_TABLE.  */
+
+  auto inline int32_t
+  __attribute ((always_inline))
+  seek_collating_symbol_entry (name, name_len)
+	 const unsigned char *name;
+	 size_t name_len;
+    {
+      int32_t hash = elem_hash ((const char *) name, name_len);
+      int32_t elem = hash % table_size;
+      if (symb_table[2 * elem] != 0)
+	{
+	  int32_t second = hash % (table_size - 2) + 1;
+
+	  do
+	    {
+	      /* First compare the hashing value.  */
+	      if (symb_table[2 * elem] == hash
+		  /* Compare the length of the name.  */
+		  && name_len == extra[symb_table[2 * elem + 1]]
+		  /* Compare the name.  */
+		  && memcmp (name, &extra[symb_table[2 * elem + 1] + 1],
+			     name_len) == 0)
+		{
+		  /* Yep, this is the entry.  */
+		  break;
+		}
+
+	      /* Next entry.  */
+	      elem += second;
+	    }
+	  while (symb_table[2 * elem] != 0);
+	}
+      return elem;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environment.
+     Look up the collation sequence value of BR_ELEM.
+     Return the value if succeeded, UINT_MAX otherwise.  */
+
+  auto inline unsigned int
+  __attribute ((always_inline))
+  lookup_collation_sequence_value (br_elem)
+	 bracket_elem_t *br_elem;
+    {
+      if (br_elem->type == SB_CHAR)
+	{
+	  /*
+	  if (MB_CUR_MAX == 1)
+	  */
+	  if (nrules == 0)
+	    return collseqmb[br_elem->opr.ch];
+	  else
+	    {
+	      wint_t wc = __btowc (br_elem->opr.ch);
+	      return __collseq_table_lookup (collseqwc, wc);
+	    }
+	}
+      else if (br_elem->type == MB_CHAR)
+	{
+	  if (nrules != 0)
+	    return __collseq_table_lookup (collseqwc, br_elem->opr.wch);
+	}
+      else if (br_elem->type == COLL_SYM)
+	{
+	  size_t sym_name_len = strlen ((char *) br_elem->opr.name);
+	  if (nrules != 0)
+	    {
+	      int32_t elem, idx;
+	      elem = seek_collating_symbol_entry (br_elem->opr.name,
+						  sym_name_len);
+	      if (symb_table[2 * elem] != 0)
+		{
+		  /* We found the entry.  */
+		  idx = symb_table[2 * elem + 1];
+		  /* Skip the name of collating element name.  */
+		  idx += 1 + extra[idx];
+		  /* Skip the byte sequence of the collating element.  */
+		  idx += 1 + extra[idx];
+		  /* Adjust for the alignment.  */
+		  idx = (idx + 3) & ~3;
+		  /* Skip the multibyte collation sequence value.  */
+		  idx += sizeof (unsigned int);
+		  /* Skip the wide char sequence of the collating element.  */
+		  idx += sizeof (unsigned int) *
+		    (1 + *(unsigned int *) (extra + idx));
+		  /* Return the collation sequence value.  */
+		  return *(unsigned int *) (extra + idx);
+		}
+	      else if (symb_table[2 * elem] == 0 && sym_name_len == 1)
+		{
+		  /* No valid character.  Match it as a single byte
+		     character.  */
+		  return collseqmb[br_elem->opr.name[0]];
+		}
+	    }
+	  else if (sym_name_len == 1)
+	    return collseqmb[br_elem->opr.name[0]];
+	}
+      return UINT_MAX;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Build the range expression which starts from START_ELEM, and ends
+     at END_ELEM.  The result are written to MBCSET and SBCSET.
+     RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+     mbcset->range_ends, is a pointer argument sinse we may
+     update it.  */
+
+  auto inline reg_errcode_t
+  __attribute ((always_inline))
+  build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem)
+	 re_charset_t *mbcset;
+	 Idx *range_alloc;
+	 bitset_t sbcset;
+	 bracket_elem_t *start_elem, *end_elem;
+    {
+      unsigned int ch;
+      uint32_t start_collseq;
+      uint32_t end_collseq;
+
+      /* Equivalence Classes and Character Classes can't be a range
+	 start/end.  */
+      if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS
+	      || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS,
+	      0))
+	return REG_ERANGE;
+
+      start_collseq = lookup_collation_sequence_value (start_elem);
+      end_collseq = lookup_collation_sequence_value (end_elem);
+      /* Check start/end collation sequence values.  */
+      if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0))
+	return REG_ECOLLATE;
+      if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0))
+	return REG_ERANGE;
+
+      /* Got valid collation sequence values, add them as a new entry.
+	 However, if we have no collation elements, and the character set
+	 is single byte, the single byte character set that we
+	 build below suffices. */
+      if (nrules > 0 || dfa->mb_cur_max > 1)
+	{
+	  /* Check the space of the arrays.  */
+	  if (BE (*range_alloc == mbcset->nranges, 0))
+	    {
+	      /* There is not enough space, need realloc.  */
+	      uint32_t *new_array_start;
+	      uint32_t *new_array_end;
+	      Idx new_nranges;
+
+	      /* +1 in case of mbcset->nranges is 0.  */
+	      new_nranges = 2 * mbcset->nranges + 1;
+	      new_array_start = re_realloc (mbcset->range_starts, uint32_t,
+					    new_nranges);
+	      new_array_end = re_realloc (mbcset->range_ends, uint32_t,
+					  new_nranges);
+
+	      if (BE (new_array_start == NULL || new_array_end == NULL, 0))
+		return REG_ESPACE;
+
+	      mbcset->range_starts = new_array_start;
+	      mbcset->range_ends = new_array_end;
+	      *range_alloc = new_nranges;
+	    }
+
+	  mbcset->range_starts[mbcset->nranges] = start_collseq;
+	  mbcset->range_ends[mbcset->nranges++] = end_collseq;
+	}
+
+      /* Build the table for single byte characters.  */
+      for (ch = 0; ch < SBC_MAX; ch++)
+	{
+	  uint32_t ch_collseq;
+	  /*
+	  if (MB_CUR_MAX == 1)
+	  */
+	  if (nrules == 0)
+	    ch_collseq = collseqmb[ch];
+	  else
+	    ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch));
+	  if (start_collseq <= ch_collseq && ch_collseq <= end_collseq)
+	    bitset_set (sbcset, ch);
+	}
+      return REG_NOERROR;
+    }
+
+  /* Local function for parse_bracket_exp used in _LIBC environement.
+     Build the collating element which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+     pointer argument sinse we may update it.  */
+
+  auto inline reg_errcode_t
+  __attribute ((always_inline))
+  build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name)
+	 re_charset_t *mbcset;
+	 Idx *coll_sym_alloc;
+	 bitset_t sbcset;
+	 const unsigned char *name;
+    {
+      int32_t elem, idx;
+      size_t name_len = strlen ((const char *) name);
+      if (nrules != 0)
+	{
+	  elem = seek_collating_symbol_entry (name, name_len);
+	  if (symb_table[2 * elem] != 0)
+	    {
+	      /* We found the entry.  */
+	      idx = symb_table[2 * elem + 1];
+	      /* Skip the name of collating element name.  */
+	      idx += 1 + extra[idx];
+	    }
+	  else if (symb_table[2 * elem] == 0 && name_len == 1)
+	    {
+	      /* No valid character, treat it as a normal
+		 character.  */
+	      bitset_set (sbcset, name[0]);
+	      return REG_NOERROR;
+	    }
+	  else
+	    return REG_ECOLLATE;
+
+	  /* Got valid collation sequence, add it as a new entry.  */
+	  /* Check the space of the arrays.  */
+	  if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0))
+	    {
+	      /* Not enough, realloc it.  */
+	      /* +1 in case of mbcset->ncoll_syms is 0.  */
+	      Idx new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1;
+	      /* Use realloc since mbcset->coll_syms is NULL
+		 if *alloc == 0.  */
+	      int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t,
+						   new_coll_sym_alloc);
+	      if (BE (new_coll_syms == NULL, 0))
+		return REG_ESPACE;
+	      mbcset->coll_syms = new_coll_syms;
+	      *coll_sym_alloc = new_coll_sym_alloc;
+	    }
+	  mbcset->coll_syms[mbcset->ncoll_syms++] = idx;
+	  return REG_NOERROR;
+	}
+      else
+	{
+	  if (BE (name_len != 1, 0))
+	    return REG_ECOLLATE;
+	  else
+	    {
+	      bitset_set (sbcset, name[0]);
+	      return REG_NOERROR;
+	    }
+	}
+    }
+#endif
+
+  re_token_t br_token;
+  re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+  re_charset_t *mbcset;
+  Idx coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0;
+  Idx equiv_class_alloc = 0, char_class_alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+  bool non_match = false;
+  bin_tree_t *work_tree;
+  int token_len;
+  bool first_round = true;
+#ifdef _LIBC
+  collseqmb = (const unsigned char *)
+    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+  nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules)
+    {
+      /*
+      if (MB_CUR_MAX > 1)
+      */
+      collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+      table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB);
+      symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+						  _NL_COLLATE_SYMB_TABLEMB);
+      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+						   _NL_COLLATE_SYMB_EXTRAMB);
+    }
+#endif
+  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+#ifdef RE_ENABLE_I18N
+  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+#ifdef RE_ENABLE_I18N
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else
+  if (BE (sbcset == NULL, 0))
+#endif /* RE_ENABLE_I18N */
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  token_len = peek_token_bracket (token, regexp, syntax);
+  if (BE (token->type == END_OF_RE, 0))
+    {
+      *err = REG_BADPAT;
+      goto parse_bracket_exp_free_return;
+    }
+  if (token->type == OP_NON_MATCH_LIST)
+    {
+#ifdef RE_ENABLE_I18N
+      mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+      non_match = true;
+      if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
+	bitset_set (sbcset, '\n');
+      re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+      token_len = peek_token_bracket (token, regexp, syntax);
+      if (BE (token->type == END_OF_RE, 0))
+	{
+	  *err = REG_BADPAT;
+	  goto parse_bracket_exp_free_return;
+	}
+    }
+
+  /* We treat the first ']' as a normal character.  */
+  if (token->type == OP_CLOSE_BRACKET)
+    token->type = CHARACTER;
+
+  while (1)
+    {
+      bracket_elem_t start_elem, end_elem;
+      unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
+      unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
+      reg_errcode_t ret;
+      int token_len2 = 0;
+      bool is_range_exp = false;
+      re_token_t token2;
+
+      start_elem.opr.name = start_name_buf;
+      ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa,
+				   syntax, first_round);
+      if (BE (ret != REG_NOERROR, 0))
+	{
+	  *err = ret;
+	  goto parse_bracket_exp_free_return;
+	}
+      first_round = false;
+
+      /* Get information about the next token.  We need it in any case.  */
+      token_len = peek_token_bracket (token, regexp, syntax);
+
+      /* Do not check for ranges if we know they are not allowed.  */
+      if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS)
+	{
+	  if (BE (token->type == END_OF_RE, 0))
+	    {
+	      *err = REG_EBRACK;
+	      goto parse_bracket_exp_free_return;
+	    }
+	  if (token->type == OP_CHARSET_RANGE)
+	    {
+	      re_string_skip_bytes (regexp, token_len); /* Skip '-'.  */
+	      token_len2 = peek_token_bracket (&token2, regexp, syntax);
+	      if (BE (token2.type == END_OF_RE, 0))
+		{
+		  *err = REG_EBRACK;
+		  goto parse_bracket_exp_free_return;
+		}
+	      if (token2.type == OP_CLOSE_BRACKET)
+		{
+		  /* We treat the last '-' as a normal character.  */
+		  re_string_skip_bytes (regexp, -token_len);
+		  token->type = CHARACTER;
+		}
+	      else
+		is_range_exp = true;
+	    }
+	}
+
+      if (is_range_exp == true)
+	{
+	  end_elem.opr.name = end_name_buf;
+	  ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2,
+				       dfa, syntax, true);
+	  if (BE (ret != REG_NOERROR, 0))
+	    {
+	      *err = ret;
+	      goto parse_bracket_exp_free_return;
+	    }
+
+	  token_len = peek_token_bracket (token, regexp, syntax);
+
+#ifdef _LIBC
+	  *err = build_range_exp (sbcset, mbcset, &range_alloc,
+				  &start_elem, &end_elem);
+#else
+# ifdef RE_ENABLE_I18N
+	  *err = build_range_exp (syntax, sbcset,
+				  dfa->mb_cur_max > 1 ? mbcset : NULL,
+				  &range_alloc, &start_elem, &end_elem);
+# else
+	  *err = build_range_exp (syntax, sbcset, &start_elem, &end_elem);
+# endif
+#endif /* RE_ENABLE_I18N */
+	  if (BE (*err != REG_NOERROR, 0))
+	    goto parse_bracket_exp_free_return;
+	}
+      else
+	{
+	  switch (start_elem.type)
+	    {
+	    case SB_CHAR:
+	      bitset_set (sbcset, start_elem.opr.ch);
+	      break;
+#ifdef RE_ENABLE_I18N
+	    case MB_CHAR:
+	      /* Check whether the array has enough space.  */
+	      if (BE (mbchar_alloc == mbcset->nmbchars, 0))
+		{
+		  wchar_t *new_mbchars;
+		  /* Not enough, realloc it.  */
+		  /* +1 in case of mbcset->nmbchars is 0.  */
+		  mbchar_alloc = 2 * mbcset->nmbchars + 1;
+		  /* Use realloc since array is NULL if *alloc == 0.  */
+		  new_mbchars = re_realloc (mbcset->mbchars, wchar_t,
+					    mbchar_alloc);
+		  if (BE (new_mbchars == NULL, 0))
+		    goto parse_bracket_exp_espace;
+		  mbcset->mbchars = new_mbchars;
+		}
+	      mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch;
+	      break;
+#endif /* RE_ENABLE_I18N */
+	    case EQUIV_CLASS:
+	      *err = build_equiv_class (sbcset,
+#ifdef RE_ENABLE_I18N
+					mbcset, &equiv_class_alloc,
+#endif /* RE_ENABLE_I18N */
+					start_elem.opr.name);
+	      if (BE (*err != REG_NOERROR, 0))
+		goto parse_bracket_exp_free_return;
+	      break;
+	    case COLL_SYM:
+	      *err = build_collating_symbol (sbcset,
+#ifdef RE_ENABLE_I18N
+					     mbcset, &coll_sym_alloc,
+#endif /* RE_ENABLE_I18N */
+					     start_elem.opr.name);
+	      if (BE (*err != REG_NOERROR, 0))
+		goto parse_bracket_exp_free_return;
+	      break;
+	    case CHAR_CLASS:
+	      *err = build_charclass (regexp->trans, sbcset,
+#ifdef RE_ENABLE_I18N
+				      mbcset, &char_class_alloc,
+#endif /* RE_ENABLE_I18N */
+				      start_elem.opr.name, syntax);
+	      if (BE (*err != REG_NOERROR, 0))
+	       goto parse_bracket_exp_free_return;
+	      break;
+	    default:
+	      assert (0);
+	      break;
+	    }
+	}
+      if (BE (token->type == END_OF_RE, 0))
+	{
+	  *err = REG_EBRACK;
+	  goto parse_bracket_exp_free_return;
+	}
+      if (token->type == OP_CLOSE_BRACKET)
+	break;
+    }
+
+  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+
+  /* If it is non-matching list.  */
+  if (non_match)
+    bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure only single byte characters are set.  */
+  if (dfa->mb_cur_max > 1)
+    bitset_mask (sbcset, dfa->sb_char);
+
+  if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes
+      || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes
+						     || mbcset->non_match)))
+    {
+      bin_tree_t *mbc_tree;
+      int sbc_idx;
+      /* Build a tree for complex bracket.  */
+      dfa->has_mb_node = 1;
+      br_token.type = COMPLEX_BRACKET;
+      br_token.opr.mbcset = mbcset;
+      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (mbc_tree == NULL, 0))
+	goto parse_bracket_exp_espace;
+      for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx)
+	if (sbcset[sbc_idx])
+	  break;
+      /* If there are no bits set in sbcset, there is no point
+	 of having both SIMPLE_BRACKET and COMPLEX_BRACKET.  */
+      if (sbc_idx < BITSET_WORDS)
+	{
+	  /* Build a tree for simple bracket.  */
+	  br_token.type = SIMPLE_BRACKET;
+	  br_token.opr.sbcset = sbcset;
+	  work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+	  if (BE (work_tree == NULL, 0))
+	    goto parse_bracket_exp_espace;
+
+	  /* Then join them by ALT node.  */
+	  work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT);
+	  if (BE (work_tree == NULL, 0))
+	    goto parse_bracket_exp_espace;
+	}
+      else
+	{
+	  re_free (sbcset);
+	  work_tree = mbc_tree;
+	}
+    }
+  else
+#endif /* not RE_ENABLE_I18N */
+    {
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif
+      /* Build a tree for simple bracket.  */
+      br_token.type = SIMPLE_BRACKET;
+      br_token.opr.sbcset = sbcset;
+      work_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (work_tree == NULL, 0))
+	goto parse_bracket_exp_espace;
+    }
+  return work_tree;
+
+ parse_bracket_exp_espace:
+  *err = REG_ESPACE;
+ parse_bracket_exp_free_return:
+  re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+  free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+  return NULL;
+}
+
+/* Parse an element in the bracket expression.  */
+
+static reg_errcode_t
+parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp,
+		       re_token_t *token, int token_len, re_dfa_t *dfa,
+		       reg_syntax_t syntax, bool accept_hyphen)
+{
+#ifdef RE_ENABLE_I18N
+  int cur_char_size;
+  cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp));
+  if (cur_char_size > 1)
+    {
+      elem->type = MB_CHAR;
+      elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp));
+      re_string_skip_bytes (regexp, cur_char_size);
+      return REG_NOERROR;
+    }
+#endif /* RE_ENABLE_I18N */
+  re_string_skip_bytes (regexp, token_len); /* Skip a token.  */
+  if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+      || token->type == OP_OPEN_EQUIV_CLASS)
+    return parse_bracket_symbol (elem, regexp, token);
+  if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen)
+    {
+      /* A '-' must only appear as anything but a range indicator before
+	 the closing bracket.  Everything else is an error.  */
+      re_token_t token2;
+      (void) peek_token_bracket (&token2, regexp, syntax);
+      if (token2.type != OP_CLOSE_BRACKET)
+	/* The actual error value is not standardized since this whole
+	   case is undefined.  But ERANGE makes good sense.  */
+	return REG_ERANGE;
+    }
+  elem->type = SB_CHAR;
+  elem->opr.ch = token->opr.c;
+  return REG_NOERROR;
+}
+
+/* Parse a bracket symbol in the bracket expression.  Bracket symbols are
+   such as [:<character_class>:], [.<collating_element>.], and
+   [=<equivalent_class>=].  */
+
+static reg_errcode_t
+parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp,
+		      re_token_t *token)
+{
+  unsigned char ch, delim = token->opr.c;
+  int i = 0;
+  if (re_string_eoi(regexp))
+    return REG_EBRACK;
+  for (;; ++i)
+    {
+      if (i >= BRACKET_NAME_BUF_SIZE)
+	return REG_EBRACK;
+      if (token->type == OP_OPEN_CHAR_CLASS)
+	ch = re_string_fetch_byte_case (regexp);
+      else
+	ch = re_string_fetch_byte (regexp);
+      if (re_string_eoi(regexp))
+	return REG_EBRACK;
+      if (ch == delim && re_string_peek_byte (regexp, 0) == ']')
+	break;
+      elem->opr.name[i] = ch;
+    }
+  re_string_skip_bytes (regexp, 1);
+  elem->opr.name[i] = '\0';
+  switch (token->type)
+    {
+    case OP_OPEN_COLL_ELEM:
+      elem->type = COLL_SYM;
+      break;
+    case OP_OPEN_EQUIV_CLASS:
+      elem->type = EQUIV_CLASS;
+      break;
+    case OP_OPEN_CHAR_CLASS:
+      elem->type = CHAR_CLASS;
+      break;
+    default:
+      break;
+    }
+  return REG_NOERROR;
+}
+
+  /* Helper function for parse_bracket_exp.
+     Build the equivalence class which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
+     is a pointer argument sinse we may update it.  */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_equiv_class (bitset_t sbcset, re_charset_t *mbcset,
+		   Idx *equiv_class_alloc, const unsigned char *name)
+#else /* not RE_ENABLE_I18N */
+build_equiv_class (bitset_t sbcset, const unsigned char *name)
+#endif /* not RE_ENABLE_I18N */
+{
+#ifdef _LIBC
+  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules != 0)
+    {
+      const int32_t *table, *indirect;
+      const unsigned char *weights, *extra, *cp;
+      unsigned char char_buf[2];
+      int32_t idx1, idx2;
+      unsigned int ch;
+      size_t len;
+      /* This #include defines a local function!  */
+# include <locale/weight.h>
+      /* Calculate the index for equivalence class.  */
+      cp = name;
+      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+      weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+					       _NL_COLLATE_WEIGHTMB);
+      extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE,
+						   _NL_COLLATE_EXTRAMB);
+      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+						_NL_COLLATE_INDIRECTMB);
+      idx1 = findidx (&cp);
+      if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0))
+	/* This isn't a valid character.  */
+	return REG_ECOLLATE;
+
+      /* Build single byte matcing table for this equivalence class.  */
+      char_buf[1] = (unsigned char) '\0';
+      len = weights[idx1 & 0xffffff];
+      for (ch = 0; ch < SBC_MAX; ++ch)
+	{
+	  char_buf[0] = ch;
+	  cp = char_buf;
+	  idx2 = findidx (&cp);
+/*
+	  idx2 = table[ch];
+*/
+	  if (idx2 == 0)
+	    /* This isn't a valid character.  */
+	    continue;
+	  /* Compare only if the length matches and the collation rule
+	     index is the same.  */
+	  if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24))
+	    {
+	      int cnt = 0;
+
+	      while (cnt <= len &&
+		     weights[(idx1 & 0xffffff) + 1 + cnt]
+		     == weights[(idx2 & 0xffffff) + 1 + cnt])
+		++cnt;
+
+	      if (cnt > len)
+		bitset_set (sbcset, ch);
+	    }
+	}
+      /* Check whether the array has enough space.  */
+      if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0))
+	{
+	  /* Not enough, realloc it.  */
+	  /* +1 in case of mbcset->nequiv_classes is 0.  */
+	  Idx new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1;
+	  /* Use realloc since the array is NULL if *alloc == 0.  */
+	  int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes,
+						   int32_t,
+						   new_equiv_class_alloc);
+	  if (BE (new_equiv_classes == NULL, 0))
+	    return REG_ESPACE;
+	  mbcset->equiv_classes = new_equiv_classes;
+	  *equiv_class_alloc = new_equiv_class_alloc;
+	}
+      mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1;
+    }
+  else
+#endif /* _LIBC */
+    {
+      if (BE (strlen ((const char *) name) != 1, 0))
+	return REG_ECOLLATE;
+      bitset_set (sbcset, *name);
+    }
+  return REG_NOERROR;
+}
+
+  /* Helper function for parse_bracket_exp.
+     Build the character class which is represented by NAME.
+     The result are written to MBCSET and SBCSET.
+     CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
+     is a pointer argument sinse we may update it.  */
+
+static reg_errcode_t
+#ifdef RE_ENABLE_I18N
+build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+		 re_charset_t *mbcset, Idx *char_class_alloc,
+		 const unsigned char *class_name, reg_syntax_t syntax)
+#else /* not RE_ENABLE_I18N */
+build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+		 const unsigned char *class_name, reg_syntax_t syntax)
+#endif /* not RE_ENABLE_I18N */
+{
+  int i;
+  const char *name = (const char *) class_name;
+
+  /* In case of REG_ICASE "upper" and "lower" match the both of
+     upper and lower cases.  */
+  if ((syntax & RE_ICASE)
+      && (strcmp (name, "upper") == 0 || strcmp (name, "lower") == 0))
+    name = "alpha";
+
+#ifdef RE_ENABLE_I18N
+  /* Check the space of the arrays.  */
+  if (BE (*char_class_alloc == mbcset->nchar_classes, 0))
+    {
+      /* Not enough, realloc it.  */
+      /* +1 in case of mbcset->nchar_classes is 0.  */
+      Idx new_char_class_alloc = 2 * mbcset->nchar_classes + 1;
+      /* Use realloc since array is NULL if *alloc == 0.  */
+      wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t,
+					       new_char_class_alloc);
+      if (BE (new_char_classes == NULL, 0))
+	return REG_ESPACE;
+      mbcset->char_classes = new_char_classes;
+      *char_class_alloc = new_char_class_alloc;
+    }
+  mbcset->char_classes[mbcset->nchar_classes++] = __wctype (name);
+#endif /* RE_ENABLE_I18N */
+
+#define BUILD_CHARCLASS_LOOP(ctype_func)	\
+  do {						\
+    if (BE (trans != NULL, 0))			\
+      {						\
+	for (i = 0; i < SBC_MAX; ++i)		\
+	  if (ctype_func (i))			\
+	    bitset_set (sbcset, trans[i]);	\
+      }						\
+    else					\
+      {						\
+	for (i = 0; i < SBC_MAX; ++i)		\
+	  if (ctype_func (i))			\
+	    bitset_set (sbcset, i);		\
+      }						\
+  } while (0)
+
+  if (strcmp (name, "alnum") == 0)
+    BUILD_CHARCLASS_LOOP (isalnum);
+  else if (strcmp (name, "cntrl") == 0)
+    BUILD_CHARCLASS_LOOP (iscntrl);
+  else if (strcmp (name, "lower") == 0)
+    BUILD_CHARCLASS_LOOP (islower);
+  else if (strcmp (name, "space") == 0)
+    BUILD_CHARCLASS_LOOP (isspace);
+  else if (strcmp (name, "alpha") == 0)
+    BUILD_CHARCLASS_LOOP (isalpha);
+  else if (strcmp (name, "digit") == 0)
+    BUILD_CHARCLASS_LOOP (isdigit);
+  else if (strcmp (name, "print") == 0)
+    BUILD_CHARCLASS_LOOP (isprint);
+  else if (strcmp (name, "upper") == 0)
+    BUILD_CHARCLASS_LOOP (isupper);
+  else if (strcmp (name, "blank") == 0)
+    BUILD_CHARCLASS_LOOP (isblank);
+  else if (strcmp (name, "graph") == 0)
+    BUILD_CHARCLASS_LOOP (isgraph);
+  else if (strcmp (name, "punct") == 0)
+    BUILD_CHARCLASS_LOOP (ispunct);
+  else if (strcmp (name, "xdigit") == 0)
+    BUILD_CHARCLASS_LOOP (isxdigit);
+  else
+    return REG_ECTYPE;
+
+  return REG_NOERROR;
+}
+
+static bin_tree_t *
+build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+		    const unsigned char *class_name,
+		    const unsigned char *extra, bool non_match,
+		    reg_errcode_t *err)
+{
+  re_bitset_ptr_t sbcset;
+#ifdef RE_ENABLE_I18N
+  re_charset_t *mbcset;
+  Idx alloc = 0;
+#endif /* not RE_ENABLE_I18N */
+  reg_errcode_t ret;
+  re_token_t br_token;
+  bin_tree_t *tree;
+
+  sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1);
+#ifdef RE_ENABLE_I18N
+  mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1);
+#endif /* RE_ENABLE_I18N */
+
+#ifdef RE_ENABLE_I18N
+  if (BE (sbcset == NULL || mbcset == NULL, 0))
+#else /* not RE_ENABLE_I18N */
+  if (BE (sbcset == NULL, 0))
+#endif /* not RE_ENABLE_I18N */
+    {
+      *err = REG_ESPACE;
+      return NULL;
+    }
+
+  if (non_match)
+    {
+#ifdef RE_ENABLE_I18N
+      mbcset->non_match = 1;
+#endif /* not RE_ENABLE_I18N */
+    }
+
+  /* We don't care the syntax in this case.  */
+  ret = build_charclass (trans, sbcset,
+#ifdef RE_ENABLE_I18N
+			 mbcset, &alloc,
+#endif /* RE_ENABLE_I18N */
+			 class_name, 0);
+
+  if (BE (ret != REG_NOERROR, 0))
+    {
+      re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+      free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+      *err = ret;
+      return NULL;
+    }
+  /* \w match '_' also.  */
+  for (; *extra; extra++)
+    bitset_set (sbcset, *extra);
+
+  /* If it is non-matching list.  */
+  if (non_match)
+    bitset_not (sbcset);
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure only single byte characters are set.  */
+  if (dfa->mb_cur_max > 1)
+    bitset_mask (sbcset, dfa->sb_char);
+#endif
+
+  /* Build a tree for simple bracket.  */
+  br_token.type = SIMPLE_BRACKET;
+  br_token.opr.sbcset = sbcset;
+  tree = create_token_tree (dfa, NULL, NULL, &br_token);
+  if (BE (tree == NULL, 0))
+    goto build_word_op_espace;
+
+#ifdef RE_ENABLE_I18N
+  if (dfa->mb_cur_max > 1)
+    {
+      bin_tree_t *mbc_tree;
+      /* Build a tree for complex bracket.  */
+      br_token.type = COMPLEX_BRACKET;
+      br_token.opr.mbcset = mbcset;
+      dfa->has_mb_node = 1;
+      mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token);
+      if (BE (mbc_tree == NULL, 0))
+	goto build_word_op_espace;
+      /* Then join them by ALT node.  */
+      tree = create_tree (dfa, tree, mbc_tree, OP_ALT);
+      if (BE (mbc_tree != NULL, 1))
+	return tree;
+    }
+  else
+    {
+      free_charset (mbcset);
+      return tree;
+    }
+#else /* not RE_ENABLE_I18N */
+  return tree;
+#endif /* not RE_ENABLE_I18N */
+
+ build_word_op_espace:
+  re_free (sbcset);
+#ifdef RE_ENABLE_I18N
+  free_charset (mbcset);
+#endif /* RE_ENABLE_I18N */
+  *err = REG_ESPACE;
+  return NULL;
+}
+
+/* This is intended for the expressions like "a{1,3}".
+   Fetch a number from `input', and return the number.
+   Return REG_MISSING if the number field is empty like "{,1}".
+   Return REG_ERROR if an error occurred.  */
+
+static Idx
+fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax)
+{
+  Idx num = REG_MISSING;
+  unsigned char c;
+  while (1)
+    {
+      fetch_token (token, input, syntax);
+      c = token->opr.c;
+      if (BE (token->type == END_OF_RE, 0))
+	return REG_ERROR;
+      if (token->type == OP_CLOSE_DUP_NUM || c == ',')
+	break;
+      num = ((token->type != CHARACTER || c < '0' || '9' < c
+	      || num == REG_ERROR)
+	     ? REG_ERROR
+	     : ((num == REG_MISSING) ? c - '0' : num * 10 + c - '0'));
+      num = (num > RE_DUP_MAX) ? REG_ERROR : num;
+    }
+  return num;
+}
+

+#ifdef RE_ENABLE_I18N
+static void
+free_charset (re_charset_t *cset)
+{
+  re_free (cset->mbchars);
+# ifdef _LIBC
+  re_free (cset->coll_syms);
+  re_free (cset->equiv_classes);
+  re_free (cset->range_starts);
+  re_free (cset->range_ends);
+# endif
+  re_free (cset->char_classes);
+  re_free (cset);
+}
+#endif /* RE_ENABLE_I18N */
+

+/* Functions for binary tree operation.  */
+
+/* Create a tree node.  */
+
+static bin_tree_t *
+create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+	     re_token_type_t type)
+{
+  re_token_t t;
+  t.type = type;
+  return create_token_tree (dfa, left, right, &t);
+}
+
+static bin_tree_t *
+create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+		   const re_token_t *token)
+{
+  bin_tree_t *tree;
+  if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0))
+    {
+      bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1);
+
+      if (storage == NULL)
+	return NULL;
+      storage->next = dfa->str_tree_storage;
+      dfa->str_tree_storage = storage;
+      dfa->str_tree_storage_idx = 0;
+    }
+  tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];
+
+  tree->parent = NULL;
+  tree->left = left;
+  tree->right = right;
+  tree->token = *token;
+  tree->token.duplicated = 0;
+  tree->token.opt_subexp = 0;
+  tree->first = NULL;
+  tree->next = NULL;
+  tree->node_idx = REG_MISSING;
+
+  if (left != NULL)
+    left->parent = tree;
+  if (right != NULL)
+    right->parent = tree;
+  return tree;
+}
+
+/* Mark the tree SRC as an optional subexpression.
+   To be called from preorder or postorder.  */
+
+static reg_errcode_t
+mark_opt_subexp (void *extra, bin_tree_t *node)
+{
+  Idx idx = (Idx) (long) extra;
+  if (node->token.type == SUBEXP && node->token.opr.idx == idx)
+    node->token.opt_subexp = 1;
+
+  return REG_NOERROR;
+}
+
+/* Free the allocated memory inside NODE. */
+
+static void
+free_token (re_token_t *node)
+{
+#ifdef RE_ENABLE_I18N
+  if (node->type == COMPLEX_BRACKET && node->duplicated == 0)
+    free_charset (node->opr.mbcset);
+  else
+#endif /* RE_ENABLE_I18N */
+    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+      re_free (node->opr.sbcset);
+}
+
+/* Worker function for tree walking.  Free the allocated memory inside NODE
+   and its children. */
+
+static reg_errcode_t
+free_tree (void *extra, bin_tree_t *node)
+{
+  free_token (&node->token);
+  return REG_NOERROR;
+}
+
+
+/* Duplicate the node SRC, and return new node.  This is a preorder
+   visit similar to the one implemented by the generic visitor, but
+   we need more infrastructure to maintain two parallel trees --- so,
+   it's easier to duplicate.  */
+
+static bin_tree_t *
+duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa)
+{
+  const bin_tree_t *node;
+  bin_tree_t *dup_root;
+  bin_tree_t **p_new = &dup_root, *dup_node = root->parent;
+
+  for (node = root; ; )
+    {
+      /* Create a new tree and link it back to the current parent.  */
+      *p_new = create_token_tree (dfa, NULL, NULL, &node->token);
+      if (*p_new == NULL)
+	return NULL;
+      (*p_new)->parent = dup_node;
+      (*p_new)->token.duplicated = 1;
+      dup_node = *p_new;
+
+      /* Go to the left node, or up and to the right.  */
+      if (node->left)
+	{
+	  node = node->left;
+	  p_new = &dup_node->left;
+	}
+      else
+	{
+	  const bin_tree_t *prev = NULL;
+	  while (node->right == prev || node->right == NULL)
+	    {
+	      prev = node;
+	      node = node->parent;
+	      dup_node = dup_node->parent;
+	      if (!node)
+		return dup_root;
+	    }
+	  node = node->right;
+	  p_new = &dup_node->right;
+	}
+    }
+}
diff --git a/gl/regex.c b/gl/regex.c
new file mode 100644
index 0000000..9d3cf3d
--- /dev/null
+++ b/gl/regex.c
@@ -0,0 +1,71 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2003, 2005-2006, 2009-2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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. */
+
+#include <config.h>
+
+/* Make sure noone compiles this code with a C++ compiler.  */
+#if defined __cplusplus && defined _LIBC
+# error "This is C code, use a C compiler"
+#endif
+
+#ifdef _LIBC
+/* We have to keep the namespace clean.  */
+# define regfree(preg) __regfree (preg)
+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
+# define regerror(errcode, preg, errbuf, errbuf_size) \
+	__regerror(errcode, preg, errbuf, errbuf_size)
+# define re_set_registers(bu, re, nu, st, en) \
+	__re_set_registers (bu, re, nu, st, en)
+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
+	__re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+# define re_match(bufp, string, size, pos, regs) \
+	__re_match (bufp, string, size, pos, regs)
+# define re_search(bufp, string, size, startpos, range, regs) \
+	__re_search (bufp, string, size, startpos, range, regs)
+# define re_compile_pattern(pattern, length, bufp) \
+	__re_compile_pattern (pattern, length, bufp)
+# define re_set_syntax(syntax) __re_set_syntax (syntax)
+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
+	__re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
+
+# include "../locale/localeinfo.h"
+#endif
+
+/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
+   GNU regex allows.  Include it before <regex.h>, which correctly
+   #undefs RE_DUP_MAX and sets it to the right value.  */
+#include <limits.h>
+
+#include <regex.h>
+#include "regex_internal.h"
+
+#include "regex_internal.c"
+#include "regcomp.c"
+#include "regexec.c"
+
+/* Binary backward compatibility.  */
+#if _LIBC
+# include <shlib-compat.h>
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3)
+link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.")
+int re_max_failures = 2000;
+# endif
+#endif
diff --git a/gl/regex.h b/gl/regex.h
new file mode 100644
index 0000000..1908687
--- /dev/null
+++ b/gl/regex.h
@@ -0,0 +1,675 @@
+/* Definitions for data structures and routines for the regular
+   expression library.
+   Copyright (C) 1985, 1989-1993, 1995-1998, 2000-2003, 2005-2006, 2009-2011
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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. */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+#include <sys/types.h>
+
+/* Allow the use in C++ code.  */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define __USE_GNU_REGEX to declare GNU extensions that violate the
+   POSIX name space rules.  */
+#undef __USE_GNU_REGEX
+#if (defined _GNU_SOURCE					\
+     || (!defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE	\
+	 && !defined _XOPEN_SOURCE))
+# define __USE_GNU_REGEX 1
+#endif
+
+#ifdef _REGEX_LARGE_OFFSETS
+
+/* Use types and values that are wide enough to represent signed and
+   unsigned byte offsets in memory.  This currently works only when
+   the regex code is used outside of the GNU C library; it is not yet
+   supported within glibc itself, and glibc users should not define
+   _REGEX_LARGE_OFFSETS.  */
+
+/* The type of the offset of a byte within a string.
+   For historical reasons POSIX 1003.1-2004 requires that regoff_t be
+   at least as wide as off_t.  However, many common POSIX platforms set
+   regoff_t to the more-sensible ssize_t and the Open Group has
+   signalled its intention to change the requirement to be that
+   regoff_t be at least as wide as ptrdiff_t and ssize_t; see XBD ERN
+   60 (2005-08-25).  We don't know of any hosts where ssize_t or
+   ptrdiff_t is wider than ssize_t, so ssize_t is safe.  */
+typedef ssize_t regoff_t;
+
+/* The type of nonnegative object indexes.  Traditionally, GNU regex
+   uses 'int' for these.  Code that uses __re_idx_t should work
+   regardless of whether the type is signed.  */
+typedef size_t __re_idx_t;
+
+/* The type of object sizes.  */
+typedef size_t __re_size_t;
+
+/* The type of object sizes, in places where the traditional code
+   uses unsigned long int.  */
+typedef size_t __re_long_size_t;
+
+#else
+
+/* Use types that are binary-compatible with the traditional GNU regex
+   implementation, which mishandles strings longer than INT_MAX.  */
+
+typedef int regoff_t;
+typedef int __re_idx_t;
+typedef unsigned int __re_size_t;
+typedef unsigned long int __re_long_size_t;
+
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+   wide enough to hold a value of a pointer.  For most ANSI compilers
+   ptrdiff_t and size_t should be likely OK.  Still size of these two
+   types is 2 for Microsoft C.  Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned long int reg_syntax_t;
+
+#ifdef __USE_GNU_REGEX
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+   If set, then such a \ quotes the following character.  */
+# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+     literals.
+   If set, then \+ and \? are operators and + and ? are literals.  */
+# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported.  They are:
+     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
+     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+   If not set, then character classes are not supported.  */
+# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+     expressions, of course).
+   If this bit is not set, then it depends:
+	^  is an anchor if it is at the beginning of a regular
+	   expression or after an open-group or an alternation operator;
+	$  is an anchor if it is at the end of a regular expression, or
+	   before a close-group or an alternation operator.
+
+   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+   POSIX draft 11.2 says that * etc. in leading positions is undefined.
+   We already implemented a previous draft which made those constructs
+   invalid, though, so we haven't changed the code back.  */
+# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+     regardless of where they are in the pattern.
+   If this bit is not set, then special characters are special only in
+     some contexts; otherwise they are ordinary.  Specifically,
+     * + ? and intervals are only special when not after the beginning,
+     open-group, or alternation operator.  */
+# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+     immediately after an alternation or begin-group operator.  */
+# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+   If not set, then it doesn't.  */
+# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+   If not set, then it does.  */
+# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+   If not set, they do.  */
+# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+     interval, depending on RE_NO_BK_BRACES.
+   If not set, \{, \}, {, and } are literals.  */
+# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+   If not set, they are.  */
+# define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+   If not set, newline is literal.  */
+# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+     are literals.
+  If not set, then `\{...\}' defines an interval.  */
+# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+   If not set, \(...\) defines a group, and ( and ) are literals.  */
+# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+   If not set, then \<digit> is a back-reference.  */
+# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+   If not set, then \| is an alternation operator, and | is literal.  */
+# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+     than the starting range point, as in [z-a], is invalid.
+   If not set, then when ending range point collates higher than the
+     starting range point, the range is ignored.  */
+# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+   If not set, then an unmatched ) is invalid.  */
+# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+   without further backtracking.  */
+# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+   If not set, then the GNU regex operators are recognized. */
+# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+   If not set, and debugging was on, turn it off.
+   This only works if regex.c is compiled -DDEBUG.
+   We define this bit always, so that all that's needed to turn on
+   debugging is to recompile regex.c; the calling code can always have
+   this bit set, and it won't affect anything in the normal case. */
+# define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* If this bit is set, a syntactically invalid interval is treated as
+   a string of ordinary characters.  For example, the ERE 'a{1' is
+   treated as 'a\{1'.  */
+# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+
+/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
+   for ^, because it is difficult to scan the regex backwards to find
+   whether ^ should be special.  */
+# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
+
+/* If this bit is set, then \{ cannot be first in a regex or
+   immediately after an alternation, open-group or \} operator.  */
+# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
+
+/* If this bit is set, then no_sub will be set to 1 during
+   re_compile_pattern.  */
+# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
+
+#endif /* defined __USE_GNU_REGEX */
+
+/* This global variable defines the particular regexp syntax to use (for
+   some interfaces).  When a regexp is compiled, the syntax used is
+   stored in the pattern buffer, so changing this does not affect
+   already-compiled regexps.  */
+extern reg_syntax_t re_syntax_options;
+

+#ifdef __USE_GNU_REGEX
+/* Define combinations of the above bits for the standard possibilities.
+   (The [[[ comments delimit what gets put into the Texinfo file, so
+   don't delete them!)  */
+/* [[[begin syntaxes]]] */
+# define RE_SYNTAX_EMACS 0
+
+# define RE_SYNTAX_AWK							\
+  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL			\
+   | RE_NO_BK_PARENS              | RE_NO_BK_REFS			\
+   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES			\
+   | RE_DOT_NEWLINE		  | RE_CONTEXT_INDEP_ANCHORS		\
+   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+# define RE_SYNTAX_GNU_AWK						\
+  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG)	\
+   & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS		\
+       | RE_CONTEXT_INVALID_OPS ))
+
+# define RE_SYNTAX_POSIX_AWK						\
+  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
+   | RE_INTERVALS	    | RE_NO_GNU_OPS)
+
+# define RE_SYNTAX_GREP							\
+  (RE_BK_PLUS_QM              | RE_CHAR_CLASSES				\
+   | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS				\
+   | RE_NEWLINE_ALT)
+
+# define RE_SYNTAX_EGREP						\
+  (RE_CHAR_CLASSES        | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE			\
+   | RE_NEWLINE_ALT       | RE_NO_BK_PARENS				\
+   | RE_NO_BK_VBAR)
+
+# define RE_SYNTAX_POSIX_EGREP						\
+  (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES			\
+   | RE_INVALID_INTERVAL_ORD)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
+# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax.  */
+# define _RE_SYNTAX_POSIX_COMMON					\
+  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
+   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+
+# define RE_SYNTAX_POSIX_BASIC						\
+  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+   isn't minimal, since other operators, such as \`, aren't disabled.  */
+# define RE_SYNTAX_POSIX_MINIMAL_BASIC					\
+  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+# define RE_SYNTAX_POSIX_EXTENDED					\
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES				\
+   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR				\
+   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
+   removed and RE_NO_BK_REFS is added.  */
+# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED				\
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES				\
+   | RE_NO_BK_PARENS        | RE_NO_BK_REFS				\
+   | RE_NO_BK_VBAR	    | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+#endif /* defined __USE_GNU_REGEX */
+

+#ifdef __USE_GNU_REGEX
+
+/* Maximum number of duplicates an interval can allow.  POSIX-conforming
+   systems might define this in <limits.h>, but we want our
+   value, so remove any previous define.  */
+# ifdef RE_DUP_MAX
+#  undef RE_DUP_MAX
+# endif
+
+/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored
+   the counter as a 2-byte signed integer.  This is no longer true, so
+   RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to
+   ((SIZE_MAX - 2) / 10 - 1) if _REGEX_LARGE_OFFSETS is defined.
+   However, there would be a huge performance problem if someone
+   actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains
+   its historical value.  */
+# define RE_DUP_MAX (0x7fff)
+
+#endif /* defined __USE_GNU_REGEX */
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp').  */
+
+/* If this bit is set, then use extended regular expression syntax.
+   If not set, then use basic regular expression syntax.  */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+#define REG_ICASE (1 << 1)
+
+/* If this bit is set, then anchors do not match at newline
+     characters in the string.
+   If not set, then anchors do match at newlines.  */
+#define REG_NEWLINE (1 << 2)
+
+/* If this bit is set, then report only success or fail in regexec.
+   If not set, then returns differ between not matching and errors.  */
+#define REG_NOSUB (1 << 3)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec).  */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+     the beginning of the string (presumably because it's not the
+     beginning of a line).
+   If not set, then the beginning-of-line operator does match the
+     beginning of the string.  */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line.  */
+#define REG_NOTEOL (1 << 1)
+
+/* Use PMATCH[0] to delimit the start and end of the search in the
+   buffer.  */
+#define REG_STARTEND (1 << 2)
+
+
+/* If any error codes are removed, changed, or added, update the
+   `__re_error_msgid' table in regcomp.c.  */
+
+typedef enum
+{
+  _REG_ENOSYS = -1,	/* This will never happen for this implementation.  */
+  _REG_NOERROR = 0,	/* Success.  */
+  _REG_NOMATCH,		/* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+  _REG_BADPAT,		/* Invalid pattern.  */
+  _REG_ECOLLATE,	/* Invalid collating element.  */
+  _REG_ECTYPE,		/* Invalid character class name.  */
+  _REG_EESCAPE,		/* Trailing backslash.  */
+  _REG_ESUBREG,		/* Invalid back reference.  */
+  _REG_EBRACK,		/* Unmatched left bracket.  */
+  _REG_EPAREN,		/* Parenthesis imbalance.  */
+  _REG_EBRACE,		/* Unmatched \{.  */
+  _REG_BADBR,		/* Invalid contents of \{\}.  */
+  _REG_ERANGE,		/* Invalid range end.  */
+  _REG_ESPACE,		/* Ran out of memory.  */
+  _REG_BADRPT,		/* No preceding re for repetition op.  */
+
+  /* Error codes we've added.  */
+  _REG_EEND,		/* Premature end.  */
+  _REG_ESIZE,		/* Compiled pattern bigger than 2^16 bytes.  */
+  _REG_ERPAREN		/* Unmatched ) or \); not returned from regcomp.  */
+} reg_errcode_t;
+
+#ifdef _XOPEN_SOURCE
+# define REG_ENOSYS	_REG_ENOSYS
+#endif
+#define REG_NOERROR	_REG_NOERROR
+#define REG_NOMATCH	_REG_NOMATCH
+#define REG_BADPAT	_REG_BADPAT
+#define REG_ECOLLATE	_REG_ECOLLATE
+#define REG_ECTYPE	_REG_ECTYPE
+#define REG_EESCAPE	_REG_EESCAPE
+#define REG_ESUBREG	_REG_ESUBREG
+#define REG_EBRACK	_REG_EBRACK
+#define REG_EPAREN	_REG_EPAREN
+#define REG_EBRACE	_REG_EBRACE
+#define REG_BADBR	_REG_BADBR
+#define REG_ERANGE	_REG_ERANGE
+#define REG_ESPACE	_REG_ESPACE
+#define REG_BADRPT	_REG_BADRPT
+#define REG_EEND	_REG_EEND
+#define REG_ESIZE	_REG_ESIZE
+#define REG_ERPAREN	_REG_ERPAREN
+

+/* struct re_pattern_buffer normally uses member names like `buffer'
+   that POSIX does not allow.  In POSIX mode these members have names
+   with leading `re_' (e.g., `re_buffer').  */
+#ifdef __USE_GNU_REGEX
+# define _REG_RE_NAME(id) id
+# define _REG_RM_NAME(id) id
+#else
+# define _REG_RE_NAME(id) re_##id
+# define _REG_RM_NAME(id) rm_##id
+#endif
+
+/* The user can specify the type of the re_translate member by
+   defining the macro RE_TRANSLATE_TYPE, which defaults to unsigned
+   char *.  This pollutes the POSIX name space, so in POSIX mode just
+   use unsigned char *.  */
+#ifdef __USE_GNU_REGEX
+# ifndef RE_TRANSLATE_TYPE
+#  define RE_TRANSLATE_TYPE unsigned char *
+# endif
+# define REG_TRANSLATE_TYPE RE_TRANSLATE_TYPE
+#else
+# define REG_TRANSLATE_TYPE unsigned char *
+#endif
+
+/* This data structure represents a compiled pattern.  Before calling
+   the pattern compiler, the fields `buffer', `allocated', `fastmap',
+   `translate', and `no_sub' can be set.  After the pattern has been
+   compiled, the `re_nsub' field is available.  All other fields are
+   private to the regex routines.  */
+
+struct re_pattern_buffer
+{
+  /* Space that holds the compiled pattern.  It is declared as
+     `unsigned char *' because its elements are sometimes used as
+     array indexes.  */
+  unsigned char *_REG_RE_NAME (buffer);
+
+  /* Number of bytes to which `buffer' points.  */
+  __re_long_size_t _REG_RE_NAME (allocated);
+
+  /* Number of bytes actually used in `buffer'.  */
+  __re_long_size_t _REG_RE_NAME (used);
+
+  /* Syntax setting with which the pattern was compiled.  */
+  reg_syntax_t _REG_RE_NAME (syntax);
+
+  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the
+     fastmap, if there is one, to skip over impossible starting points
+     for matches.  */
+  char *_REG_RE_NAME (fastmap);
+
+  /* Either a translate table to apply to all characters before
+     comparing them, or zero for no translation.  The translation is
+     applied to a pattern when it is compiled and to a string when it
+     is matched.  */
+  REG_TRANSLATE_TYPE _REG_RE_NAME (translate);
+
+  /* Number of subexpressions found by the compiler.  */
+  size_t re_nsub;
+
+  /* Zero if this pattern cannot match the empty string, one else.
+     Well, in truth it's used only in `re_search_2', to see whether or
+     not we should use the fastmap, so we don't set this absolutely
+     perfectly; see `re_compile_fastmap' (the `duplicate' case).  */
+  unsigned int _REG_RE_NAME (can_be_null) : 1;
+
+  /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+     for `max (RE_NREGS, re_nsub + 1)' groups.
+     If REGS_REALLOCATE, reallocate space if necessary.
+     If REGS_FIXED, use what's there.  */
+#ifdef __USE_GNU_REGEX
+# define REGS_UNALLOCATED 0
+# define REGS_REALLOCATE 1
+# define REGS_FIXED 2
+#endif
+  unsigned int _REG_RE_NAME (regs_allocated) : 2;
+
+  /* Set to zero when `re_compile_pattern' compiles a pattern; set to
+     one by `re_compile_fastmap' if it updates the fastmap.  */
+  unsigned int _REG_RE_NAME (fastmap_accurate) : 1;
+
+  /* If set, `re_match_2' does not return information about
+     subexpressions.  */
+  unsigned int _REG_RE_NAME (no_sub) : 1;
+
+  /* If set, a beginning-of-line anchor doesn't match at the beginning
+     of the string.  */
+  unsigned int _REG_RE_NAME (not_bol) : 1;
+
+  /* Similarly for an end-of-line anchor.  */
+  unsigned int _REG_RE_NAME (not_eol) : 1;
+
+  /* If true, an anchor at a newline matches.  */
+  unsigned int _REG_RE_NAME (newline_anchor) : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+

+/* This is the structure we store register match data in.  See
+   regex.texinfo for a full description of what registers match.  */
+struct re_registers
+{
+  __re_size_t _REG_RM_NAME (num_regs);
+  regoff_t *_REG_RM_NAME (start);
+  regoff_t *_REG_RM_NAME (end);
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+   `re_match_2' returns information about at least this many registers
+   the first time a `regs' structure is passed.  */
+#if !defined RE_NREGS && defined __USE_GNU_REGEX
+# define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers.  Aside from the different names than
+   `re_registers', POSIX uses an array of structures, instead of a
+   structure of arrays.  */
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+

+/* Declarations for routines.  */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+   You can also simply assign to the `re_syntax_options' variable.  */
+extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
+
+/* Compile the regular expression PATTERN, with length LENGTH
+   and syntax given by the global `re_syntax_options', into the buffer
+   BUFFER.  Return NULL if successful, and an error string if not.  */
+extern const char *re_compile_pattern (const char *__pattern, size_t __length,
+				       struct re_pattern_buffer *__buffer);
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+   accelerate searches.  Return 0 if successful and -2 if was an
+   internal error.  */
+extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+   compiled into BUFFER.  Start searching at position START, for RANGE
+   characters.  Return the starting position of the match, -1 for no
+   match, or -2 for an internal error.  Also return register
+   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
+extern regoff_t re_search (struct re_pattern_buffer *__buffer,
+			   const char *__string, __re_idx_t __length,
+			   __re_idx_t __start, regoff_t __range,
+			   struct re_registers *__regs);
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+   STRING2.  Also, stop searching at index START + STOP.  */
+extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
+			     const char *__string1, __re_idx_t __length1,
+			     const char *__string2, __re_idx_t __length2,
+			     __re_idx_t __start, regoff_t __range,
+			     struct re_registers *__regs,
+			     __re_idx_t __stop);
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+   in BUFFER matched, starting at position START.  */
+extern regoff_t re_match (struct re_pattern_buffer *__buffer,
+			  const char *__string, __re_idx_t __length,
+			  __re_idx_t __start, struct re_registers *__regs);
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'.  */
+extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
+			    const char *__string1, __re_idx_t __length1,
+			    const char *__string2, __re_idx_t __length2,
+			    __re_idx_t __start, struct re_registers *__regs,
+			    __re_idx_t __stop);
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
+   for recording register information.  STARTS and ENDS must be
+   allocated with malloc, and must each be at least `NUM_REGS * sizeof
+   (regoff_t)' bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   BUFFER will allocate its own register data, without freeing the old
+   data.  */
+extern void re_set_registers (struct re_pattern_buffer *__buffer,
+			      struct re_registers *__regs,
+			      __re_size_t __num_regs,
+			      regoff_t *__starts, regoff_t *__ends);
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+# ifndef _CRAY
+/* 4.2 bsd compatibility.  */
+extern char *re_comp (const char *);
+extern int re_exec (const char *);
+# endif
+#endif
+
+/* GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".
+   Other compilers use __restrict, __restrict__, and _Restrict, and
+   'configure' might #define 'restrict' to those words, so pick a
+   different name.  */
+#ifndef _Restrict_
+# if 199901L <= __STDC_VERSION__
+#  define _Restrict_ restrict
+# elif 2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)
+#  define _Restrict_ __restrict
+# else
+#  define _Restrict_
+# endif
+#endif
+/* gcc 3.1 and up support the [restrict] syntax.  Don't trust
+   sys/cdefs.h's definition of __restrict_arr, though, as it
+   mishandles gcc -ansi -pedantic.  */
+#ifndef _Restrict_arr_
+# if ((199901L <= __STDC_VERSION__					\
+       || ((3 < __GNUC__ || (3 == __GNUC__ && 1 <= __GNUC_MINOR__))	\
+	   && !__STRICT_ANSI__))					\
+      && !defined __GNUG__)
+#  define _Restrict_arr_ _Restrict_
+# else
+#  define _Restrict_arr_
+# endif
+#endif
+
+/* POSIX compatibility.  */
+extern int regcomp (regex_t *_Restrict_ __preg,
+		    const char *_Restrict_ __pattern,
+		    int __cflags);
+
+extern int regexec (const regex_t *_Restrict_ __preg,
+		    const char *_Restrict_ __string, size_t __nmatch,
+		    regmatch_t __pmatch[_Restrict_arr_],
+		    int __eflags);
+
+extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
+			char *_Restrict_ __errbuf, size_t __errbuf_size);
+
+extern void regfree (regex_t *__preg);
+
+
+#ifdef __cplusplus
+}
+#endif	/* C++ */
+
+#endif /* regex.h */
diff --git a/gl/regex_internal.c b/gl/regex_internal.c
new file mode 100644
index 0000000..e77cb76
--- /dev/null
+++ b/gl/regex_internal.c
@@ -0,0 +1,1741 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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. */
+
+static void re_string_construct_common (const char *str, Idx len,
+					re_string_t *pstr,
+					RE_TRANSLATE_TYPE trans, bool icase,
+					const re_dfa_t *dfa) internal_function;
+static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa,
+					  const re_node_set *nodes,
+					  re_hashval_t hash) internal_function;
+static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa,
+					  const re_node_set *nodes,
+					  unsigned int context,
+					  re_hashval_t hash) internal_function;
+

+/* Functions for string operation.  */
+
+/* This function allocate the buffers.  It is necessary to call
+   re_string_reconstruct before using the object.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_allocate (re_string_t *pstr, const char *str, Idx len, Idx init_len,
+		    RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
+{
+  reg_errcode_t ret;
+  Idx init_buf_len;
+
+  /* Ensure at least one character fits into the buffers.  */
+  if (init_len < dfa->mb_cur_max)
+    init_len = dfa->mb_cur_max;
+  init_buf_len = (len + 1 < init_len) ? len + 1: init_len;
+  re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+  ret = re_string_realloc_buffers (pstr, init_buf_len);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  pstr->word_char = dfa->word_char;
+  pstr->word_ops_used = dfa->word_ops_used;
+  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+  pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
+  pstr->valid_raw_len = pstr->valid_len;
+  return REG_NOERROR;
+}
+
+/* This function allocate the buffers, and initialize them.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_construct (re_string_t *pstr, const char *str, Idx len,
+		     RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa)
+{
+  reg_errcode_t ret;
+  memset (pstr, '\0', sizeof (re_string_t));
+  re_string_construct_common (str, len, pstr, trans, icase, dfa);
+
+  if (len > 0)
+    {
+      ret = re_string_realloc_buffers (pstr, len + 1);
+      if (BE (ret != REG_NOERROR, 0))
+	return ret;
+    }
+  pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+
+  if (icase)
+    {
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+	{
+	  while (1)
+	    {
+	      ret = build_wcs_upper_buffer (pstr);
+	      if (BE (ret != REG_NOERROR, 0))
+		return ret;
+	      if (pstr->valid_raw_len >= len)
+		break;
+	      if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max)
+		break;
+	      ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+	      if (BE (ret != REG_NOERROR, 0))
+		return ret;
+	    }
+	}
+      else
+#endif /* RE_ENABLE_I18N  */
+	build_upper_buffer (pstr);
+    }
+  else
+    {
+#ifdef RE_ENABLE_I18N
+      if (dfa->mb_cur_max > 1)
+	build_wcs_buffer (pstr);
+      else
+#endif /* RE_ENABLE_I18N  */
+	{
+	  if (trans != NULL)
+	    re_string_translate_buffer (pstr);
+	  else
+	    {
+	      pstr->valid_len = pstr->bufs_len;
+	      pstr->valid_raw_len = pstr->bufs_len;
+	    }
+	}
+    }
+
+  return REG_NOERROR;
+}
+
+/* Helper functions for re_string_allocate, and re_string_construct.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_realloc_buffers (re_string_t *pstr, Idx new_buf_len)
+{
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1)
+    {
+      wint_t *new_wcs;
+
+      /* Avoid overflow.  */
+      size_t max_object_size = MAX (sizeof (wint_t), sizeof (Idx));
+      if (BE (SIZE_MAX / max_object_size < new_buf_len, 0))
+	return REG_ESPACE;
+
+      new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len);
+      if (BE (new_wcs == NULL, 0))
+	return REG_ESPACE;
+      pstr->wcs = new_wcs;
+      if (pstr->offsets != NULL)
+	{
+	  Idx *new_offsets = re_realloc (pstr->offsets, Idx, new_buf_len);
+	  if (BE (new_offsets == NULL, 0))
+	    return REG_ESPACE;
+	  pstr->offsets = new_offsets;
+	}
+    }
+#endif /* RE_ENABLE_I18N  */
+  if (pstr->mbs_allocated)
+    {
+      unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char,
+					   new_buf_len);
+      if (BE (new_mbs == NULL, 0))
+	return REG_ESPACE;
+      pstr->mbs = new_mbs;
+    }
+  pstr->bufs_len = new_buf_len;
+  return REG_NOERROR;
+}
+
+
+static void
+internal_function
+re_string_construct_common (const char *str, Idx len, re_string_t *pstr,
+			    RE_TRANSLATE_TYPE trans, bool icase,
+			    const re_dfa_t *dfa)
+{
+  pstr->raw_mbs = (const unsigned char *) str;
+  pstr->len = len;
+  pstr->raw_len = len;
+  pstr->trans = trans;
+  pstr->icase = icase;
+  pstr->mbs_allocated = (trans != NULL || icase);
+  pstr->mb_cur_max = dfa->mb_cur_max;
+  pstr->is_utf8 = dfa->is_utf8;
+  pstr->map_notascii = dfa->map_notascii;
+  pstr->stop = pstr->len;
+  pstr->raw_stop = pstr->stop;
+}
+
+#ifdef RE_ENABLE_I18N
+
+/* Build wide character buffer PSTR->WCS.
+   If the byte sequence of the string are:
+     <mb1>(0), <mb1>(1), <mb2>(0), <mb2>(1), <sb3>
+   Then wide character buffer will be:
+     <wc1>   , WEOF    , <wc2>   , WEOF    , <wc3>
+   We use WEOF for padding, they indicate that the position isn't
+   a first byte of a multibyte character.
+
+   Note that this function assumes PSTR->VALID_LEN elements are already
+   built and starts from PSTR->VALID_LEN.  */
+
+static void
+internal_function
+build_wcs_buffer (re_string_t *pstr)
+{
+#ifdef _LIBC
+  unsigned char buf[MB_LEN_MAX];
+  assert (MB_LEN_MAX >= pstr->mb_cur_max);
+#else
+  unsigned char buf[64];
+#endif
+  mbstate_t prev_st;
+  Idx byte_idx, end_idx, remain_len;
+  size_t mbclen;
+
+  /* Build the buffers from pstr->valid_len to either pstr->len or
+     pstr->bufs_len.  */
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+  for (byte_idx = pstr->valid_len; byte_idx < end_idx;)
+    {
+      wchar_t wc;
+      const char *p;
+
+      remain_len = end_idx - byte_idx;
+      prev_st = pstr->cur_state;
+      /* Apply the translation if we need.  */
+      if (BE (pstr->trans != NULL, 0))
+	{
+	  int i, ch;
+
+	  for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+	    {
+	      ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i];
+	      buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch];
+	    }
+	  p = (const char *) buf;
+	}
+      else
+	p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx;
+      mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+      if (BE (mbclen == (size_t) -2, 0))
+	{
+	  /* The buffer doesn't have enough space, finish to build.  */
+	  pstr->cur_state = prev_st;
+	  break;
+	}
+      else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0))
+	{
+	  /* We treat these cases as a singlebyte character.  */
+	  mbclen = 1;
+	  wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+	  if (BE (pstr->trans != NULL, 0))
+	    wc = pstr->trans[wc];
+	  pstr->cur_state = prev_st;
+	}
+
+      /* Write wide character and padding.  */
+      pstr->wcs[byte_idx++] = wc;
+      /* Write paddings.  */
+      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+	pstr->wcs[byte_idx++] = WEOF;
+    }
+  pstr->valid_len = byte_idx;
+  pstr->valid_raw_len = byte_idx;
+}
+
+/* Build wide character buffer PSTR->WCS like build_wcs_buffer,
+   but for REG_ICASE.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+build_wcs_upper_buffer (re_string_t *pstr)
+{
+  mbstate_t prev_st;
+  Idx src_idx, byte_idx, end_idx, remain_len;
+  size_t mbclen;
+#ifdef _LIBC
+  char buf[MB_LEN_MAX];
+  assert (MB_LEN_MAX >= pstr->mb_cur_max);
+#else
+  char buf[64];
+#endif
+
+  byte_idx = pstr->valid_len;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  /* The following optimization assumes that ASCII characters can be
+     mapped to wide characters with a simple cast.  */
+  if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed)
+    {
+      while (byte_idx < end_idx)
+	{
+	  wchar_t wc;
+
+	  if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx])
+	      && mbsinit (&pstr->cur_state))
+	    {
+	      /* In case of a singlebyte character.  */
+	      pstr->mbs[byte_idx]
+		= toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]);
+	      /* The next step uses the assumption that wchar_t is encoded
+		 ASCII-safe: all ASCII values can be converted like this.  */
+	      pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx];
+	      ++byte_idx;
+	      continue;
+	    }
+
+	  remain_len = end_idx - byte_idx;
+	  prev_st = pstr->cur_state;
+	  mbclen = __mbrtowc (&wc,
+			      ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx
+			       + byte_idx), remain_len, &pstr->cur_state);
+	  if (BE (mbclen < (size_t) -2, 1))
+	    {
+	      wchar_t wcu = wc;
+	      if (iswlower (wc))
+		{
+		  size_t mbcdlen;
+
+		  wcu = towupper (wc);
+		  mbcdlen = wcrtomb (buf, wcu, &prev_st);
+		  if (BE (mbclen == mbcdlen, 1))
+		    memcpy (pstr->mbs + byte_idx, buf, mbclen);
+		  else
+		    {
+		      src_idx = byte_idx;
+		      goto offsets_needed;
+		    }
+		}
+	      else
+		memcpy (pstr->mbs + byte_idx,
+			pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen);
+	      pstr->wcs[byte_idx++] = wcu;
+	      /* Write paddings.  */
+	      for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+		pstr->wcs[byte_idx++] = WEOF;
+	    }
+	  else if (mbclen == (size_t) -1 || mbclen == 0)
+	    {
+	      /* It is an invalid character or '\0'.  Just use the byte.  */
+	      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx];
+	      pstr->mbs[byte_idx] = ch;
+	      /* And also cast it to wide char.  */
+	      pstr->wcs[byte_idx++] = (wchar_t) ch;
+	      if (BE (mbclen == (size_t) -1, 0))
+		pstr->cur_state = prev_st;
+	    }
+	  else
+	    {
+	      /* The buffer doesn't have enough space, finish to build.  */
+	      pstr->cur_state = prev_st;
+	      break;
+	    }
+	}
+      pstr->valid_len = byte_idx;
+      pstr->valid_raw_len = byte_idx;
+      return REG_NOERROR;
+    }
+  else
+    for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;)
+      {
+	wchar_t wc;
+	const char *p;
+      offsets_needed:
+	remain_len = end_idx - byte_idx;
+	prev_st = pstr->cur_state;
+	if (BE (pstr->trans != NULL, 0))
+	  {
+	    int i, ch;
+
+	    for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i)
+	      {
+		ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i];
+		buf[i] = pstr->trans[ch];
+	      }
+	    p = (const char *) buf;
+	  }
+	else
+	  p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx;
+	mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state);
+	if (BE (mbclen < (size_t) -2, 1))
+	  {
+	    wchar_t wcu = wc;
+	    if (iswlower (wc))
+	      {
+		size_t mbcdlen;
+
+		wcu = towupper (wc);
+		mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st);
+		if (BE (mbclen == mbcdlen, 1))
+		  memcpy (pstr->mbs + byte_idx, buf, mbclen);
+		else if (mbcdlen != (size_t) -1)
+		  {
+		    size_t i;
+
+		    if (byte_idx + mbcdlen > pstr->bufs_len)
+		      {
+			pstr->cur_state = prev_st;
+			break;
+		      }
+
+		    if (pstr->offsets == NULL)
+		      {
+			pstr->offsets = re_malloc (Idx, pstr->bufs_len);
+
+			if (pstr->offsets == NULL)
+			  return REG_ESPACE;
+		      }
+		    if (!pstr->offsets_needed)
+		      {
+			for (i = 0; i < (size_t) byte_idx; ++i)
+			  pstr->offsets[i] = i;
+			pstr->offsets_needed = 1;
+		      }
+
+		    memcpy (pstr->mbs + byte_idx, buf, mbcdlen);
+		    pstr->wcs[byte_idx] = wcu;
+		    pstr->offsets[byte_idx] = src_idx;
+		    for (i = 1; i < mbcdlen; ++i)
+		      {
+			pstr->offsets[byte_idx + i]
+			  = src_idx + (i < mbclen ? i : mbclen - 1);
+			pstr->wcs[byte_idx + i] = WEOF;
+		      }
+		    pstr->len += mbcdlen - mbclen;
+		    if (pstr->raw_stop > src_idx)
+		      pstr->stop += mbcdlen - mbclen;
+		    end_idx = (pstr->bufs_len > pstr->len)
+			      ? pstr->len : pstr->bufs_len;
+		    byte_idx += mbcdlen;
+		    src_idx += mbclen;
+		    continue;
+		  }
+		else
+		  memcpy (pstr->mbs + byte_idx, p, mbclen);
+	      }
+	    else
+	      memcpy (pstr->mbs + byte_idx, p, mbclen);
+
+	    if (BE (pstr->offsets_needed != 0, 0))
+	      {
+		size_t i;
+		for (i = 0; i < mbclen; ++i)
+		  pstr->offsets[byte_idx + i] = src_idx + i;
+	      }
+	    src_idx += mbclen;
+
+	    pstr->wcs[byte_idx++] = wcu;
+	    /* Write paddings.  */
+	    for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;)
+	      pstr->wcs[byte_idx++] = WEOF;
+	  }
+	else if (mbclen == (size_t) -1 || mbclen == 0)
+	  {
+	    /* It is an invalid character or '\0'.  Just use the byte.  */
+	    int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx];
+
+	    if (BE (pstr->trans != NULL, 0))
+	      ch = pstr->trans [ch];
+	    pstr->mbs[byte_idx] = ch;
+
+	    if (BE (pstr->offsets_needed != 0, 0))
+	      pstr->offsets[byte_idx] = src_idx;
+	    ++src_idx;
+
+	    /* And also cast it to wide char.  */
+	    pstr->wcs[byte_idx++] = (wchar_t) ch;
+	    if (BE (mbclen == (size_t) -1, 0))
+	      pstr->cur_state = prev_st;
+	  }
+	else
+	  {
+	    /* The buffer doesn't have enough space, finish to build.  */
+	    pstr->cur_state = prev_st;
+	    break;
+	  }
+      }
+  pstr->valid_len = byte_idx;
+  pstr->valid_raw_len = src_idx;
+  return REG_NOERROR;
+}
+
+/* Skip characters until the index becomes greater than NEW_RAW_IDX.
+   Return the index.  */
+
+static Idx
+internal_function
+re_string_skip_chars (re_string_t *pstr, Idx new_raw_idx, wint_t *last_wc)
+{
+  mbstate_t prev_st;
+  Idx rawbuf_idx;
+  size_t mbclen;
+  wint_t wc = WEOF;
+
+  /* Skip the characters which are not necessary to check.  */
+  for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len;
+       rawbuf_idx < new_raw_idx;)
+    {
+      wchar_t wc2;
+      Idx remain_len;
+      remain_len = pstr->len - rawbuf_idx;
+      prev_st = pstr->cur_state;
+      mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx,
+			  remain_len, &pstr->cur_state);
+      if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0))
+	{
+	  /* We treat these cases as a single byte character.  */
+	  if (mbclen == 0 || remain_len == 0)
+	    wc = L'\0';
+	  else
+	    wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx);
+	  mbclen = 1;
+	  pstr->cur_state = prev_st;
+	}
+      else
+	wc = wc2;
+      /* Then proceed the next character.  */
+      rawbuf_idx += mbclen;
+    }
+  *last_wc = wc;
+  return rawbuf_idx;
+}
+#endif /* RE_ENABLE_I18N  */
+
+/* Build the buffer PSTR->MBS, and apply the translation if we need.
+   This function is used in case of REG_ICASE.  */
+
+static void
+internal_function
+build_upper_buffer (re_string_t *pstr)
+{
+  Idx char_idx, end_idx;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx)
+    {
+      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
+      if (BE (pstr->trans != NULL, 0))
+	ch = pstr->trans[ch];
+      if (islower (ch))
+	pstr->mbs[char_idx] = toupper (ch);
+      else
+	pstr->mbs[char_idx] = ch;
+    }
+  pstr->valid_len = char_idx;
+  pstr->valid_raw_len = char_idx;
+}
+
+/* Apply TRANS to the buffer in PSTR.  */
+
+static void
+internal_function
+re_string_translate_buffer (re_string_t *pstr)
+{
+  Idx buf_idx, end_idx;
+  end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+  for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx)
+    {
+      int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
+      pstr->mbs[buf_idx] = pstr->trans[ch];
+    }
+
+  pstr->valid_len = buf_idx;
+  pstr->valid_raw_len = buf_idx;
+}
+
+/* This function re-construct the buffers.
+   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+   convert to upper case in case of REG_ICASE, apply translation.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_string_reconstruct (re_string_t *pstr, Idx idx, int eflags)
+{
+  Idx offset;
+
+  if (BE (pstr->raw_mbs_idx <= idx, 0))
+    offset = idx - pstr->raw_mbs_idx;
+  else
+    {
+      /* Reset buffer.  */
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+	memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+#endif /* RE_ENABLE_I18N */
+      pstr->len = pstr->raw_len;
+      pstr->stop = pstr->raw_stop;
+      pstr->valid_len = 0;
+      pstr->raw_mbs_idx = 0;
+      pstr->valid_raw_len = 0;
+      pstr->offsets_needed = 0;
+      pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
+      if (!pstr->mbs_allocated)
+	pstr->mbs = (unsigned char *) pstr->raw_mbs;
+      offset = idx;
+    }
+
+  if (BE (offset != 0, 1))
+    {
+      /* Should the already checked characters be kept?  */
+      if (BE (offset < pstr->valid_raw_len, 1))
+	{
+	  /* Yes, move them to the front of the buffer.  */
+#ifdef RE_ENABLE_I18N
+	  if (BE (pstr->offsets_needed, 0))
+	    {
+	      Idx low = 0, high = pstr->valid_len, mid;
+	      do
+		{
+		  mid = (high + low) / 2;
+		  if (pstr->offsets[mid] > offset)
+		    high = mid;
+		  else if (pstr->offsets[mid] < offset)
+		    low = mid + 1;
+		  else
+		    break;
+		}
+	      while (low < high);
+	      if (pstr->offsets[mid] < offset)
+		++mid;
+	      pstr->tip_context = re_string_context_at (pstr, mid - 1,
+							eflags);
+	      /* This can be quite complicated, so handle specially
+		 only the common and easy case where the character with
+		 different length representation of lower and upper
+		 case is present at or after offset.  */
+	      if (pstr->valid_len > offset
+		  && mid == offset && pstr->offsets[mid] == offset)
+		{
+		  memmove (pstr->wcs, pstr->wcs + offset,
+			   (pstr->valid_len - offset) * sizeof (wint_t));
+		  memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset);
+		  pstr->valid_len -= offset;
+		  pstr->valid_raw_len -= offset;
+		  for (low = 0; low < pstr->valid_len; low++)
+		    pstr->offsets[low] = pstr->offsets[low + offset] - offset;
+		}
+	      else
+		{
+		  /* Otherwise, just find out how long the partial multibyte
+		     character at offset is and fill it with WEOF/255.  */
+		  pstr->len = pstr->raw_len - idx + offset;
+		  pstr->stop = pstr->raw_stop - idx + offset;
+		  pstr->offsets_needed = 0;
+		  while (mid > 0 && pstr->offsets[mid - 1] == offset)
+		    --mid;
+		  while (mid < pstr->valid_len)
+		    if (pstr->wcs[mid] != WEOF)
+		      break;
+		    else
+		      ++mid;
+		  if (mid == pstr->valid_len)
+		    pstr->valid_len = 0;
+		  else
+		    {
+		      pstr->valid_len = pstr->offsets[mid] - offset;
+		      if (pstr->valid_len)
+			{
+			  for (low = 0; low < pstr->valid_len; ++low)
+			    pstr->wcs[low] = WEOF;
+			  memset (pstr->mbs, 255, pstr->valid_len);
+			}
+		    }
+		  pstr->valid_raw_len = pstr->valid_len;
+		}
+	    }
+	  else
+#endif
+	    {
+	      pstr->tip_context = re_string_context_at (pstr, offset - 1,
+							eflags);
+#ifdef RE_ENABLE_I18N
+	      if (pstr->mb_cur_max > 1)
+		memmove (pstr->wcs, pstr->wcs + offset,
+			 (pstr->valid_len - offset) * sizeof (wint_t));
+#endif /* RE_ENABLE_I18N */
+	      if (BE (pstr->mbs_allocated, 0))
+		memmove (pstr->mbs, pstr->mbs + offset,
+			 pstr->valid_len - offset);
+	      pstr->valid_len -= offset;
+	      pstr->valid_raw_len -= offset;
+#if DEBUG
+	      assert (pstr->valid_len > 0);
+#endif
+	    }
+	}
+      else
+	{
+#ifdef RE_ENABLE_I18N
+	  /* No, skip all characters until IDX.  */
+	  Idx prev_valid_len = pstr->valid_len;
+
+	  if (BE (pstr->offsets_needed, 0))
+	    {
+	      pstr->len = pstr->raw_len - idx + offset;
+	      pstr->stop = pstr->raw_stop - idx + offset;
+	      pstr->offsets_needed = 0;
+	    }
+#endif
+	  pstr->valid_len = 0;
+#ifdef RE_ENABLE_I18N
+	  if (pstr->mb_cur_max > 1)
+	    {
+	      Idx wcs_idx;
+	      wint_t wc = WEOF;
+
+	      if (pstr->is_utf8)
+		{
+		  const unsigned char *raw, *p, *end;
+
+		  /* Special case UTF-8.  Multi-byte chars start with any
+		     byte other than 0x80 - 0xbf.  */
+		  raw = pstr->raw_mbs + pstr->raw_mbs_idx;
+		  end = raw + (offset - pstr->mb_cur_max);
+		  if (end < pstr->raw_mbs)
+		    end = pstr->raw_mbs;
+		  p = raw + offset - 1;
+#ifdef _LIBC
+		  /* We know the wchar_t encoding is UCS4, so for the simple
+		     case, ASCII characters, skip the conversion step.  */
+		  if (isascii (*p) && BE (pstr->trans == NULL, 1))
+		    {
+		      memset (&pstr->cur_state, '\0', sizeof (mbstate_t));
+		      /* pstr->valid_len = 0; */
+		      wc = (wchar_t) *p;
+		    }
+		  else
+#endif
+		    for (; p >= end; --p)
+		      if ((*p & 0xc0) != 0x80)
+			{
+			  mbstate_t cur_state;
+			  wchar_t wc2;
+			  Idx mlen = raw + pstr->len - p;
+			  size_t mbclen;
+
+#if 0 /* dead code: buf is set but never used */
+			  unsigned char buf[6];
+			  if (BE (pstr->trans != NULL, 0))
+			    {
+			      int i = mlen < 6 ? mlen : 6;
+			      while (--i >= 0)
+				buf[i] = pstr->trans[p[i]];
+			    }
+#endif
+			  /* XXX Don't use mbrtowc, we know which conversion
+			     to use (UTF-8 -> UCS4).  */
+			  memset (&cur_state, 0, sizeof (cur_state));
+			  mbclen = __mbrtowc (&wc2, (const char *) p, mlen,
+					      &cur_state);
+			  if (raw + offset - p <= mbclen
+			      && mbclen < (size_t) -2)
+			    {
+			      memset (&pstr->cur_state, '\0',
+				      sizeof (mbstate_t));
+			      pstr->valid_len = mbclen - (raw + offset - p);
+			      wc = wc2;
+			    }
+			  break;
+			}
+		}
+
+	      if (wc == WEOF)
+		pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx;
+	      if (wc == WEOF)
+		pstr->tip_context
+		  = re_string_context_at (pstr, prev_valid_len - 1, eflags);
+	      else
+		pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0)
+				      && IS_WIDE_WORD_CHAR (wc))
+				     ? CONTEXT_WORD
+				     : ((IS_WIDE_NEWLINE (wc)
+					 && pstr->newline_anchor)
+					? CONTEXT_NEWLINE : 0));
+	      if (BE (pstr->valid_len, 0))
+		{
+		  for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx)
+		    pstr->wcs[wcs_idx] = WEOF;
+		  if (pstr->mbs_allocated)
+		    memset (pstr->mbs, 255, pstr->valid_len);
+		}
+	      pstr->valid_raw_len = pstr->valid_len;
+	    }
+	  else
+#endif /* RE_ENABLE_I18N */
+	    {
+	      int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+	      pstr->valid_raw_len = 0;
+	      if (pstr->trans)
+		c = pstr->trans[c];
+	      pstr->tip_context = (bitset_contain (pstr->word_char, c)
+				   ? CONTEXT_WORD
+				   : ((IS_NEWLINE (c) && pstr->newline_anchor)
+				      ? CONTEXT_NEWLINE : 0));
+	    }
+	}
+      if (!BE (pstr->mbs_allocated, 0))
+	pstr->mbs += offset;
+    }
+  pstr->raw_mbs_idx = idx;
+  pstr->len -= offset;
+  pstr->stop -= offset;
+
+  /* Then build the buffers.  */
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1)
+    {
+      if (pstr->icase)
+	{
+	  reg_errcode_t ret = build_wcs_upper_buffer (pstr);
+	  if (BE (ret != REG_NOERROR, 0))
+	    return ret;
+	}
+      else
+	build_wcs_buffer (pstr);
+    }
+  else
+#endif /* RE_ENABLE_I18N */
+    if (BE (pstr->mbs_allocated, 0))
+      {
+	if (pstr->icase)
+	  build_upper_buffer (pstr);
+	else if (pstr->trans != NULL)
+	  re_string_translate_buffer (pstr);
+      }
+    else
+      pstr->valid_len = pstr->len;
+
+  pstr->cur_idx = 0;
+  return REG_NOERROR;
+}
+
+static unsigned char
+internal_function __attribute ((pure))
+re_string_peek_byte_case (const re_string_t *pstr, Idx idx)
+{
+  int ch;
+  Idx off;
+
+  /* Handle the common (easiest) cases first.  */
+  if (BE (!pstr->mbs_allocated, 1))
+    return re_string_peek_byte (pstr, idx);
+
+#ifdef RE_ENABLE_I18N
+  if (pstr->mb_cur_max > 1
+      && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx))
+    return re_string_peek_byte (pstr, idx);
+#endif
+
+  off = pstr->cur_idx + idx;
+#ifdef RE_ENABLE_I18N
+  if (pstr->offsets_needed)
+    off = pstr->offsets[off];
+#endif
+
+  ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+#ifdef RE_ENABLE_I18N
+  /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I
+     this function returns CAPITAL LETTER I instead of first byte of
+     DOTLESS SMALL LETTER I.  The latter would confuse the parser,
+     since peek_byte_case doesn't advance cur_idx in any way.  */
+  if (pstr->offsets_needed && !isascii (ch))
+    return re_string_peek_byte (pstr, idx);
+#endif
+
+  return ch;
+}
+
+static unsigned char
+internal_function __attribute ((pure))
+re_string_fetch_byte_case (re_string_t *pstr)
+{
+  if (BE (!pstr->mbs_allocated, 1))
+    return re_string_fetch_byte (pstr);
+
+#ifdef RE_ENABLE_I18N
+  if (pstr->offsets_needed)
+    {
+      Idx off;
+      int ch;
+
+      /* For tr_TR.UTF-8 [[:islower:]] there is
+	 [[: CAPITAL LETTER I WITH DOT lower:]] in mbs.  Skip
+	 in that case the whole multi-byte character and return
+	 the original letter.  On the other side, with
+	 [[: DOTLESS SMALL LETTER I return [[:I, as doing
+	 anything else would complicate things too much.  */
+
+      if (!re_string_first_byte (pstr, pstr->cur_idx))
+	return re_string_fetch_byte (pstr);
+
+      off = pstr->offsets[pstr->cur_idx];
+      ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+      if (! isascii (ch))
+	return re_string_fetch_byte (pstr);
+
+      re_string_skip_bytes (pstr,
+			    re_string_char_size_at (pstr, pstr->cur_idx));
+      return ch;
+    }
+#endif
+
+  return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
+}
+
+static void
+internal_function
+re_string_destruct (re_string_t *pstr)
+{
+#ifdef RE_ENABLE_I18N
+  re_free (pstr->wcs);
+  re_free (pstr->offsets);
+#endif /* RE_ENABLE_I18N  */
+  if (pstr->mbs_allocated)
+    re_free (pstr->mbs);
+}
+
+/* Return the context at IDX in INPUT.  */
+
+static unsigned int
+internal_function
+re_string_context_at (const re_string_t *input, Idx idx, int eflags)
+{
+  int c;
+  if (BE (! REG_VALID_INDEX (idx), 0))
+    /* In this case, we use the value stored in input->tip_context,
+       since we can't know the character in input->mbs[-1] here.  */
+    return input->tip_context;
+  if (BE (idx == input->len, 0))
+    return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+	    : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+#ifdef RE_ENABLE_I18N
+  if (input->mb_cur_max > 1)
+    {
+      wint_t wc;
+      Idx wc_idx = idx;
+      while(input->wcs[wc_idx] == WEOF)
+	{
+#ifdef DEBUG
+	  /* It must not happen.  */
+	  assert (REG_VALID_INDEX (wc_idx));
+#endif
+	  --wc_idx;
+	  if (! REG_VALID_INDEX (wc_idx))
+	    return input->tip_context;
+	}
+      wc = input->wcs[wc_idx];
+      if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc))
+	return CONTEXT_WORD;
+      return (IS_WIDE_NEWLINE (wc) && input->newline_anchor
+	      ? CONTEXT_NEWLINE : 0);
+    }
+  else
+#endif
+    {
+      c = re_string_byte_at (input, idx);
+      if (bitset_contain (input->word_char, c))
+	return CONTEXT_WORD;
+      return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
+    }
+}
+

+/* Functions for set operation.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_alloc (re_node_set *set, Idx size)
+{
+  set->alloc = size;
+  set->nelem = 0;
+  set->elems = re_malloc (Idx, size);
+  if (BE (set->elems == NULL, 0))
+    return REG_ESPACE;
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_1 (re_node_set *set, Idx elem)
+{
+  set->alloc = 1;
+  set->nelem = 1;
+  set->elems = re_malloc (Idx, 1);
+  if (BE (set->elems == NULL, 0))
+    {
+      set->alloc = set->nelem = 0;
+      return REG_ESPACE;
+    }
+  set->elems[0] = elem;
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_2 (re_node_set *set, Idx elem1, Idx elem2)
+{
+  set->alloc = 2;
+  set->elems = re_malloc (Idx, 2);
+  if (BE (set->elems == NULL, 0))
+    return REG_ESPACE;
+  if (elem1 == elem2)
+    {
+      set->nelem = 1;
+      set->elems[0] = elem1;
+    }
+  else
+    {
+      set->nelem = 2;
+      if (elem1 < elem2)
+	{
+	  set->elems[0] = elem1;
+	  set->elems[1] = elem2;
+	}
+      else
+	{
+	  set->elems[0] = elem2;
+	  set->elems[1] = elem1;
+	}
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_copy (re_node_set *dest, const re_node_set *src)
+{
+  dest->nelem = src->nelem;
+  if (src->nelem > 0)
+    {
+      dest->alloc = dest->nelem;
+      dest->elems = re_malloc (Idx, dest->alloc);
+      if (BE (dest->elems == NULL, 0))
+	{
+	  dest->alloc = dest->nelem = 0;
+	  return REG_ESPACE;
+	}
+      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
+    }
+  else
+    re_node_set_init_empty (dest);
+  return REG_NOERROR;
+}
+
+/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
+   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1,
+			   const re_node_set *src2)
+{
+  Idx i1, i2, is, id, delta, sbase;
+  if (src1->nelem == 0 || src2->nelem == 0)
+    return REG_NOERROR;
+
+  /* We need dest->nelem + 2 * elems_in_intersection; this is a
+     conservative estimate.  */
+  if (src1->nelem + src2->nelem + dest->nelem > dest->alloc)
+    {
+      Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
+      Idx *new_elems = re_realloc (dest->elems, Idx, new_alloc);
+      if (BE (new_elems == NULL, 0))
+	return REG_ESPACE;
+      dest->elems = new_elems;
+      dest->alloc = new_alloc;
+    }
+
+  /* Find the items in the intersection of SRC1 and SRC2, and copy
+     into the top of DEST those that are not already in DEST itself.  */
+  sbase = dest->nelem + src1->nelem + src2->nelem;
+  i1 = src1->nelem - 1;
+  i2 = src2->nelem - 1;
+  id = dest->nelem - 1;
+  for (;;)
+    {
+      if (src1->elems[i1] == src2->elems[i2])
+	{
+	  /* Try to find the item in DEST.  Maybe we could binary search?  */
+	  while (REG_VALID_INDEX (id) && dest->elems[id] > src1->elems[i1])
+	    --id;
+
+          if (! REG_VALID_INDEX (id) || dest->elems[id] != src1->elems[i1])
+            dest->elems[--sbase] = src1->elems[i1];
+
+	  if (! REG_VALID_INDEX (--i1) || ! REG_VALID_INDEX (--i2))
+	    break;
+	}
+
+      /* Lower the highest of the two items.  */
+      else if (src1->elems[i1] < src2->elems[i2])
+	{
+	  if (! REG_VALID_INDEX (--i2))
+	    break;
+	}
+      else
+	{
+	  if (! REG_VALID_INDEX (--i1))
+	    break;
+	}
+    }
+
+  id = dest->nelem - 1;
+  is = dest->nelem + src1->nelem + src2->nelem - 1;
+  delta = is - sbase + 1;
+
+  /* Now copy.  When DELTA becomes zero, the remaining
+     DEST elements are already in place; this is more or
+     less the same loop that is in re_node_set_merge.  */
+  dest->nelem += delta;
+  if (delta > 0 && REG_VALID_INDEX (id))
+    for (;;)
+      {
+	if (dest->elems[is] > dest->elems[id])
+	  {
+	    /* Copy from the top.  */
+	    dest->elems[id + delta--] = dest->elems[is--];
+	    if (delta == 0)
+	      break;
+	  }
+	else
+	  {
+	    /* Slide from the bottom.  */
+	    dest->elems[id + delta] = dest->elems[id];
+	    if (! REG_VALID_INDEX (--id))
+	      break;
+	  }
+      }
+
+  /* Copy remaining SRC elements.  */
+  memcpy (dest->elems, dest->elems + sbase, delta * sizeof (Idx));
+
+  return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets SRC1 and SRC2. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_init_union (re_node_set *dest, const re_node_set *src1,
+			const re_node_set *src2)
+{
+  Idx i1, i2, id;
+  if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0)
+    {
+      dest->alloc = src1->nelem + src2->nelem;
+      dest->elems = re_malloc (Idx, dest->alloc);
+      if (BE (dest->elems == NULL, 0))
+	return REG_ESPACE;
+    }
+  else
+    {
+      if (src1 != NULL && src1->nelem > 0)
+	return re_node_set_init_copy (dest, src1);
+      else if (src2 != NULL && src2->nelem > 0)
+	return re_node_set_init_copy (dest, src2);
+      else
+	re_node_set_init_empty (dest);
+      return REG_NOERROR;
+    }
+  for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;)
+    {
+      if (src1->elems[i1] > src2->elems[i2])
+	{
+	  dest->elems[id++] = src2->elems[i2++];
+	  continue;
+	}
+      if (src1->elems[i1] == src2->elems[i2])
+	++i2;
+      dest->elems[id++] = src1->elems[i1++];
+    }
+  if (i1 < src1->nelem)
+    {
+      memcpy (dest->elems + id, src1->elems + i1,
+	     (src1->nelem - i1) * sizeof (Idx));
+      id += src1->nelem - i1;
+    }
+  else if (i2 < src2->nelem)
+    {
+      memcpy (dest->elems + id, src2->elems + i2,
+	     (src2->nelem - i2) * sizeof (Idx));
+      id += src2->nelem - i2;
+    }
+  dest->nelem = id;
+  return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets DEST and SRC. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_node_set_merge (re_node_set *dest, const re_node_set *src)
+{
+  Idx is, id, sbase, delta;
+  if (src == NULL || src->nelem == 0)
+    return REG_NOERROR;
+  if (dest->alloc < 2 * src->nelem + dest->nelem)
+    {
+      Idx new_alloc = 2 * (src->nelem + dest->alloc);
+      Idx *new_buffer = re_realloc (dest->elems, Idx, new_alloc);
+      if (BE (new_buffer == NULL, 0))
+	return REG_ESPACE;
+      dest->elems = new_buffer;
+      dest->alloc = new_alloc;
+    }
+
+  if (BE (dest->nelem == 0, 0))
+    {
+      dest->nelem = src->nelem;
+      memcpy (dest->elems, src->elems, src->nelem * sizeof (Idx));
+      return REG_NOERROR;
+    }
+
+  /* Copy into the top of DEST the items of SRC that are not
+     found in DEST.  Maybe we could binary search in DEST?  */
+  for (sbase = dest->nelem + 2 * src->nelem,
+       is = src->nelem - 1, id = dest->nelem - 1;
+       REG_VALID_INDEX (is) && REG_VALID_INDEX (id); )
+    {
+      if (dest->elems[id] == src->elems[is])
+	is--, id--;
+      else if (dest->elems[id] < src->elems[is])
+	dest->elems[--sbase] = src->elems[is--];
+      else /* if (dest->elems[id] > src->elems[is]) */
+	--id;
+    }
+
+  if (REG_VALID_INDEX (is))
+    {
+      /* If DEST is exhausted, the remaining items of SRC must be unique.  */
+      sbase -= is + 1;
+      memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (Idx));
+    }
+
+  id = dest->nelem - 1;
+  is = dest->nelem + 2 * src->nelem - 1;
+  delta = is - sbase + 1;
+  if (delta == 0)
+    return REG_NOERROR;
+
+  /* Now copy.  When DELTA becomes zero, the remaining
+     DEST elements are already in place.  */
+  dest->nelem += delta;
+  for (;;)
+    {
+      if (dest->elems[is] > dest->elems[id])
+	{
+	  /* Copy from the top.  */
+	  dest->elems[id + delta--] = dest->elems[is--];
+	  if (delta == 0)
+	    break;
+	}
+      else
+	{
+	  /* Slide from the bottom.  */
+	  dest->elems[id + delta] = dest->elems[id];
+	  if (! REG_VALID_INDEX (--id))
+	    {
+	      /* Copy remaining SRC elements.  */
+	      memcpy (dest->elems, dest->elems + sbase,
+		      delta * sizeof (Idx));
+	      break;
+	    }
+	}
+    }
+
+  return REG_NOERROR;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have ELEM.
+   Return true if successful.  */
+
+static bool
+internal_function __attribute_warn_unused_result__
+re_node_set_insert (re_node_set *set, Idx elem)
+{
+  Idx idx;
+  /* In case the set is empty.  */
+  if (set->alloc == 0)
+    return BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1);
+
+  if (BE (set->nelem, 0) == 0)
+    {
+      /* We already guaranteed above that set->alloc != 0.  */
+      set->elems[0] = elem;
+      ++set->nelem;
+      return true;
+    }
+
+  /* Realloc if we need.  */
+  if (set->alloc == set->nelem)
+    {
+      Idx *new_elems;
+      set->alloc = set->alloc * 2;
+      new_elems = re_realloc (set->elems, Idx, set->alloc);
+      if (BE (new_elems == NULL, 0))
+	return false;
+      set->elems = new_elems;
+    }
+
+  /* Move the elements which follows the new element.  Test the
+     first element separately to skip a check in the inner loop.  */
+  if (elem < set->elems[0])
+    {
+      idx = 0;
+      for (idx = set->nelem; idx > 0; idx--)
+	set->elems[idx] = set->elems[idx - 1];
+    }
+  else
+    {
+      for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
+	set->elems[idx] = set->elems[idx - 1];
+    }
+
+  /* Insert the new element.  */
+  set->elems[idx] = elem;
+  ++set->nelem;
+  return true;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have any element greater than or equal to ELEM.
+   Return true if successful.  */
+
+static bool
+internal_function __attribute_warn_unused_result__
+re_node_set_insert_last (re_node_set *set, Idx elem)
+{
+  /* Realloc if we need.  */
+  if (set->alloc == set->nelem)
+    {
+      Idx *new_elems;
+      set->alloc = (set->alloc + 1) * 2;
+      new_elems = re_realloc (set->elems, Idx, set->alloc);
+      if (BE (new_elems == NULL, 0))
+	return false;
+      set->elems = new_elems;
+    }
+
+  /* Insert the new element.  */
+  set->elems[set->nelem++] = elem;
+  return true;
+}
+
+/* Compare two node sets SET1 and SET2.
+   Return true if SET1 and SET2 are equivalent.  */
+
+static bool
+internal_function __attribute ((pure))
+re_node_set_compare (const re_node_set *set1, const re_node_set *set2)
+{
+  Idx i;
+  if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
+    return false;
+  for (i = set1->nelem ; REG_VALID_INDEX (--i) ; )
+    if (set1->elems[i] != set2->elems[i])
+      return false;
+  return true;
+}
+
+/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
+
+static Idx
+internal_function __attribute ((pure))
+re_node_set_contains (const re_node_set *set, Idx elem)
+{
+  __re_size_t idx, right, mid;
+  if (! REG_VALID_NONZERO_INDEX (set->nelem))
+    return 0;
+
+  /* Binary search the element.  */
+  idx = 0;
+  right = set->nelem - 1;
+  while (idx < right)
+    {
+      mid = (idx + right) / 2;
+      if (set->elems[mid] < elem)
+	idx = mid + 1;
+      else
+	right = mid;
+    }
+  return set->elems[idx] == elem ? idx + 1 : 0;
+}
+
+static void
+internal_function
+re_node_set_remove_at (re_node_set *set, Idx idx)
+{
+  if (idx < 0 || idx >= set->nelem)
+    return;
+  --set->nelem;
+  for (; idx < set->nelem; idx++)
+    set->elems[idx] = set->elems[idx + 1];
+}
+

+
+/* Add the token TOKEN to dfa->nodes, and return the index of the token.
+   Or return REG_MISSING if an error occurred.  */
+
+static Idx
+internal_function
+re_dfa_add_node (re_dfa_t *dfa, re_token_t token)
+{
+  if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0))
+    {
+      size_t new_nodes_alloc = dfa->nodes_alloc * 2;
+      Idx *new_nexts, *new_indices;
+      re_node_set *new_edests, *new_eclosures;
+      re_token_t *new_nodes;
+      size_t max_object_size =
+	MAX (sizeof (re_token_t),
+	     MAX (sizeof (re_node_set),
+		  sizeof (Idx)));
+
+      /* Avoid overflows.  */
+      if (BE (SIZE_MAX / 2 / max_object_size < dfa->nodes_alloc, 0))
+	return REG_MISSING;
+
+      new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc);
+      if (BE (new_nodes == NULL, 0))
+	return REG_MISSING;
+      dfa->nodes = new_nodes;
+      new_nexts = re_realloc (dfa->nexts, Idx, new_nodes_alloc);
+      new_indices = re_realloc (dfa->org_indices, Idx, new_nodes_alloc);
+      new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc);
+      new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc);
+      if (BE (new_nexts == NULL || new_indices == NULL
+	      || new_edests == NULL || new_eclosures == NULL, 0))
+	return REG_MISSING;
+      dfa->nexts = new_nexts;
+      dfa->org_indices = new_indices;
+      dfa->edests = new_edests;
+      dfa->eclosures = new_eclosures;
+      dfa->nodes_alloc = new_nodes_alloc;
+    }
+  dfa->nodes[dfa->nodes_len] = token;
+  dfa->nodes[dfa->nodes_len].constraint = 0;
+#ifdef RE_ENABLE_I18N
+  {
+  int type = token.type;
+  dfa->nodes[dfa->nodes_len].accept_mb =
+    (type == OP_PERIOD && dfa->mb_cur_max > 1) || type == COMPLEX_BRACKET;
+  }
+#endif
+  dfa->nexts[dfa->nodes_len] = REG_MISSING;
+  re_node_set_init_empty (dfa->edests + dfa->nodes_len);
+  re_node_set_init_empty (dfa->eclosures + dfa->nodes_len);
+  return dfa->nodes_len++;
+}
+
+static inline re_hashval_t
+internal_function
+calc_state_hash (const re_node_set *nodes, unsigned int context)
+{
+  re_hashval_t hash = nodes->nelem + context;
+  Idx i;
+  for (i = 0 ; i < nodes->nelem ; i++)
+    hash += nodes->elems[i];
+  return hash;
+}
+
+/* Search for the state whose node_set is equivalent to NODES.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+	   return value is NULL and ERR is REG_NOERROR.
+	 - We never return non-NULL value in case of any errors, it is for
+	   optimization.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa,
+		  const re_node_set *nodes)
+{
+  re_hashval_t hash;
+  re_dfastate_t *new_state;
+  struct re_state_table_entry *spot;
+  Idx i;
+#ifdef lint
+  /* Suppress bogus uninitialized-variable warnings.  */
+  *err = REG_NOERROR;
+#endif
+  if (BE (nodes->nelem == 0, 0))
+    {
+      *err = REG_NOERROR;
+      return NULL;
+    }
+  hash = calc_state_hash (nodes, 0);
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+  for (i = 0 ; i < spot->num ; i++)
+    {
+      re_dfastate_t *state = spot->array[i];
+      if (hash != state->hash)
+	continue;
+      if (re_node_set_compare (&state->nodes, nodes))
+	return state;
+    }
+
+  /* There are no appropriate state in the dfa, create the new one.  */
+  new_state = create_ci_newstate (dfa, nodes, hash);
+  if (BE (new_state == NULL, 0))
+    *err = REG_ESPACE;
+
+  return new_state;
+}
+
+/* Search for the state whose node_set is equivalent to NODES and
+   whose context is equivalent to CONTEXT.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+	   return value is NULL and ERR is REG_NOERROR.
+	 - We never return non-NULL value in case of any errors, it is for
+	   optimization.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa,
+			  const re_node_set *nodes, unsigned int context)
+{
+  re_hashval_t hash;
+  re_dfastate_t *new_state;
+  struct re_state_table_entry *spot;
+  Idx i;
+#ifdef lint
+  /* Suppress bogus uninitialized-variable warnings.  */
+  *err = REG_NOERROR;
+#endif
+  if (nodes->nelem == 0)
+    {
+      *err = REG_NOERROR;
+      return NULL;
+    }
+  hash = calc_state_hash (nodes, context);
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+  for (i = 0 ; i < spot->num ; i++)
+    {
+      re_dfastate_t *state = spot->array[i];
+      if (state->hash == hash
+	  && state->context == context
+	  && re_node_set_compare (state->entrance_nodes, nodes))
+	return state;
+    }
+  /* There are no appropriate state in `dfa', create the new one.  */
+  new_state = create_cd_newstate (dfa, nodes, context, hash);
+  if (BE (new_state == NULL, 0))
+    *err = REG_ESPACE;
+
+  return new_state;
+}
+
+/* Finish initialization of the new state NEWSTATE, and using its hash value
+   HASH put in the appropriate bucket of DFA's state table.  Return value
+   indicates the error code if failed.  */
+
+static reg_errcode_t
+__attribute_warn_unused_result__
+register_state (const re_dfa_t *dfa, re_dfastate_t *newstate,
+		re_hashval_t hash)
+{
+  struct re_state_table_entry *spot;
+  reg_errcode_t err;
+  Idx i;
+
+  newstate->hash = hash;
+  err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem);
+  if (BE (err != REG_NOERROR, 0))
+    return REG_ESPACE;
+  for (i = 0; i < newstate->nodes.nelem; i++)
+    {
+      Idx elem = newstate->nodes.elems[i];
+      if (!IS_EPSILON_NODE (dfa->nodes[elem].type))
+	if (BE (! re_node_set_insert_last (&newstate->non_eps_nodes, elem), 0))
+	  return REG_ESPACE;
+    }
+
+  spot = dfa->state_table + (hash & dfa->state_hash_mask);
+  if (BE (spot->alloc <= spot->num, 0))
+    {
+      Idx new_alloc = 2 * spot->num + 2;
+      re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *,
+					      new_alloc);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      spot->array = new_array;
+      spot->alloc = new_alloc;
+    }
+  spot->array[spot->num++] = newstate;
+  return REG_NOERROR;
+}
+
+static void
+free_state (re_dfastate_t *state)
+{
+  re_node_set_free (&state->non_eps_nodes);
+  re_node_set_free (&state->inveclosure);
+  if (state->entrance_nodes != &state->nodes)
+    {
+      re_node_set_free (state->entrance_nodes);
+      re_free (state->entrance_nodes);
+    }
+  re_node_set_free (&state->nodes);
+  re_free (state->word_trtable);
+  re_free (state->trtable);
+  re_free (state);
+}
+
+/* Create the new state which is independ of contexts.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
+		    re_hashval_t hash)
+{
+  Idx i;
+  reg_errcode_t err;
+  re_dfastate_t *newstate;
+
+  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  if (BE (newstate == NULL, 0))
+    return NULL;
+  err = re_node_set_init_copy (&newstate->nodes, nodes);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      re_free (newstate);
+      return NULL;
+    }
+
+  newstate->entrance_nodes = &newstate->nodes;
+  for (i = 0 ; i < nodes->nelem ; i++)
+    {
+      re_token_t *node = dfa->nodes + nodes->elems[i];
+      re_token_type_t type = node->type;
+      if (type == CHARACTER && !node->constraint)
+	continue;
+#ifdef RE_ENABLE_I18N
+      newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+      /* If the state has the halt node, the state is a halt state.  */
+      if (type == END_OF_RE)
+	newstate->halt = 1;
+      else if (type == OP_BACK_REF)
+	newstate->has_backref = 1;
+      else if (type == ANCHOR || node->constraint)
+	newstate->has_constraint = 1;
+    }
+  err = register_state (dfa, newstate, hash);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_state (newstate);
+      newstate = NULL;
+    }
+  return newstate;
+}
+
+/* Create the new state which is depend on the context CONTEXT.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes,
+		    unsigned int context, re_hashval_t hash)
+{
+  Idx i, nctx_nodes = 0;
+  reg_errcode_t err;
+  re_dfastate_t *newstate;
+
+  newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1);
+  if (BE (newstate == NULL, 0))
+    return NULL;
+  err = re_node_set_init_copy (&newstate->nodes, nodes);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      re_free (newstate);
+      return NULL;
+    }
+
+  newstate->context = context;
+  newstate->entrance_nodes = &newstate->nodes;
+
+  for (i = 0 ; i < nodes->nelem ; i++)
+    {
+      re_token_t *node = dfa->nodes + nodes->elems[i];
+      re_token_type_t type = node->type;
+      unsigned int constraint = node->constraint;
+
+      if (type == CHARACTER && !constraint)
+	continue;
+#ifdef RE_ENABLE_I18N
+      newstate->accept_mb |= node->accept_mb;
+#endif /* RE_ENABLE_I18N */
+
+      /* If the state has the halt node, the state is a halt state.  */
+      if (type == END_OF_RE)
+	newstate->halt = 1;
+      else if (type == OP_BACK_REF)
+	newstate->has_backref = 1;
+
+      if (constraint)
+	{
+	  if (newstate->entrance_nodes == &newstate->nodes)
+	    {
+	      newstate->entrance_nodes = re_malloc (re_node_set, 1);
+	      if (BE (newstate->entrance_nodes == NULL, 0))
+		{
+		  free_state (newstate);
+		  return NULL;
+		}
+	      if (re_node_set_init_copy (newstate->entrance_nodes, nodes)
+		  != REG_NOERROR)
+		return NULL;
+	      nctx_nodes = 0;
+	      newstate->has_constraint = 1;
+	    }
+
+	  if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context))
+	    {
+	      re_node_set_remove_at (&newstate->nodes, i - nctx_nodes);
+	      ++nctx_nodes;
+	    }
+	}
+    }
+  err = register_state (dfa, newstate, hash);
+  if (BE (err != REG_NOERROR, 0))
+    {
+      free_state (newstate);
+      newstate = NULL;
+    }
+  return  newstate;
+}
diff --git a/gl/regex_internal.h b/gl/regex_internal.h
new file mode 100644
index 0000000..f9b0d24
--- /dev/null
+++ b/gl/regex_internal.h
@@ -0,0 +1,870 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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. */
+
+#ifndef _REGEX_INTERNAL_H
+#define _REGEX_INTERNAL_H 1
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <langinfo.h>
+#ifndef _LIBC
+# include "localcharset.h"
+#endif
+#include <locale.h>
+
+#include <wchar.h>
+#include <wctype.h>
+#include <stdint.h>
+#if defined _LIBC
+# include <bits/libc-lock.h>
+#else
+# define __libc_lock_init(NAME) do { } while (0)
+# define __libc_lock_lock(NAME) do { } while (0)
+# define __libc_lock_unlock(NAME) do { } while (0)
+#endif
+
+/* In case that the system doesn't have isblank().  */
+#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
+# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
+#endif
+
+#ifdef _LIBC
+# ifndef _RE_DEFINE_LOCALE_FUNCTIONS
+#  define _RE_DEFINE_LOCALE_FUNCTIONS 1
+#   include <locale/localeinfo.h>
+#   include <locale/elem-hash.h>
+#   include <locale/coll-lookup.h>
+# endif
+#endif
+
+/* This is for other GNU distributions with internationalized messages.  */
+#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include <libintl.h>
+# ifdef _LIBC
+#  undef gettext
+#  define gettext(msgid) \
+  INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES)
+# endif
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+   strings.  */
+# define gettext_noop(String) String
+#endif
+
+/* For loser systems without the definition.  */
+#ifndef SIZE_MAX
+# define SIZE_MAX ((size_t) -1)
+#endif
+
+#if (defined MB_CUR_MAX && HAVE_WCTYPE_H && HAVE_ISWCTYPE && HAVE_WCSCOLL) || _LIBC
+# define RE_ENABLE_I18N
+#endif
+
+#if __GNUC__ >= 3
+# define BE(expr, val) __builtin_expect (expr, val)
+#else
+# define BE(expr, val) (expr)
+# ifdef _LIBC
+#  define inline
+# endif
+#endif
+
+/* Number of ASCII characters.  */
+#define ASCII_CHARS 0x80
+
+/* Number of single byte characters.  */
+#define SBC_MAX (UCHAR_MAX + 1)
+
+#define COLL_ELEM_LEN_MAX 8
+
+/* The character which represents newline.  */
+#define NEWLINE_CHAR '\n'
+#define WIDE_NEWLINE_CHAR L'\n'
+
+/* Rename to standard API for using out of glibc.  */
+#ifndef _LIBC
+# define __wctype wctype
+# define __iswctype iswctype
+# define __btowc btowc
+# define __wcrtomb wcrtomb
+# define __mbrtowc mbrtowc
+# define __regfree regfree
+# define attribute_hidden
+#endif /* not _LIBC */
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+# define __attribute(arg) __attribute__ (arg)
+#else
+# define __attribute(arg)
+#endif
+
+typedef __re_idx_t Idx;
+
+/* Special return value for failure to match.  */
+#define REG_MISSING ((Idx) -1)
+
+/* Special return value for internal error.  */
+#define REG_ERROR ((Idx) -2)
+
+/* Test whether N is a valid index, and is not one of the above.  */
+#ifdef _REGEX_LARGE_OFFSETS
+# define REG_VALID_INDEX(n) ((Idx) (n) < REG_ERROR)
+#else
+# define REG_VALID_INDEX(n) (0 <= (n))
+#endif
+
+/* Test whether N is a valid nonzero index.  */
+#ifdef _REGEX_LARGE_OFFSETS
+# define REG_VALID_NONZERO_INDEX(n) ((Idx) ((n) - 1) < (Idx) (REG_ERROR - 1))
+#else
+# define REG_VALID_NONZERO_INDEX(n) (0 < (n))
+#endif
+
+/* A hash value, suitable for computing hash tables.  */
+typedef __re_size_t re_hashval_t;
+
+/* An integer used to represent a set of bits.  It must be unsigned,
+   and must be at least as wide as unsigned int.  */
+typedef unsigned long int bitset_word_t;
+/* All bits set in a bitset_word_t.  */
+#define BITSET_WORD_MAX ULONG_MAX
+
+/* Number of bits in a bitset_word_t.  For portability to hosts with
+   padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)';
+   instead, deduce it directly from BITSET_WORD_MAX.  Avoid
+   greater-than-32-bit integers and unconditional shifts by more than
+   31 bits, as they're not portable.  */
+#if BITSET_WORD_MAX == 0xffffffffUL
+# define BITSET_WORD_BITS 32
+#elif BITSET_WORD_MAX >> 31 >> 4 == 1
+# define BITSET_WORD_BITS 36
+#elif BITSET_WORD_MAX >> 31 >> 16 == 1
+# define BITSET_WORD_BITS 48
+#elif BITSET_WORD_MAX >> 31 >> 28 == 1
+# define BITSET_WORD_BITS 60
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1
+# define BITSET_WORD_BITS 64
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1
+# define BITSET_WORD_BITS 72
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1
+# define BITSET_WORD_BITS 128
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1
+# define BITSET_WORD_BITS 256
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1
+# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */
+# if BITSET_WORD_BITS <= SBC_MAX
+#  error "Invalid SBC_MAX"
+# endif
+#else
+# error "Add case for new bitset_word_t size"
+#endif
+
+/* Number of bitset_word_t values in a bitset_t.  */
+#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
+
+typedef bitset_word_t bitset_t[BITSET_WORDS];
+typedef bitset_word_t *re_bitset_ptr_t;
+typedef const bitset_word_t *re_const_bitset_ptr_t;
+
+#define PREV_WORD_CONSTRAINT 0x0001
+#define PREV_NOTWORD_CONSTRAINT 0x0002
+#define NEXT_WORD_CONSTRAINT 0x0004
+#define NEXT_NOTWORD_CONSTRAINT 0x0008
+#define PREV_NEWLINE_CONSTRAINT 0x0010
+#define NEXT_NEWLINE_CONSTRAINT 0x0020
+#define PREV_BEGBUF_CONSTRAINT 0x0040
+#define NEXT_ENDBUF_CONSTRAINT 0x0080
+#define WORD_DELIM_CONSTRAINT 0x0100
+#define NOT_WORD_DELIM_CONSTRAINT 0x0200
+
+typedef enum
+{
+  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
+  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
+  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
+  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
+  WORD_DELIM = WORD_DELIM_CONSTRAINT,
+  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
+} re_context_type;
+
+typedef struct
+{
+  Idx alloc;
+  Idx nelem;
+  Idx *elems;
+} re_node_set;
+
+typedef enum
+{
+  NON_TYPE = 0,
+
+  /* Node type, These are used by token, node, tree.  */
+  CHARACTER = 1,
+  END_OF_RE = 2,
+  SIMPLE_BRACKET = 3,
+  OP_BACK_REF = 4,
+  OP_PERIOD = 5,
+#ifdef RE_ENABLE_I18N
+  COMPLEX_BRACKET = 6,
+  OP_UTF8_PERIOD = 7,
+#endif /* RE_ENABLE_I18N */
+
+  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
+     when the debugger shows values of this enum type.  */
+#define EPSILON_BIT 8
+  OP_OPEN_SUBEXP = EPSILON_BIT | 0,
+  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
+  OP_ALT = EPSILON_BIT | 2,
+  OP_DUP_ASTERISK = EPSILON_BIT | 3,
+  ANCHOR = EPSILON_BIT | 4,
+
+  /* Tree type, these are used only by tree. */
+  CONCAT = 16,
+  SUBEXP = 17,
+
+  /* Token type, these are used only by token.  */
+  OP_DUP_PLUS = 18,
+  OP_DUP_QUESTION,
+  OP_OPEN_BRACKET,
+  OP_CLOSE_BRACKET,
+  OP_CHARSET_RANGE,
+  OP_OPEN_DUP_NUM,
+  OP_CLOSE_DUP_NUM,
+  OP_NON_MATCH_LIST,
+  OP_OPEN_COLL_ELEM,
+  OP_CLOSE_COLL_ELEM,
+  OP_OPEN_EQUIV_CLASS,
+  OP_CLOSE_EQUIV_CLASS,
+  OP_OPEN_CHAR_CLASS,
+  OP_CLOSE_CHAR_CLASS,
+  OP_WORD,
+  OP_NOTWORD,
+  OP_SPACE,
+  OP_NOTSPACE,
+  BACK_SLASH
+
+} re_token_type_t;
+
+#ifdef RE_ENABLE_I18N
+typedef struct
+{
+  /* Multibyte characters.  */
+  wchar_t *mbchars;
+
+  /* Collating symbols.  */
+# ifdef _LIBC
+  int32_t *coll_syms;
+# endif
+
+  /* Equivalence classes. */
+# ifdef _LIBC
+  int32_t *equiv_classes;
+# endif
+
+  /* Range expressions. */
+# ifdef _LIBC
+  uint32_t *range_starts;
+  uint32_t *range_ends;
+# else /* not _LIBC */
+  wchar_t *range_starts;
+  wchar_t *range_ends;
+# endif /* not _LIBC */
+
+  /* Character classes. */
+  wctype_t *char_classes;
+
+  /* If this character set is the non-matching list.  */
+  unsigned int non_match : 1;
+
+  /* # of multibyte characters.  */
+  Idx nmbchars;
+
+  /* # of collating symbols.  */
+  Idx ncoll_syms;
+
+  /* # of equivalence classes. */
+  Idx nequiv_classes;
+
+  /* # of range expressions. */
+  Idx nranges;
+
+  /* # of character classes. */
+  Idx nchar_classes;
+} re_charset_t;
+#endif /* RE_ENABLE_I18N */
+
+typedef struct
+{
+  union
+  {
+    unsigned char c;		/* for CHARACTER */
+    re_bitset_ptr_t sbcset;	/* for SIMPLE_BRACKET */
+#ifdef RE_ENABLE_I18N
+    re_charset_t *mbcset;	/* for COMPLEX_BRACKET */
+#endif /* RE_ENABLE_I18N */
+    Idx idx;			/* for BACK_REF */
+    re_context_type ctx_type;	/* for ANCHOR */
+  } opr;
+#if __GNUC__ >= 2 && !__STRICT_ANSI__
+  re_token_type_t type : 8;
+#else
+  re_token_type_t type;
+#endif
+  unsigned int constraint : 10;	/* context constraint */
+  unsigned int duplicated : 1;
+  unsigned int opt_subexp : 1;
+#ifdef RE_ENABLE_I18N
+  unsigned int accept_mb : 1;
+  /* These 2 bits can be moved into the union if needed (e.g. if running out
+     of bits; move opr.c to opr.c.c and move the flags to opr.c.flags).  */
+  unsigned int mb_partial : 1;
+#endif
+  unsigned int word_char : 1;
+} re_token_t;
+
+#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
+
+struct re_string_t
+{
+  /* Indicate the raw buffer which is the original string passed as an
+     argument of regexec(), re_search(), etc..  */
+  const unsigned char *raw_mbs;
+  /* Store the multibyte string.  In case of "case insensitive mode" like
+     REG_ICASE, upper cases of the string are stored, otherwise MBS points
+     the same address that RAW_MBS points.  */
+  unsigned char *mbs;
+#ifdef RE_ENABLE_I18N
+  /* Store the wide character string which is corresponding to MBS.  */
+  wint_t *wcs;
+  Idx *offsets;
+  mbstate_t cur_state;
+#endif
+  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
+     raw_mbs[raw_mbs_idx + i].  */
+  Idx raw_mbs_idx;
+  /* The length of the valid characters in the buffers.  */
+  Idx valid_len;
+  /* The corresponding number of bytes in raw_mbs array.  */
+  Idx valid_raw_len;
+  /* The length of the buffers MBS and WCS.  */
+  Idx bufs_len;
+  /* The index in MBS, which is updated by re_string_fetch_byte.  */
+  Idx cur_idx;
+  /* length of RAW_MBS array.  */
+  Idx raw_len;
+  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */
+  Idx len;
+  /* End of the buffer may be shorter than its length in the cases such
+     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
+     instead of LEN.  */
+  Idx raw_stop;
+  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */
+  Idx stop;
+
+  /* The context of mbs[0].  We store the context independently, since
+     the context of mbs[0] may be different from raw_mbs[0], which is
+     the beginning of the input string.  */
+  unsigned int tip_context;
+  /* The translation passed as a part of an argument of re_compile_pattern.  */
+  RE_TRANSLATE_TYPE trans;
+  /* Copy of re_dfa_t's word_char.  */
+  re_const_bitset_ptr_t word_char;
+  /* true if REG_ICASE.  */
+  unsigned char icase;
+  unsigned char is_utf8;
+  unsigned char map_notascii;
+  unsigned char mbs_allocated;
+  unsigned char offsets_needed;
+  unsigned char newline_anchor;
+  unsigned char word_ops_used;
+  int mb_cur_max;
+};
+typedef struct re_string_t re_string_t;
+
+
+struct re_dfa_t;
+typedef struct re_dfa_t re_dfa_t;
+
+#ifndef _LIBC
+# if defined __i386__ && !defined __EMX__
+#  define internal_function   __attribute ((regparm (3), stdcall))
+# else
+#  define internal_function
+# endif
+#endif
+
+static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr,
+						Idx new_buf_len)
+     internal_function;
+#ifdef RE_ENABLE_I18N
+static void build_wcs_buffer (re_string_t *pstr) internal_function;
+static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static void build_upper_buffer (re_string_t *pstr) internal_function;
+static void re_string_translate_buffer (re_string_t *pstr) internal_function;
+static unsigned int re_string_context_at (const re_string_t *input, Idx idx,
+					  int eflags)
+     internal_function __attribute ((pure));
+#define re_string_peek_byte(pstr, offset) \
+  ((pstr)->mbs[(pstr)->cur_idx + offset])
+#define re_string_fetch_byte(pstr) \
+  ((pstr)->mbs[(pstr)->cur_idx++])
+#define re_string_first_byte(pstr, idx) \
+  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
+#define re_string_is_single_byte_char(pstr, idx) \
+  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
+				|| (pstr)->wcs[(idx) + 1] != WEOF))
+#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
+#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
+#define re_string_get_buffer(pstr) ((pstr)->mbs)
+#define re_string_length(pstr) ((pstr)->len)
+#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
+#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
+#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
+
+#include <alloca.h>
+
+#ifndef _LIBC
+# if HAVE_ALLOCA
+/* The OS usually guarantees 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
+   allocate anything larger than 4096 bytes.  Also care for the possibility
+   of a few compiler-allocated temporary stack slots.  */
+#  define __libc_use_alloca(n) ((n) < 4032)
+# else
+/* alloca is implemented with malloc, so just use malloc.  */
+#  define __libc_use_alloca(n) 0
+#  undef alloca
+#  define alloca(n) malloc (n)
+# endif
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+
+#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
+#define re_free(p) free (p)
+
+struct bin_tree_t
+{
+  struct bin_tree_t *parent;
+  struct bin_tree_t *left;
+  struct bin_tree_t *right;
+  struct bin_tree_t *first;
+  struct bin_tree_t *next;
+
+  re_token_t token;
+
+  /* `node_idx' is the index in dfa->nodes, if `type' == 0.
+     Otherwise `type' indicate the type of this node.  */
+  Idx node_idx;
+};
+typedef struct bin_tree_t bin_tree_t;
+
+#define BIN_TREE_STORAGE_SIZE \
+  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))
+
+struct bin_tree_storage_t
+{
+  struct bin_tree_storage_t *next;
+  bin_tree_t data[BIN_TREE_STORAGE_SIZE];
+};
+typedef struct bin_tree_storage_t bin_tree_storage_t;
+
+#define CONTEXT_WORD 1
+#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
+#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
+#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
+
+#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
+#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
+#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
+#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
+#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
+
+#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
+#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
+#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_')
+#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
+
+#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
+ ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
+  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
+
+#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
+ ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
+  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
+
+struct re_dfastate_t
+{
+  re_hashval_t hash;
+  re_node_set nodes;
+  re_node_set non_eps_nodes;
+  re_node_set inveclosure;
+  re_node_set *entrance_nodes;
+  struct re_dfastate_t **trtable, **word_trtable;
+  unsigned int context : 4;
+  unsigned int halt : 1;
+  /* If this state can accept `multi byte'.
+     Note that we refer to multibyte characters, and multi character
+     collating elements as `multi byte'.  */
+  unsigned int accept_mb : 1;
+  /* If this state has backreference node(s).  */
+  unsigned int has_backref : 1;
+  unsigned int has_constraint : 1;
+};
+typedef struct re_dfastate_t re_dfastate_t;
+
+struct re_state_table_entry
+{
+  Idx num;
+  Idx alloc;
+  re_dfastate_t **array;
+};
+
+/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */
+
+typedef struct
+{
+  Idx next_idx;
+  Idx alloc;
+  re_dfastate_t **array;
+} state_array_t;
+
+/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */
+
+typedef struct
+{
+  Idx node;
+  Idx str_idx; /* The position NODE match at.  */
+  state_array_t path;
+} re_sub_match_last_t;
+
+/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
+   And information about the node, whose type is OP_CLOSE_SUBEXP,
+   corresponding to NODE is stored in LASTS.  */
+
+typedef struct
+{
+  Idx str_idx;
+  Idx node;
+  state_array_t *path;
+  Idx alasts; /* Allocation size of LASTS.  */
+  Idx nlasts; /* The number of LASTS.  */
+  re_sub_match_last_t **lasts;
+} re_sub_match_top_t;
+
+struct re_backref_cache_entry
+{
+  Idx node;
+  Idx str_idx;
+  Idx subexp_from;
+  Idx subexp_to;
+  char more;
+  char unused;
+  unsigned short int eps_reachable_subexps_map;
+};
+
+typedef struct
+{
+  /* The string object corresponding to the input string.  */
+  re_string_t input;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+  const re_dfa_t *const dfa;
+#else
+  const re_dfa_t *dfa;
+#endif
+  /* EFLAGS of the argument of regexec.  */
+  int eflags;
+  /* Where the matching ends.  */
+  Idx match_last;
+  Idx last_node;
+  /* The state log used by the matcher.  */
+  re_dfastate_t **state_log;
+  Idx state_log_top;
+  /* Back reference cache.  */
+  Idx nbkref_ents;
+  Idx abkref_ents;
+  struct re_backref_cache_entry *bkref_ents;
+  int max_mb_elem_len;
+  Idx nsub_tops;
+  Idx asub_tops;
+  re_sub_match_top_t **sub_tops;
+} re_match_context_t;
+
+typedef struct
+{
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **limited_states;
+  Idx last_node;
+  Idx last_str_idx;
+  re_node_set limits;
+} re_sift_context_t;
+
+struct re_fail_stack_ent_t
+{
+  Idx idx;
+  Idx node;
+  regmatch_t *regs;
+  re_node_set eps_via_nodes;
+};
+
+struct re_fail_stack_t
+{
+  Idx num;
+  Idx alloc;
+  struct re_fail_stack_ent_t *stack;
+};
+
+struct re_dfa_t
+{
+  re_token_t *nodes;
+  size_t nodes_alloc;
+  size_t nodes_len;
+  Idx *nexts;
+  Idx *org_indices;
+  re_node_set *edests;
+  re_node_set *eclosures;
+  re_node_set *inveclosures;
+  struct re_state_table_entry *state_table;
+  re_dfastate_t *init_state;
+  re_dfastate_t *init_state_word;
+  re_dfastate_t *init_state_nl;
+  re_dfastate_t *init_state_begbuf;
+  bin_tree_t *str_tree;
+  bin_tree_storage_t *str_tree_storage;
+  re_bitset_ptr_t sb_char;
+  int str_tree_storage_idx;
+
+  /* number of subexpressions `re_nsub' is in regex_t.  */
+  re_hashval_t state_hash_mask;
+  Idx init_node;
+  Idx nbackref; /* The number of backreference in this dfa.  */
+
+  /* Bitmap expressing which backreference is used.  */
+  bitset_word_t used_bkref_map;
+  bitset_word_t completed_bkref_map;
+
+  unsigned int has_plural_match : 1;
+  /* If this dfa has "multibyte node", which is a backreference or
+     a node which can accept multibyte character or multi character
+     collating element.  */
+  unsigned int has_mb_node : 1;
+  unsigned int is_utf8 : 1;
+  unsigned int map_notascii : 1;
+  unsigned int word_ops_used : 1;
+  int mb_cur_max;
+  bitset_t word_char;
+  reg_syntax_t syntax;
+  Idx *subexp_map;
+#ifdef DEBUG
+  char* re_str;
+#endif
+#ifdef _LIBC
+  __libc_lock_define (, lock)
+#endif
+};
+
+#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+#define re_node_set_remove(set,id) \
+  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+#define re_node_set_empty(p) ((p)->nelem = 0)
+#define re_node_set_free(set) re_free ((set)->elems)
+

+
+typedef enum
+{
+  SB_CHAR,
+  MB_CHAR,
+  EQUIV_CLASS,
+  COLL_SYM,
+  CHAR_CLASS
+} bracket_elem_type;
+
+typedef struct
+{
+  bracket_elem_type type;
+  union
+  {
+    unsigned char ch;
+    unsigned char *name;
+    wchar_t wch;
+  } opr;
+} bracket_elem_t;
+
+
+/* Inline functions for bitset_t operation.  */
+
+static inline void
+bitset_set (bitset_t set, Idx i)
+{
+  set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
+}
+
+static inline void
+bitset_clear (bitset_t set, Idx i)
+{
+  set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
+}
+
+static inline bool
+bitset_contain (const bitset_t set, Idx i)
+{
+  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
+}
+
+static inline void
+bitset_empty (bitset_t set)
+{
+  memset (set, '\0', sizeof (bitset_t));
+}
+
+static inline void
+bitset_set_all (bitset_t set)
+{
+  memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
+  if (SBC_MAX % BITSET_WORD_BITS != 0)
+    set[BITSET_WORDS - 1] =
+      ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
+}
+
+static inline void
+bitset_copy (bitset_t dest, const bitset_t src)
+{
+  memcpy (dest, src, sizeof (bitset_t));
+}
+
+static inline void
+bitset_not (bitset_t set)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)
+    set[bitset_i] = ~set[bitset_i];
+  if (SBC_MAX % BITSET_WORD_BITS != 0)
+    set[BITSET_WORDS - 1] =
+      ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)
+       & ~set[BITSET_WORDS - 1]);
+}
+
+static inline void
+bitset_merge (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] |= src[bitset_i];
+}
+
+static inline void
+bitset_mask (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] &= src[bitset_i];
+}
+
+#ifdef RE_ENABLE_I18N
+/* Inline functions for re_string.  */
+static inline int
+internal_function __attribute ((pure))
+re_string_char_size_at (const re_string_t *pstr, Idx idx)
+{
+  int byte_idx;
+  if (pstr->mb_cur_max == 1)
+    return 1;
+  for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx)
+    if (pstr->wcs[idx + byte_idx] != WEOF)
+      break;
+  return byte_idx;
+}
+
+static inline wint_t
+internal_function __attribute ((pure))
+re_string_wchar_at (const re_string_t *pstr, Idx idx)
+{
+  if (pstr->mb_cur_max == 1)
+    return (wint_t) pstr->mbs[idx];
+  return (wint_t) pstr->wcs[idx];
+}
+
+static int
+internal_function __attribute ((pure))
+re_string_elem_size_at (const re_string_t *pstr, Idx idx)
+{
+# ifdef _LIBC
+  const unsigned char *p, *extra;
+  const int32_t *table, *indirect;
+  int32_t tmp;
+#  include <locale/weight.h>
+  uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+
+  if (nrules != 0)
+    {
+      table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+      extra = (const unsigned char *)
+	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+      indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE,
+						_NL_COLLATE_INDIRECTMB);
+      p = pstr->mbs + idx;
+      tmp = findidx (&p);
+      return p - pstr->mbs - idx;
+    }
+  else
+# endif /* _LIBC */
+    return 1;
+}
+#endif /* RE_ENABLE_I18N */
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#if __GNUC_PREREQ (3,4)
+# undef __attribute_warn_unused_result__
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+
+#endif /*  _REGEX_INTERNAL_H */
diff --git a/gl/regexec.c b/gl/regexec.c
new file mode 100644
index 0000000..c54bf65
--- /dev/null
+++ b/gl/regexec.c
@@ -0,0 +1,4417 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2011 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu at yamato.ibm.com>.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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. */
+
+static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags,
+				     Idx n) internal_function;
+static void match_ctx_clean (re_match_context_t *mctx) internal_function;
+static void match_ctx_free (re_match_context_t *cache) internal_function;
+static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, Idx node,
+					  Idx str_idx, Idx from, Idx to)
+     internal_function;
+static Idx search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
+     internal_function;
+static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, Idx node,
+					   Idx str_idx) internal_function;
+static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop,
+						    Idx node, Idx str_idx)
+     internal_function;
+static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+			   re_dfastate_t **limited_sts, Idx last_node,
+			   Idx last_str_idx)
+     internal_function;
+static reg_errcode_t re_search_internal (const regex_t *preg,
+					 const char *string, Idx length,
+					 Idx start, Idx last_start, Idx stop,
+					 size_t nmatch, regmatch_t pmatch[],
+					 int eflags) internal_function;
+static regoff_t re_search_2_stub (struct re_pattern_buffer *bufp,
+				  const char *string1, Idx length1,
+				  const char *string2, Idx length2,
+				  Idx start, regoff_t range,
+				  struct re_registers *regs,
+				  Idx stop, bool ret_len) internal_function;
+static regoff_t re_search_stub (struct re_pattern_buffer *bufp,
+				const char *string, Idx length, Idx start,
+				regoff_t range, Idx stop,
+				struct re_registers *regs,
+				bool ret_len) internal_function;
+static unsigned int re_copy_regs (struct re_registers *regs, regmatch_t *pmatch,
+				  Idx nregs, int regs_allocated)
+     internal_function;
+static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx)
+     internal_function;
+static Idx check_matching (re_match_context_t *mctx, bool fl_longest_match,
+			   Idx *p_match_first) internal_function;
+static Idx check_halt_state_context (const re_match_context_t *mctx,
+				     const re_dfastate_t *state, Idx idx)
+     internal_function;
+static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+			 regmatch_t *prev_idx_match, Idx cur_node,
+			 Idx cur_idx, Idx nmatch) internal_function;
+static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs,
+				      Idx str_idx, Idx dest_node, Idx nregs,
+				      regmatch_t *regs,
+				      re_node_set *eps_via_nodes)
+     internal_function;
+static reg_errcode_t set_regs (const regex_t *preg,
+			       const re_match_context_t *mctx,
+			       size_t nmatch, regmatch_t *pmatch,
+			       bool fl_backtrack) internal_function;
+static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs)
+     internal_function;
+
+#ifdef RE_ENABLE_I18N
+static int sift_states_iter_mb (const re_match_context_t *mctx,
+				re_sift_context_t *sctx,
+				Idx node_idx, Idx str_idx, Idx max_str_idx)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t sift_states_backward (const re_match_context_t *mctx,
+					   re_sift_context_t *sctx)
+     internal_function;
+static reg_errcode_t build_sifted_states (const re_match_context_t *mctx,
+					  re_sift_context_t *sctx, Idx str_idx,
+					  re_node_set *cur_dest)
+     internal_function;
+static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx,
+					      re_sift_context_t *sctx,
+					      Idx str_idx,
+					      re_node_set *dest_nodes)
+     internal_function;
+static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa,
+					    re_node_set *dest_nodes,
+					    const re_node_set *candidates)
+     internal_function;
+static bool check_dst_limits (const re_match_context_t *mctx,
+			      const re_node_set *limits,
+			      Idx dst_node, Idx dst_idx, Idx src_node,
+			      Idx src_idx) internal_function;
+static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx,
+					int boundaries, Idx subexp_idx,
+					Idx from_node, Idx bkref_idx)
+     internal_function;
+static int check_dst_limits_calc_pos (const re_match_context_t *mctx,
+				      Idx limit, Idx subexp_idx,
+				      Idx node, Idx str_idx,
+				      Idx bkref_idx) internal_function;
+static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa,
+					  re_node_set *dest_nodes,
+					  const re_node_set *candidates,
+					  re_node_set *limits,
+					  struct re_backref_cache_entry *bkref_ents,
+					  Idx str_idx) internal_function;
+static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx,
+					re_sift_context_t *sctx,
+					Idx str_idx, const re_node_set *candidates)
+     internal_function;
+static reg_errcode_t merge_state_array (const re_dfa_t *dfa,
+					re_dfastate_t **dst,
+					re_dfastate_t **src, Idx num)
+     internal_function;
+static re_dfastate_t *find_recover_state (reg_errcode_t *err,
+					 re_match_context_t *mctx) internal_function;
+static re_dfastate_t *transit_state (reg_errcode_t *err,
+				     re_match_context_t *mctx,
+				     re_dfastate_t *state) internal_function;
+static re_dfastate_t *merge_state_with_log (reg_errcode_t *err,
+					    re_match_context_t *mctx,
+					    re_dfastate_t *next_state)
+     internal_function;
+static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx,
+						re_node_set *cur_nodes,
+						Idx str_idx) internal_function;
+#if 0
+static re_dfastate_t *transit_state_sb (reg_errcode_t *err,
+					re_match_context_t *mctx,
+					re_dfastate_t *pstate)
+     internal_function;
+#endif
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t transit_state_mb (re_match_context_t *mctx,
+				       re_dfastate_t *pstate)
+     internal_function;
+#endif /* RE_ENABLE_I18N */
+static reg_errcode_t transit_state_bkref (re_match_context_t *mctx,
+					  const re_node_set *nodes)
+     internal_function;
+static reg_errcode_t get_subexp (re_match_context_t *mctx,
+				 Idx bkref_node, Idx bkref_str_idx)
+     internal_function;
+static reg_errcode_t get_subexp_sub (re_match_context_t *mctx,
+				     const re_sub_match_top_t *sub_top,
+				     re_sub_match_last_t *sub_last,
+				     Idx bkref_node, Idx bkref_str)
+     internal_function;
+static Idx find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+			     Idx subexp_idx, int type) internal_function;
+static reg_errcode_t check_arrival (re_match_context_t *mctx,
+				    state_array_t *path, Idx top_node,
+				    Idx top_str, Idx last_node, Idx last_str,
+				    int type) internal_function;
+static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx,
+						   Idx str_idx,
+						   re_node_set *cur_nodes,
+						   re_node_set *next_nodes)
+     internal_function;
+static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa,
+					       re_node_set *cur_nodes,
+					       Idx ex_subexp, int type)
+     internal_function;
+static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa,
+						   re_node_set *dst_nodes,
+						   Idx target, Idx ex_subexp,
+						   int type) internal_function;
+static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx,
+					 re_node_set *cur_nodes, Idx cur_str,
+					 Idx subexp_num, int type)
+     internal_function;
+static bool build_trtable (const re_dfa_t *dfa,
+			   re_dfastate_t *state) internal_function;
+#ifdef RE_ENABLE_I18N
+static int check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
+				    const re_string_t *input, Idx idx)
+     internal_function;
+# ifdef _LIBC
+static unsigned int find_collation_sequence_value (const unsigned char *mbs,
+						   size_t name_len)
+     internal_function;
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+static Idx group_nodes_into_DFAstates (const re_dfa_t *dfa,
+				       const re_dfastate_t *state,
+				       re_node_set *states_node,
+				       bitset_t *states_ch) internal_function;
+static bool check_node_accept (const re_match_context_t *mctx,
+			       const re_token_t *node, Idx idx)
+     internal_function;
+static reg_errcode_t extend_buffers (re_match_context_t *mctx)
+     internal_function;
+

+/* Entry point for POSIX code.  */
+
+/* regexec searches for a given pattern, specified by PREG, in the
+   string STRING.
+
+   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+   `regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
+   least NMATCH elements, and we set them to the offsets of the
+   corresponding matched substrings.
+
+   EFLAGS specifies `execution flags' which affect matching: if
+   REG_NOTBOL is set, then ^ does not match at the beginning of the
+   string; if REG_NOTEOL is set, then $ does not match at the end.
+
+   We return 0 if we find a match and REG_NOMATCH if not.  */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+    const regex_t *_Restrict_ preg;
+    const char *_Restrict_ string;
+    size_t nmatch;
+    regmatch_t pmatch[_Restrict_arr_];
+    int eflags;
+{
+  reg_errcode_t err;
+  Idx start, length;
+#ifdef _LIBC
+  re_dfa_t *dfa = (re_dfa_t *) preg->buffer;
+#endif
+
+  if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
+    return REG_BADPAT;
+
+  if (eflags & REG_STARTEND)
+    {
+      start = pmatch[0].rm_so;
+      length = pmatch[0].rm_eo;
+    }
+  else
+    {
+      start = 0;
+      length = strlen (string);
+    }
+
+  __libc_lock_lock (dfa->lock);
+  if (preg->no_sub)
+    err = re_search_internal (preg, string, length, start, length,
+			      length, 0, NULL, eflags);
+  else
+    err = re_search_internal (preg, string, length, start, length,
+			      length, nmatch, pmatch, eflags);
+  __libc_lock_unlock (dfa->lock);
+  return err != REG_NOERROR;
+}
+
+#ifdef _LIBC
+# include <shlib-compat.h>
+versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4);
+
+# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
+__typeof__ (__regexec) __compat_regexec;
+
+int
+attribute_compat_text_section
+__compat_regexec (const regex_t *_Restrict_ preg,
+		  const char *_Restrict_ string, size_t nmatch,
+		  regmatch_t pmatch[], int eflags)
+{
+  return regexec (preg, string, nmatch, pmatch,
+		  eflags & (REG_NOTBOL | REG_NOTEOL));
+}
+compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0);
+# endif
+#endif
+
+/* Entry points for GNU code.  */
+
+/* re_match, re_search, re_match_2, re_search_2
+
+   The former two functions operate on STRING with length LENGTH,
+   while the later two operate on concatenation of STRING1 and STRING2
+   with lengths LENGTH1 and LENGTH2, respectively.
+
+   re_match() matches the compiled pattern in BUFP against the string,
+   starting at index START.
+
+   re_search() first tries matching at index START, then it tries to match
+   starting from index START + 1, and so on.  The last start position tried
+   is START + RANGE.  (Thus RANGE = 0 forces re_search to operate the same
+   way as re_match().)
+
+   The parameter STOP of re_{match,search}_2 specifies that no match exceeding
+   the first STOP characters of the concatenation of the strings should be
+   concerned.
+
+   If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match
+   and all groups is stored in REGS.  (For the "_2" variants, the offsets are
+   computed relative to the concatenation, not relative to the individual
+   strings.)
+
+   On success, re_match* functions return the length of the match, re_search*
+   return the position of the start of the match.  Return value -1 means no
+   match was found and -2 indicates an internal error.  */
+
+regoff_t
+re_match (bufp, string, length, start, regs)
+    struct re_pattern_buffer *bufp;
+    const char *string;
+    Idx length, start;
+    struct re_registers *regs;
+{
+  return re_search_stub (bufp, string, length, start, 0, length, regs, true);
+}
+#ifdef _LIBC
+weak_alias (__re_match, re_match)
+#endif
+
+regoff_t
+re_search (bufp, string, length, start, range, regs)
+    struct re_pattern_buffer *bufp;
+    const char *string;
+    Idx length, start;
+    regoff_t range;
+    struct re_registers *regs;
+{
+  return re_search_stub (bufp, string, length, start, range, length, regs,
+			 false);
+}
+#ifdef _LIBC
+weak_alias (__re_search, re_search)
+#endif
+
+regoff_t
+re_match_2 (bufp, string1, length1, string2, length2, start, regs, stop)
+    struct re_pattern_buffer *bufp;
+    const char *string1, *string2;
+    Idx length1, length2, start, stop;
+    struct re_registers *regs;
+{
+  return re_search_2_stub (bufp, string1, length1, string2, length2,
+			   start, 0, regs, stop, true);
+}
+#ifdef _LIBC
+weak_alias (__re_match_2, re_match_2)
+#endif
+
+regoff_t
+re_search_2 (bufp, string1, length1, string2, length2, start, range, regs, stop)
+    struct re_pattern_buffer *bufp;
+    const char *string1, *string2;
+    Idx length1, length2, start, stop;
+    regoff_t range;
+    struct re_registers *regs;
+{
+  return re_search_2_stub (bufp, string1, length1, string2, length2,
+			   start, range, regs, stop, false);
+}
+#ifdef _LIBC
+weak_alias (__re_search_2, re_search_2)
+#endif
+
+static regoff_t
+internal_function
+re_search_2_stub (struct re_pattern_buffer *bufp,
+		  const char *string1, Idx length1,
+		  const char *string2, Idx length2,
+		  Idx start, regoff_t range, struct re_registers *regs,
+		  Idx stop, bool ret_len)
+{
+  const char *str;
+  regoff_t rval;
+  Idx len = length1 + length2;
+  char *s = NULL;
+
+  if (BE (length1 < 0 || length2 < 0 || stop < 0 || len < length1, 0))
+    return -2;
+
+  /* Concatenate the strings.  */
+  if (length2 > 0)
+    if (length1 > 0)
+      {
+	s = re_malloc (char, len);
+
+	if (BE (s == NULL, 0))
+	  return -2;
+#ifdef _LIBC
+	memcpy (__mempcpy (s, string1, length1), string2, length2);
+#else
+	memcpy (s, string1, length1);
+	memcpy (s + length1, string2, length2);
+#endif
+	str = s;
+      }
+    else
+      str = string2;
+  else
+    str = string1;
+
+  rval = re_search_stub (bufp, str, len, start, range, stop, regs,
+			 ret_len);
+  re_free (s);
+  return rval;
+}
+
+/* The parameters have the same meaning as those of re_search.
+   Additional parameters:
+   If RET_LEN is true the length of the match is returned (re_match style);
+   otherwise the position of the match is returned.  */
+
+static regoff_t
+internal_function
+re_search_stub (struct re_pattern_buffer *bufp,
+		const char *string, Idx length,
+		Idx start, regoff_t range, Idx stop, struct re_registers *regs,
+		bool ret_len)
+{
+  reg_errcode_t result;
+  regmatch_t *pmatch;
+  Idx nregs;
+  regoff_t rval;
+  int eflags = 0;
+#ifdef _LIBC
+  re_dfa_t *dfa = (re_dfa_t *) bufp->buffer;
+#endif
+  Idx last_start = start + range;
+
+  /* Check for out-of-range.  */
+  if (BE (start < 0 || start > length, 0))
+    return -1;
+  if (BE (length < last_start || (0 <= range && last_start < start), 0))
+    last_start = length;
+  else if (BE (last_start < 0 || (range < 0 && start <= last_start), 0))
+    last_start = 0;
+
+  __libc_lock_lock (dfa->lock);
+
+  eflags |= (bufp->not_bol) ? REG_NOTBOL : 0;
+  eflags |= (bufp->not_eol) ? REG_NOTEOL : 0;
+
+  /* Compile fastmap if we haven't yet.  */
+  if (start < last_start && bufp->fastmap != NULL && !bufp->fastmap_accurate)
+    re_compile_fastmap (bufp);
+
+  if (BE (bufp->no_sub, 0))
+    regs = NULL;
+
+  /* We need at least 1 register.  */
+  if (regs == NULL)
+    nregs = 1;
+  else if (BE (bufp->regs_allocated == REGS_FIXED
+	       && regs->num_regs <= bufp->re_nsub, 0))
+    {
+      nregs = regs->num_regs;
+      if (BE (nregs < 1, 0))
+	{
+	  /* Nothing can be copied to regs.  */
+	  regs = NULL;
+	  nregs = 1;
+	}
+    }
+  else
+    nregs = bufp->re_nsub + 1;
+  pmatch = re_malloc (regmatch_t, nregs);
+  if (BE (pmatch == NULL, 0))
+    {
+      rval = -2;
+      goto out;
+    }
+
+  result = re_search_internal (bufp, string, length, start, last_start, stop,
+			       nregs, pmatch, eflags);
+
+  rval = 0;
+
+  /* I hope we needn't fill ther regs with -1's when no match was found.  */
+  if (result != REG_NOERROR)
+    rval = -1;
+  else if (regs != NULL)
+    {
+      /* If caller wants register contents data back, copy them.  */
+      bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs,
+					   bufp->regs_allocated);
+      if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0))
+	rval = -2;
+    }
+
+  if (BE (rval == 0, 1))
+    {
+      if (ret_len)
+	{
+	  assert (pmatch[0].rm_so == start);
+	  rval = pmatch[0].rm_eo - start;
+	}
+      else
+	rval = pmatch[0].rm_so;
+    }
+  re_free (pmatch);
+ out:
+  __libc_lock_unlock (dfa->lock);
+  return rval;
+}
+
+static unsigned int
+internal_function
+re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, Idx nregs,
+	      int regs_allocated)
+{
+  int rval = REGS_REALLOCATE;
+  Idx i;
+  Idx need_regs = nregs + 1;
+  /* We need one extra element beyond `num_regs' for the `-1' marker GNU code
+     uses.  */
+
+  /* Have the register data arrays been allocated?  */
+  if (regs_allocated == REGS_UNALLOCATED)
+    { /* No.  So allocate them with malloc.  */
+      regs->start = re_malloc (regoff_t, need_regs);
+      if (BE (regs->start == NULL, 0))
+	return REGS_UNALLOCATED;
+      regs->end = re_malloc (regoff_t, need_regs);
+      if (BE (regs->end == NULL, 0))
+	{
+	  re_free (regs->start);
+	  return REGS_UNALLOCATED;
+	}
+      regs->num_regs = need_regs;
+    }
+  else if (regs_allocated == REGS_REALLOCATE)
+    { /* Yes.  If we need more elements than were already
+	 allocated, reallocate them.  If we need fewer, just
+	 leave it alone.  */
+      if (BE (need_regs > regs->num_regs, 0))
+	{
+	  regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs);
+	  regoff_t *new_end;
+	  if (BE (new_start == NULL, 0))
+	    return REGS_UNALLOCATED;
+	  new_end = re_realloc (regs->end, regoff_t, need_regs);
+	  if (BE (new_end == NULL, 0))
+	    {
+	      re_free (new_start);
+	      return REGS_UNALLOCATED;
+	    }
+	  regs->start = new_start;
+	  regs->end = new_end;
+	  regs->num_regs = need_regs;
+	}
+    }
+  else
+    {
+      assert (regs_allocated == REGS_FIXED);
+      /* This function may not be called with REGS_FIXED and nregs too big.  */
+      assert (regs->num_regs >= nregs);
+      rval = REGS_FIXED;
+    }
+
+  /* Copy the regs.  */
+  for (i = 0; i < nregs; ++i)
+    {
+      regs->start[i] = pmatch[i].rm_so;
+      regs->end[i] = pmatch[i].rm_eo;
+    }
+  for ( ; i < regs->num_regs; ++i)
+    regs->start[i] = regs->end[i] = -1;
+
+  return rval;
+}
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using PATTERN_BUFFER and REGS will use
+   this memory for recording register information.  STARTS and ENDS
+   must be allocated using the malloc library routine, and must each
+   be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   PATTERN_BUFFER will allocate its own register data, without
+   freeing the old data.  */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+    struct re_pattern_buffer *bufp;
+    struct re_registers *regs;
+    __re_size_t num_regs;
+    regoff_t *starts, *ends;
+{
+  if (num_regs)
+    {
+      bufp->regs_allocated = REGS_REALLOCATE;
+      regs->num_regs = num_regs;
+      regs->start = starts;
+      regs->end = ends;
+    }
+  else
+    {
+      bufp->regs_allocated = REGS_UNALLOCATED;
+      regs->num_regs = 0;
+      regs->start = regs->end = NULL;
+    }
+}
+#ifdef _LIBC
+weak_alias (__re_set_registers, re_set_registers)
+#endif
+

+/* Entry points compatible with 4.2 BSD regex library.  We don't define
+   them unless specifically requested.  */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+int
+# ifdef _LIBC
+weak_function
+# endif
+re_exec (s)
+     const char *s;
+{
+  return 0 == regexec (&re_comp_buf, s, 0, NULL, 0);
+}
+#endif /* _REGEX_RE_COMP */
+

+/* Internal entry point.  */
+
+/* Searches for a compiled pattern PREG in the string STRING, whose
+   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
+   meaning as with regexec.  LAST_START is START + RANGE, where
+   START and RANGE have the same meaning as with re_search.
+   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
+   otherwise return the error code.
+   Note: We assume front end functions already check ranges.
+   (0 <= LAST_START && LAST_START <= LENGTH)  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+re_search_internal (const regex_t *preg,
+		    const char *string, Idx length,
+		    Idx start, Idx last_start, Idx stop,
+		    size_t nmatch, regmatch_t pmatch[],
+		    int eflags)
+{
+  reg_errcode_t err;
+  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
+  Idx left_lim, right_lim;
+  int incr;
+  bool fl_longest_match;
+  int match_kind;
+  Idx match_first;
+  Idx match_last = REG_MISSING;
+  Idx extra_nmatch;
+  bool sb;
+  int ch;
+#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
+  re_match_context_t mctx = { .dfa = dfa };
+#else
+  re_match_context_t mctx;
+#endif
+  char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
+		    && start != last_start && !preg->can_be_null)
+		   ? preg->fastmap : NULL);
+  RE_TRANSLATE_TYPE t = preg->translate;
+
+#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+  memset (&mctx, '\0', sizeof (re_match_context_t));
+  mctx.dfa = dfa;
+#endif
+
+  extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
+  nmatch -= extra_nmatch;
+
+  /* Check if the DFA haven't been compiled.  */
+  if (BE (preg->used == 0 || dfa->init_state == NULL
+	  || dfa->init_state_word == NULL || dfa->init_state_nl == NULL
+	  || dfa->init_state_begbuf == NULL, 0))
+    return REG_NOMATCH;
+
+#ifdef DEBUG
+  /* We assume front-end functions already check them.  */
+  assert (0 <= last_start && last_start <= length);
+#endif
+
+  /* If initial states with non-begbuf contexts have no elements,
+     the regex must be anchored.  If preg->newline_anchor is set,
+     we'll never use init_state_nl, so do not check it.  */
+  if (dfa->init_state->nodes.nelem == 0
+      && dfa->init_state_word->nodes.nelem == 0
+      && (dfa->init_state_nl->nodes.nelem == 0
+	  || !preg->newline_anchor))
+    {
+      if (start != 0 && last_start != 0)
+        return REG_NOMATCH;
+      start = last_start = 0;
+    }
+
+  /* We must check the longest matching, if nmatch > 0.  */
+  fl_longest_match = (nmatch != 0 || dfa->nbackref);
+
+  err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1,
+			    preg->translate, (preg->syntax & RE_ICASE) != 0,
+			    dfa);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+  mctx.input.stop = stop;
+  mctx.input.raw_stop = stop;
+  mctx.input.newline_anchor = preg->newline_anchor;
+
+  err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+
+  /* We will log all the DFA states through which the dfa pass,
+     if nmatch > 1, or this dfa has "multibyte node", which is a
+     back-reference or a node which can accept multibyte character or
+     multi character collating element.  */
+  if (nmatch > 1 || dfa->has_mb_node)
+    {
+      /* Avoid overflow.  */
+      if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0))
+	{
+	  err = REG_ESPACE;
+	  goto free_return;
+	}
+
+      mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1);
+      if (BE (mctx.state_log == NULL, 0))
+	{
+	  err = REG_ESPACE;
+	  goto free_return;
+	}
+    }
+  else
+    mctx.state_log = NULL;
+
+  match_first = start;
+  mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+			   : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
+
+  /* Check incrementally whether of not the input string match.  */
+  incr = (last_start < start) ? -1 : 1;
+  left_lim = (last_start < start) ? last_start : start;
+  right_lim = (last_start < start) ? start : last_start;
+  sb = dfa->mb_cur_max == 1;
+  match_kind =
+    (fastmap
+     ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+	| (start <= last_start ? 2 : 0)
+	| (t != NULL ? 1 : 0))
+     : 8);
+
+  for (;; match_first += incr)
+    {
+      err = REG_NOMATCH;
+      if (match_first < left_lim || right_lim < match_first)
+	goto free_return;
+
+      /* Advance as rapidly as possible through the string, until we
+	 find a plausible place to start matching.  This may be done
+	 with varying efficiency, so there are various possibilities:
+	 only the most common of them are specialized, in order to
+	 save on code size.  We use a switch statement for speed.  */
+      switch (match_kind)
+	{
+	case 8:
+	  /* No fastmap.  */
+	  break;
+
+	case 7:
+	  /* Fastmap with single-byte translation, match forward.  */
+	  while (BE (match_first < right_lim, 1)
+		 && !fastmap[t[(unsigned char) string[match_first]]])
+	    ++match_first;
+	  goto forward_match_found_start_or_reached_end;
+
+	case 6:
+	  /* Fastmap without translation, match forward.  */
+	  while (BE (match_first < right_lim, 1)
+		 && !fastmap[(unsigned char) string[match_first]])
+	    ++match_first;
+
+	forward_match_found_start_or_reached_end:
+	  if (BE (match_first == right_lim, 0))
+	    {
+	      ch = match_first >= length
+		       ? 0 : (unsigned char) string[match_first];
+	      if (!fastmap[t ? t[ch] : ch])
+		goto free_return;
+	    }
+	  break;
+
+	case 4:
+	case 5:
+	  /* Fastmap without multi-byte translation, match backwards.  */
+	  while (match_first >= left_lim)
+	    {
+	      ch = match_first >= length
+		       ? 0 : (unsigned char) string[match_first];
+	      if (fastmap[t ? t[ch] : ch])
+		break;
+	      --match_first;
+	    }
+	  if (match_first < left_lim)
+	    goto free_return;
+	  break;
+
+	default:
+	  /* In this case, we can't determine easily the current byte,
+	     since it might be a component byte of a multibyte
+	     character.  Then we use the constructed buffer instead.  */
+	  for (;;)
+	    {
+	      /* If MATCH_FIRST is out of the valid range, reconstruct the
+		 buffers.  */
+	      __re_size_t offset = match_first - mctx.input.raw_mbs_idx;
+	      if (BE (offset >= (__re_size_t) mctx.input.valid_raw_len, 0))
+		{
+		  err = re_string_reconstruct (&mctx.input, match_first,
+					       eflags);
+		  if (BE (err != REG_NOERROR, 0))
+		    goto free_return;
+
+		  offset = match_first - mctx.input.raw_mbs_idx;
+		}
+	      /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+		 Note that MATCH_FIRST must not be smaller than 0.  */
+	      ch = (match_first >= length
+		    ? 0 : re_string_byte_at (&mctx.input, offset));
+	      if (fastmap[ch])
+		break;
+	      match_first += incr;
+	      if (match_first < left_lim || match_first > right_lim)
+		{
+		  err = REG_NOMATCH;
+		  goto free_return;
+		}
+	    }
+	  break;
+	}
+
+      /* Reconstruct the buffers so that the matcher can assume that
+	 the matching starts from the beginning of the buffer.  */
+      err = re_string_reconstruct (&mctx.input, match_first, eflags);
+      if (BE (err != REG_NOERROR, 0))
+	goto free_return;
+
+#ifdef RE_ENABLE_I18N
+     /* Don't consider this char as a possible match start if it part,
+	yet isn't the head, of a multibyte character.  */
+      if (!sb && !re_string_first_byte (&mctx.input, 0))
+	continue;
+#endif
+
+      /* It seems to be appropriate one, then use the matcher.  */
+      /* We assume that the matching starts from 0.  */
+      mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+      match_last = check_matching (&mctx, fl_longest_match,
+				   start <= last_start ? &match_first : NULL);
+      if (match_last != REG_MISSING)
+	{
+	  if (BE (match_last == REG_ERROR, 0))
+	    {
+	      err = REG_ESPACE;
+	      goto free_return;
+	    }
+	  else
+	    {
+	      mctx.match_last = match_last;
+	      if ((!preg->no_sub && nmatch > 1) || dfa->nbackref)
+		{
+		  re_dfastate_t *pstate = mctx.state_log[match_last];
+		  mctx.last_node = check_halt_state_context (&mctx, pstate,
+							     match_last);
+		}
+	      if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
+		  || dfa->nbackref)
+		{
+		  err = prune_impossible_nodes (&mctx);
+		  if (err == REG_NOERROR)
+		    break;
+		  if (BE (err != REG_NOMATCH, 0))
+		    goto free_return;
+		  match_last = REG_MISSING;
+		}
+	      else
+		break; /* We found a match.  */
+	    }
+	}
+
+      match_ctx_clean (&mctx);
+    }
+
+#ifdef DEBUG
+  assert (match_last != REG_MISSING);
+  assert (err == REG_NOERROR);
+#endif
+
+  /* Set pmatch[] if we need.  */
+  if (nmatch > 0)
+    {
+      Idx reg_idx;
+
+      /* Initialize registers.  */
+      for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
+	pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
+
+      /* Set the points where matching start/end.  */
+      pmatch[0].rm_so = 0;
+      pmatch[0].rm_eo = mctx.match_last;
+      /* FIXME: This function should fail if mctx.match_last exceeds
+	 the maximum possible regoff_t value.  We need a new error
+	 code REG_OVERFLOW.  */
+
+      if (!preg->no_sub && nmatch > 1)
+	{
+	  err = set_regs (preg, &mctx, nmatch, pmatch,
+			  dfa->has_plural_match && dfa->nbackref > 0);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto free_return;
+	}
+
+      /* At last, add the offset to the each registers, since we slided
+	 the buffers so that we could assume that the matching starts
+	 from 0.  */
+      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+	if (pmatch[reg_idx].rm_so != -1)
+	  {
+#ifdef RE_ENABLE_I18N
+	    if (BE (mctx.input.offsets_needed != 0, 0))
+	      {
+		pmatch[reg_idx].rm_so =
+		  (pmatch[reg_idx].rm_so == mctx.input.valid_len
+		   ? mctx.input.valid_raw_len
+		   : mctx.input.offsets[pmatch[reg_idx].rm_so]);
+		pmatch[reg_idx].rm_eo =
+		  (pmatch[reg_idx].rm_eo == mctx.input.valid_len
+		   ? mctx.input.valid_raw_len
+		   : mctx.input.offsets[pmatch[reg_idx].rm_eo]);
+	      }
+#else
+	    assert (mctx.input.offsets_needed == 0);
+#endif
+	    pmatch[reg_idx].rm_so += match_first;
+	    pmatch[reg_idx].rm_eo += match_first;
+	  }
+      for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx)
+	{
+	  pmatch[nmatch + reg_idx].rm_so = -1;
+	  pmatch[nmatch + reg_idx].rm_eo = -1;
+	}
+
+      if (dfa->subexp_map)
+	for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
+	  if (dfa->subexp_map[reg_idx] != reg_idx)
+	    {
+	      pmatch[reg_idx + 1].rm_so
+		= pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
+	      pmatch[reg_idx + 1].rm_eo
+		= pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
+	    }
+    }
+
+ free_return:
+  re_free (mctx.state_log);
+  if (dfa->nbackref)
+    match_ctx_free (&mctx);
+  re_string_destruct (&mctx.input);
+  return err;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+prune_impossible_nodes (re_match_context_t *mctx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx halt_node, match_last;
+  reg_errcode_t ret;
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **lim_states = NULL;
+  re_sift_context_t sctx;
+#ifdef DEBUG
+  assert (mctx->state_log != NULL);
+#endif
+  match_last = mctx->match_last;
+  halt_node = mctx->last_node;
+
+  /* Avoid overflow.  */
+  if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0))
+    return REG_ESPACE;
+
+  sifted_states = re_malloc (re_dfastate_t *, match_last + 1);
+  if (BE (sifted_states == NULL, 0))
+    {
+      ret = REG_ESPACE;
+      goto free_return;
+    }
+  if (dfa->nbackref)
+    {
+      lim_states = re_malloc (re_dfastate_t *, match_last + 1);
+      if (BE (lim_states == NULL, 0))
+	{
+	  ret = REG_ESPACE;
+	  goto free_return;
+	}
+      while (1)
+	{
+	  memset (lim_states, '\0',
+		  sizeof (re_dfastate_t *) * (match_last + 1));
+	  sift_ctx_init (&sctx, sifted_states, lim_states, halt_node,
+			 match_last);
+	  ret = sift_states_backward (mctx, &sctx);
+	  re_node_set_free (&sctx.limits);
+	  if (BE (ret != REG_NOERROR, 0))
+	      goto free_return;
+	  if (sifted_states[0] != NULL || lim_states[0] != NULL)
+	    break;
+	  do
+	    {
+	      --match_last;
+	      if (! REG_VALID_INDEX (match_last))
+		{
+		  ret = REG_NOMATCH;
+		  goto free_return;
+		}
+	    } while (mctx->state_log[match_last] == NULL
+		     || !mctx->state_log[match_last]->halt);
+	  halt_node = check_halt_state_context (mctx,
+						mctx->state_log[match_last],
+						match_last);
+	}
+      ret = merge_state_array (dfa, sifted_states, lim_states,
+			       match_last + 1);
+      re_free (lim_states);
+      lim_states = NULL;
+      if (BE (ret != REG_NOERROR, 0))
+	goto free_return;
+    }
+  else
+    {
+      sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last);
+      ret = sift_states_backward (mctx, &sctx);
+      re_node_set_free (&sctx.limits);
+      if (BE (ret != REG_NOERROR, 0))
+	goto free_return;
+      if (sifted_states[0] == NULL)
+	{
+	  ret = REG_NOMATCH;
+	  goto free_return;
+	}
+    }
+  re_free (mctx->state_log);
+  mctx->state_log = sifted_states;
+  sifted_states = NULL;
+  mctx->last_node = halt_node;
+  mctx->match_last = match_last;
+  ret = REG_NOERROR;
+ free_return:
+  re_free (sifted_states);
+  re_free (lim_states);
+  return ret;
+}
+
+/* Acquire an initial state and return it.
+   We must select appropriate initial state depending on the context,
+   since initial states may have constraints like "\<", "^", etc..  */
+
+static inline re_dfastate_t *
+__attribute ((always_inline)) internal_function
+acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx,
+			    Idx idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  if (dfa->init_state->has_constraint)
+    {
+      unsigned int context;
+      context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags);
+      if (IS_WORD_CONTEXT (context))
+	return dfa->init_state_word;
+      else if (IS_ORDINARY_CONTEXT (context))
+	return dfa->init_state;
+      else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context))
+	return dfa->init_state_begbuf;
+      else if (IS_NEWLINE_CONTEXT (context))
+	return dfa->init_state_nl;
+      else if (IS_BEGBUF_CONTEXT (context))
+	{
+	  /* It is relatively rare case, then calculate on demand.  */
+	  return re_acquire_state_context (err, dfa,
+					   dfa->init_state->entrance_nodes,
+					   context);
+	}
+      else
+	/* Must not happen?  */
+	return dfa->init_state;
+    }
+  else
+    return dfa->init_state;
+}
+
+/* Check whether the regular expression match input string INPUT or not,
+   and return the index where the matching end.  Return REG_MISSING if
+   there is no match, and return REG_ERROR in case of an error.
+   FL_LONGEST_MATCH means we want the POSIX longest matching.
+   If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
+   next place where we may want to try matching.
+   Note that the matcher assume that the maching starts from the current
+   index of the buffer.  */
+
+static Idx
+internal_function __attribute_warn_unused_result__
+check_matching (re_match_context_t *mctx, bool fl_longest_match,
+		Idx *p_match_first)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx match = 0;
+  Idx match_last = REG_MISSING;
+  Idx cur_str_idx = re_string_cur_idx (&mctx->input);
+  re_dfastate_t *cur_state;
+  bool at_init_state = p_match_first != NULL;
+  Idx next_start_idx = cur_str_idx;
+
+  err = REG_NOERROR;
+  cur_state = acquire_init_state_context (&err, mctx, cur_str_idx);
+  /* An initial state must not be NULL (invalid).  */
+  if (BE (cur_state == NULL, 0))
+    {
+      assert (err == REG_ESPACE);
+      return REG_ERROR;
+    }
+
+  if (mctx->state_log != NULL)
+    {
+      mctx->state_log[cur_str_idx] = cur_state;
+
+      /* Check OP_OPEN_SUBEXP in the initial state in case that we use them
+	 later.  E.g. Processing back references.  */
+      if (BE (dfa->nbackref, 0))
+	{
+	  at_init_state = false;
+	  err = check_subexp_matching_top (mctx, &cur_state->nodes, 0);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+
+	  if (cur_state->has_backref)
+	    {
+	      err = transit_state_bkref (mctx, &cur_state->nodes);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	}
+    }
+
+  /* If the RE accepts NULL string.  */
+  if (BE (cur_state->halt, 0))
+    {
+      if (!cur_state->has_constraint
+	  || check_halt_state_context (mctx, cur_state, cur_str_idx))
+	{
+	  if (!fl_longest_match)
+	    return cur_str_idx;
+	  else
+	    {
+	      match_last = cur_str_idx;
+	      match = 1;
+	    }
+	}
+    }
+
+  while (!re_string_eoi (&mctx->input))
+    {
+      re_dfastate_t *old_state = cur_state;
+      Idx next_char_idx = re_string_cur_idx (&mctx->input) + 1;
+
+      if (BE (next_char_idx >= mctx->input.bufs_len, 0)
+	  || (BE (next_char_idx >= mctx->input.valid_len, 0)
+	      && mctx->input.valid_len < mctx->input.len))
+	{
+	  err = extend_buffers (mctx);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      assert (err == REG_ESPACE);
+	      return REG_ERROR;
+	    }
+	}
+
+      cur_state = transit_state (&err, mctx, cur_state);
+      if (mctx->state_log != NULL)
+	cur_state = merge_state_with_log (&err, mctx, cur_state);
+
+      if (cur_state == NULL)
+	{
+	  /* Reached the invalid state or an error.  Try to recover a valid
+	     state using the state log, if available and if we have not
+	     already found a valid (even if not the longest) match.  */
+	  if (BE (err != REG_NOERROR, 0))
+	    return REG_ERROR;
+
+	  if (mctx->state_log == NULL
+	      || (match && !fl_longest_match)
+	      || (cur_state = find_recover_state (&err, mctx)) == NULL)
+	    break;
+	}
+
+      if (BE (at_init_state, 0))
+	{
+	  if (old_state == cur_state)
+	    next_start_idx = next_char_idx;
+	  else
+	    at_init_state = false;
+	}
+
+      if (cur_state->halt)
+	{
+	  /* Reached a halt state.
+	     Check the halt state can satisfy the current context.  */
+	  if (!cur_state->has_constraint
+	      || check_halt_state_context (mctx, cur_state,
+					   re_string_cur_idx (&mctx->input)))
+	    {
+	      /* We found an appropriate halt state.  */
+	      match_last = re_string_cur_idx (&mctx->input);
+	      match = 1;
+
+	      /* We found a match, do not modify match_first below.  */
+	      p_match_first = NULL;
+	      if (!fl_longest_match)
+		break;
+	    }
+	}
+    }
+
+  if (p_match_first)
+    *p_match_first += next_start_idx;
+
+  return match_last;
+}
+
+/* Check NODE match the current context.  */
+
+static bool
+internal_function
+check_halt_node_context (const re_dfa_t *dfa, Idx node, unsigned int context)
+{
+  re_token_type_t type = dfa->nodes[node].type;
+  unsigned int constraint = dfa->nodes[node].constraint;
+  if (type != END_OF_RE)
+    return false;
+  if (!constraint)
+    return true;
+  if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context))
+    return false;
+  return true;
+}
+
+/* Check the halt state STATE match the current context.
+   Return 0 if not match, if the node, STATE has, is a halt node and
+   match the context, return the node.  */
+
+static Idx
+internal_function
+check_halt_state_context (const re_match_context_t *mctx,
+			  const re_dfastate_t *state, Idx idx)
+{
+  Idx i;
+  unsigned int context;
+#ifdef DEBUG
+  assert (state->halt);
+#endif
+  context = re_string_context_at (&mctx->input, idx, mctx->eflags);
+  for (i = 0; i < state->nodes.nelem; ++i)
+    if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context))
+      return state->nodes.elems[i];
+  return 0;
+}
+
+/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
+   corresponding to the DFA).
+   Return the destination node, and update EPS_VIA_NODES;
+   return REG_MISSING in case of errors.  */
+
+static Idx
+internal_function
+proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+		   Idx *pidx, Idx node, re_node_set *eps_via_nodes,
+		   struct re_fail_stack_t *fs)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx i;
+  bool ok;
+  if (IS_EPSILON_NODE (dfa->nodes[node].type))
+    {
+      re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
+      re_node_set *edests = &dfa->edests[node];
+      Idx dest_node;
+      ok = re_node_set_insert (eps_via_nodes, node);
+      if (BE (! ok, 0))
+	return REG_ERROR;
+      /* Pick up a valid destination, or return REG_MISSING if none
+	 is found.  */
+      for (dest_node = REG_MISSING, i = 0; i < edests->nelem; ++i)
+	{
+	  Idx candidate = edests->elems[i];
+	  if (!re_node_set_contains (cur_nodes, candidate))
+	    continue;
+          if (dest_node == REG_MISSING)
+	    dest_node = candidate;
+
+	  else
+	    {
+	      /* In order to avoid infinite loop like "(a*)*", return the second
+		 epsilon-transition if the first was already considered.  */
+	      if (re_node_set_contains (eps_via_nodes, dest_node))
+		return candidate;
+
+	      /* Otherwise, push the second epsilon-transition on the fail stack.  */
+	      else if (fs != NULL
+		       && push_fail_stack (fs, *pidx, candidate, nregs, regs,
+					   eps_via_nodes))
+		return REG_ERROR;
+
+	      /* We know we are going to exit.  */
+	      break;
+	    }
+	}
+      return dest_node;
+    }
+  else
+    {
+      Idx naccepted = 0;
+      re_token_type_t type = dfa->nodes[node].type;
+
+#ifdef RE_ENABLE_I18N
+      if (dfa->nodes[node].accept_mb)
+	naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx);
+      else
+#endif /* RE_ENABLE_I18N */
+      if (type == OP_BACK_REF)
+	{
+	  Idx subexp_idx = dfa->nodes[node].opr.idx + 1;
+	  naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
+	  if (fs != NULL)
+	    {
+	      if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
+		return REG_MISSING;
+	      else if (naccepted)
+		{
+		  char *buf = (char *) re_string_get_buffer (&mctx->input);
+		  if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
+			      naccepted) != 0)
+		    return REG_MISSING;
+		}
+	    }
+
+	  if (naccepted == 0)
+	    {
+	      Idx dest_node;
+	      ok = re_node_set_insert (eps_via_nodes, node);
+	      if (BE (! ok, 0))
+		return REG_ERROR;
+	      dest_node = dfa->edests[node].elems[0];
+	      if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+					dest_node))
+		return dest_node;
+	    }
+	}
+
+      if (naccepted != 0
+	  || check_node_accept (mctx, dfa->nodes + node, *pidx))
+	{
+	  Idx dest_node = dfa->nexts[node];
+	  *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
+	  if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
+		     || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+					       dest_node)))
+	    return REG_MISSING;
+	  re_node_set_empty (eps_via_nodes);
+	  return dest_node;
+	}
+    }
+  return REG_MISSING;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
+		 Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+  reg_errcode_t err;
+  Idx num = fs->num++;
+  if (fs->num == fs->alloc)
+    {
+      struct re_fail_stack_ent_t *new_array;
+      new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t)
+				       * fs->alloc * 2));
+      if (new_array == NULL)
+	return REG_ESPACE;
+      fs->alloc *= 2;
+      fs->stack = new_array;
+    }
+  fs->stack[num].idx = str_idx;
+  fs->stack[num].node = dest_node;
+  fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+  if (fs->stack[num].regs == NULL)
+    return REG_ESPACE;
+  memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
+  err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
+  return err;
+}
+
+static Idx
+internal_function
+pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
+		regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+  Idx num = --fs->num;
+  assert (REG_VALID_INDEX (num));
+  *pidx = fs->stack[num].idx;
+  memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
+  re_node_set_free (eps_via_nodes);
+  re_free (fs->stack[num].regs);
+  *eps_via_nodes = fs->stack[num].eps_via_nodes;
+  return fs->stack[num].node;
+}
+
+/* Set the positions where the subexpressions are starts/ends to registers
+   PMATCH.
+   Note: We assume that pmatch[0] is already set, and
+   pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
+	  regmatch_t *pmatch, bool fl_backtrack)
+{
+  const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer;
+  Idx idx, cur_node;
+  re_node_set eps_via_nodes;
+  struct re_fail_stack_t *fs;
+  struct re_fail_stack_t fs_body = { 0, 2, NULL };
+  regmatch_t *prev_idx_match;
+  bool prev_idx_match_malloced = false;
+
+#ifdef DEBUG
+  assert (nmatch > 1);
+  assert (mctx->state_log != NULL);
+#endif
+  if (fl_backtrack)
+    {
+      fs = &fs_body;
+      fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
+      if (fs->stack == NULL)
+	return REG_ESPACE;
+    }
+  else
+    fs = NULL;
+
+  cur_node = dfa->init_node;
+  re_node_set_init_empty (&eps_via_nodes);
+
+  if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
+    prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
+  else
+    {
+      prev_idx_match = re_malloc (regmatch_t, nmatch);
+      if (prev_idx_match == NULL)
+	{
+	  free_fail_stack_return (fs);
+	  return REG_ESPACE;
+	}
+      prev_idx_match_malloced = true;
+    }
+  memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+
+  for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
+    {
+      update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
+
+      if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+	{
+	  Idx reg_idx;
+	  if (fs)
+	    {
+	      for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+		if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
+		  break;
+	      if (reg_idx == nmatch)
+		{
+		  re_node_set_free (&eps_via_nodes);
+		  if (prev_idx_match_malloced)
+		    re_free (prev_idx_match);
+		  return free_fail_stack_return (fs);
+		}
+	      cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+					 &eps_via_nodes);
+	    }
+	  else
+	    {
+	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
+	      return REG_NOERROR;
+	    }
+	}
+
+      /* Proceed to next node.  */
+      cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
+				    &eps_via_nodes, fs);
+
+      if (BE (! REG_VALID_INDEX (cur_node), 0))
+	{
+	  if (BE (cur_node == REG_ERROR, 0))
+	    {
+	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
+	      free_fail_stack_return (fs);
+	      return REG_ESPACE;
+	    }
+	  if (fs)
+	    cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+				       &eps_via_nodes);
+	  else
+	    {
+	      re_node_set_free (&eps_via_nodes);
+	      if (prev_idx_match_malloced)
+		re_free (prev_idx_match);
+	      return REG_NOMATCH;
+	    }
+	}
+    }
+  re_node_set_free (&eps_via_nodes);
+  if (prev_idx_match_malloced)
+    re_free (prev_idx_match);
+  return free_fail_stack_return (fs);
+}
+
+static reg_errcode_t
+internal_function
+free_fail_stack_return (struct re_fail_stack_t *fs)
+{
+  if (fs)
+    {
+      Idx fs_idx;
+      for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
+	{
+	  re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
+	  re_free (fs->stack[fs_idx].regs);
+	}
+      re_free (fs->stack);
+    }
+  return REG_NOERROR;
+}
+
+static void
+internal_function
+update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+	     regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch)
+{
+  int type = dfa->nodes[cur_node].type;
+  if (type == OP_OPEN_SUBEXP)
+    {
+      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+
+      /* We are at the first node of this sub expression.  */
+      if (reg_num < nmatch)
+	{
+	  pmatch[reg_num].rm_so = cur_idx;
+	  pmatch[reg_num].rm_eo = -1;
+	}
+    }
+  else if (type == OP_CLOSE_SUBEXP)
+    {
+      Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+      if (reg_num < nmatch)
+	{
+	  /* We are at the last node of this sub expression.  */
+	  if (pmatch[reg_num].rm_so < cur_idx)
+	    {
+	      pmatch[reg_num].rm_eo = cur_idx;
+	      /* This is a non-empty match or we are not inside an optional
+		 subexpression.  Accept this right away.  */
+	      memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+	    }
+	  else
+	    {
+	      if (dfa->nodes[cur_node].opt_subexp
+		  && prev_idx_match[reg_num].rm_so != -1)
+		/* We transited through an empty match for an optional
+		   subexpression, like (a?)*, and this is not the subexp's
+		   first match.  Copy back the old content of the registers
+		   so that matches of an inner subexpression are undone as
+		   well, like in ((a?))*.  */
+		memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
+	      else
+		/* We completed a subexpression, but it may be part of
+		   an optional one, so do not update PREV_IDX_MATCH.  */
+		pmatch[reg_num].rm_eo = cur_idx;
+	    }
+	}
+    }
+}
+
+/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
+   and sift the nodes in each states according to the following rules.
+   Updated state_log will be wrote to STATE_LOG.
+
+   Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if...
+     1. When STR_IDX == MATCH_LAST(the last index in the state_log):
+	If `a' isn't the LAST_NODE and `a' can't epsilon transit to
+	the LAST_NODE, we throw away the node `a'.
+     2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts
+	string `s' and transit to `b':
+	i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
+	   away the node `a'.
+	ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
+	    thrown away, we throw away the node `a'.
+     3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
+	i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
+	   node `a'.
+	ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
+	    we throw away the node `a'.  */
+
+#define STATE_NODE_CONTAINS(state,node) \
+  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
+
+static reg_errcode_t
+internal_function
+sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
+{
+  reg_errcode_t err;
+  int null_cnt = 0;
+  Idx str_idx = sctx->last_str_idx;
+  re_node_set cur_dest;
+
+#ifdef DEBUG
+  assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL);
+#endif
+
+  /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
+     transit to the last_node and the last_node itself.  */
+  err = re_node_set_init_1 (&cur_dest, sctx->last_node);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+  if (BE (err != REG_NOERROR, 0))
+    goto free_return;
+
+  /* Then check each states in the state_log.  */
+  while (str_idx > 0)
+    {
+      /* Update counters.  */
+      null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
+      if (null_cnt > mctx->max_mb_elem_len)
+	{
+	  memset (sctx->sifted_states, '\0',
+		  sizeof (re_dfastate_t *) * str_idx);
+	  re_node_set_free (&cur_dest);
+	  return REG_NOERROR;
+	}
+      re_node_set_empty (&cur_dest);
+      --str_idx;
+
+      if (mctx->state_log[str_idx])
+	{
+	  err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto free_return;
+	}
+
+      /* Add all the nodes which satisfy the following conditions:
+	 - It can epsilon transit to a node in CUR_DEST.
+	 - It is in CUR_SRC.
+	 And update state_log.  */
+      err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+      if (BE (err != REG_NOERROR, 0))
+	goto free_return;
+    }
+  err = REG_NOERROR;
+ free_return:
+  re_node_set_free (&cur_dest);
+  return err;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
+		     Idx str_idx, re_node_set *cur_dest)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
+  Idx i;
+
+  /* Then build the next sifted state.
+     We build the next sifted state on `cur_dest', and update
+     `sifted_states[str_idx]' with `cur_dest'.
+     Note:
+     `cur_dest' is the sifted state from `state_log[str_idx + 1]'.
+     `cur_src' points the node_set of the old `state_log[str_idx]'
+     (with the epsilon nodes pre-filtered out).  */
+  for (i = 0; i < cur_src->nelem; i++)
+    {
+      Idx prev_node = cur_src->elems[i];
+      int naccepted = 0;
+      bool ok;
+
+#ifdef DEBUG
+      re_token_type_t type = dfa->nodes[prev_node].type;
+      assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (dfa->nodes[prev_node].accept_mb)
+	naccepted = sift_states_iter_mb (mctx, sctx, prev_node,
+					 str_idx, sctx->last_str_idx);
+#endif /* RE_ENABLE_I18N */
+
+      /* We don't check backreferences here.
+	 See update_cur_sifted_state().  */
+      if (!naccepted
+	  && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
+	  && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
+				  dfa->nexts[prev_node]))
+	naccepted = 1;
+
+      if (naccepted == 0)
+	continue;
+
+      if (sctx->limits.nelem)
+	{
+	  Idx to_idx = str_idx + naccepted;
+	  if (check_dst_limits (mctx, &sctx->limits,
+				dfa->nexts[prev_node], to_idx,
+				prev_node, str_idx))
+	    continue;
+	}
+      ok = re_node_set_insert (cur_dest, prev_node);
+      if (BE (! ok, 0))
+	return REG_ESPACE;
+    }
+
+  return REG_NOERROR;
+}
+
+/* Helper functions.  */
+
+static reg_errcode_t
+internal_function
+clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
+{
+  Idx top = mctx->state_log_top;
+
+  if (next_state_log_idx >= mctx->input.bufs_len
+      || (next_state_log_idx >= mctx->input.valid_len
+	  && mctx->input.valid_len < mctx->input.len))
+    {
+      reg_errcode_t err;
+      err = extend_buffers (mctx);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+
+  if (top < next_state_log_idx)
+    {
+      memset (mctx->state_log + top + 1, '\0',
+	      sizeof (re_dfastate_t *) * (next_state_log_idx - top));
+      mctx->state_log_top = next_state_log_idx;
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst,
+		   re_dfastate_t **src, Idx num)
+{
+  Idx st_idx;
+  reg_errcode_t err;
+  for (st_idx = 0; st_idx < num; ++st_idx)
+    {
+      if (dst[st_idx] == NULL)
+	dst[st_idx] = src[st_idx];
+      else if (src[st_idx] != NULL)
+	{
+	  re_node_set merged_set;
+	  err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
+					&src[st_idx]->nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	  dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
+	  re_node_set_free (&merged_set);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function
+update_cur_sifted_state (const re_match_context_t *mctx,
+			 re_sift_context_t *sctx, Idx str_idx,
+			 re_node_set *dest_nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err = REG_NOERROR;
+  const re_node_set *candidates;
+  candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
+		: &mctx->state_log[str_idx]->nodes);
+
+  if (dest_nodes->nelem == 0)
+    sctx->sifted_states[str_idx] = NULL;
+  else
+    {
+      if (candidates)
+	{
+	  /* At first, add the nodes which can epsilon transit to a node in
+	     DEST_NODE.  */
+	  err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+
+	  /* Then, check the limitations in the current sift_context.  */
+	  if (sctx->limits.nelem)
+	    {
+	      err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
+					 mctx->bkref_ents, str_idx);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	}
+
+      sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+
+  if (candidates && mctx->state_log[str_idx]->has_backref)
+    {
+      err = sift_states_bkref (mctx, sctx, str_idx, candidates);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
+		       const re_node_set *candidates)
+{
+  reg_errcode_t err = REG_NOERROR;
+  Idx i;
+
+  re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+
+  if (!state->inveclosure.alloc)
+    {
+      err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
+      if (BE (err != REG_NOERROR, 0))
+	return REG_ESPACE;
+      for (i = 0; i < dest_nodes->nelem; i++)
+	{
+	  err = re_node_set_merge (&state->inveclosure,
+				   dfa->inveclosures + dest_nodes->elems[i]);
+	  if (BE (err != REG_NOERROR, 0))
+	    return REG_ESPACE;
+	}
+    }
+  return re_node_set_add_intersect (dest_nodes, candidates,
+				    &state->inveclosure);
+}
+
+static reg_errcode_t
+internal_function
+sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes,
+		       const re_node_set *candidates)
+{
+    Idx ecl_idx;
+    reg_errcode_t err;
+    re_node_set *inv_eclosure = dfa->inveclosures + node;
+    re_node_set except_nodes;
+    re_node_set_init_empty (&except_nodes);
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+      {
+	Idx cur_node = inv_eclosure->elems[ecl_idx];
+	if (cur_node == node)
+	  continue;
+	if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
+	  {
+	    Idx edst1 = dfa->edests[cur_node].elems[0];
+	    Idx edst2 = ((dfa->edests[cur_node].nelem > 1)
+			 ? dfa->edests[cur_node].elems[1] : REG_MISSING);
+	    if ((!re_node_set_contains (inv_eclosure, edst1)
+		 && re_node_set_contains (dest_nodes, edst1))
+		|| (REG_VALID_NONZERO_INDEX (edst2)
+		    && !re_node_set_contains (inv_eclosure, edst2)
+		    && re_node_set_contains (dest_nodes, edst2)))
+	      {
+		err = re_node_set_add_intersect (&except_nodes, candidates,
+						 dfa->inveclosures + cur_node);
+		if (BE (err != REG_NOERROR, 0))
+		  {
+		    re_node_set_free (&except_nodes);
+		    return err;
+		  }
+	      }
+	  }
+      }
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+      {
+	Idx cur_node = inv_eclosure->elems[ecl_idx];
+	if (!re_node_set_contains (&except_nodes, cur_node))
+	  {
+	    Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1;
+	    re_node_set_remove_at (dest_nodes, idx);
+	  }
+      }
+    re_node_set_free (&except_nodes);
+    return REG_NOERROR;
+}
+
+static bool
+internal_function
+check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits,
+		  Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx lim_idx, src_pos, dst_pos;
+
+  Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
+  Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
+  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+      Idx subexp_idx;
+      struct re_backref_cache_entry *ent;
+      ent = mctx->bkref_ents + limits->elems[lim_idx];
+      subexp_idx = dfa->nodes[ent->node].opr.idx;
+
+      dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+					   subexp_idx, dst_node, dst_idx,
+					   dst_bkref_idx);
+      src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+					   subexp_idx, src_node, src_idx,
+					   src_bkref_idx);
+
+      /* In case of:
+	 <src> <dst> ( <subexp> )
+	 ( <subexp> ) <src> <dst>
+	 ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */
+      if (src_pos == dst_pos)
+	continue; /* This is unrelated limitation.  */
+      else
+	return true;
+    }
+  return false;
+}
+
+static int
+internal_function
+check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
+			     Idx subexp_idx, Idx from_node, Idx bkref_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  const re_node_set *eclosures = dfa->eclosures + from_node;
+  Idx node_idx;
+
+  /* Else, we are on the boundary: examine the nodes on the epsilon
+     closure.  */
+  for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
+    {
+      Idx node = eclosures->elems[node_idx];
+      switch (dfa->nodes[node].type)
+	{
+	case OP_BACK_REF:
+	  if (bkref_idx != REG_MISSING)
+	    {
+	      struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
+	      do
+		{
+		  Idx dst;
+		  int cpos;
+
+		  if (ent->node != node)
+		    continue;
+
+		  if (subexp_idx < BITSET_WORD_BITS
+		      && !(ent->eps_reachable_subexps_map
+			   & ((bitset_word_t) 1 << subexp_idx)))
+		    continue;
+
+		  /* Recurse trying to reach the OP_OPEN_SUBEXP and
+		     OP_CLOSE_SUBEXP cases below.  But, if the
+		     destination node is the same node as the source
+		     node, don't recurse because it would cause an
+		     infinite loop: a regex that exhibits this behavior
+		     is ()\1*\1*  */
+		  dst = dfa->edests[node].elems[0];
+		  if (dst == from_node)
+		    {
+		      if (boundaries & 1)
+			return -1;
+		      else /* if (boundaries & 2) */
+			return 0;
+		    }
+
+		  cpos =
+		    check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+						 dst, bkref_idx);
+		  if (cpos == -1 /* && (boundaries & 1) */)
+		    return -1;
+		  if (cpos == 0 && (boundaries & 2))
+		    return 0;
+
+		  if (subexp_idx < BITSET_WORD_BITS)
+		    ent->eps_reachable_subexps_map
+		      &= ~((bitset_word_t) 1 << subexp_idx);
+		}
+	      while (ent++->more);
+	    }
+	  break;
+
+	case OP_OPEN_SUBEXP:
+	  if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
+	    return -1;
+	  break;
+
+	case OP_CLOSE_SUBEXP:
+	  if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
+	    return 0;
+	  break;
+
+	default:
+	    break;
+	}
+    }
+
+  return (boundaries & 2) ? 1 : 0;
+}
+
+static int
+internal_function
+check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit,
+			   Idx subexp_idx, Idx from_node, Idx str_idx,
+			   Idx bkref_idx)
+{
+  struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+  int boundaries;
+
+  /* If we are outside the range of the subexpression, return -1 or 1.  */
+  if (str_idx < lim->subexp_from)
+    return -1;
+
+  if (lim->subexp_to < str_idx)
+    return 1;
+
+  /* If we are within the subexpression, return 0.  */
+  boundaries = (str_idx == lim->subexp_from);
+  boundaries |= (str_idx == lim->subexp_to) << 1;
+  if (boundaries == 0)
+    return 0;
+
+  /* Else, examine epsilon closure.  */
+  return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+				      from_node, bkref_idx);
+}
+
+/* Check the limitations of sub expressions LIMITS, and remove the nodes
+   which are against limitations from DEST_NODES. */
+
+static reg_errcode_t
+internal_function
+check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
+		     const re_node_set *candidates, re_node_set *limits,
+		     struct re_backref_cache_entry *bkref_ents, Idx str_idx)
+{
+  reg_errcode_t err;
+  Idx node_idx, lim_idx;
+
+  for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+      Idx subexp_idx;
+      struct re_backref_cache_entry *ent;
+      ent = bkref_ents + limits->elems[lim_idx];
+
+      if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
+	continue; /* This is unrelated limitation.  */
+
+      subexp_idx = dfa->nodes[ent->node].opr.idx;
+      if (ent->subexp_to == str_idx)
+	{
+	  Idx ops_node = REG_MISSING;
+	  Idx cls_node = REG_MISSING;
+	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+	    {
+	      Idx node = dest_nodes->elems[node_idx];
+	      re_token_type_t type = dfa->nodes[node].type;
+	      if (type == OP_OPEN_SUBEXP
+		  && subexp_idx == dfa->nodes[node].opr.idx)
+		ops_node = node;
+	      else if (type == OP_CLOSE_SUBEXP
+		       && subexp_idx == dfa->nodes[node].opr.idx)
+		cls_node = node;
+	    }
+
+	  /* Check the limitation of the open subexpression.  */
+	  /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
+	  if (REG_VALID_INDEX (ops_node))
+	    {
+	      err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
+					   candidates);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+
+	  /* Check the limitation of the close subexpression.  */
+	  if (REG_VALID_INDEX (cls_node))
+	    for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+	      {
+		Idx node = dest_nodes->elems[node_idx];
+		if (!re_node_set_contains (dfa->inveclosures + node,
+					   cls_node)
+		    && !re_node_set_contains (dfa->eclosures + node,
+					      cls_node))
+		  {
+		    /* It is against this limitation.
+		       Remove it form the current sifted state.  */
+		    err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+						 candidates);
+		    if (BE (err != REG_NOERROR, 0))
+		      return err;
+		    --node_idx;
+		  }
+	      }
+	}
+      else /* (ent->subexp_to != str_idx)  */
+	{
+	  for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+	    {
+	      Idx node = dest_nodes->elems[node_idx];
+	      re_token_type_t type = dfa->nodes[node].type;
+	      if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
+		{
+		  if (subexp_idx != dfa->nodes[node].opr.idx)
+		    continue;
+		  /* It is against this limitation.
+		     Remove it form the current sifted state.  */
+		  err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+					       candidates);
+		  if (BE (err != REG_NOERROR, 0))
+		    return err;
+		}
+	    }
+	}
+    }
+  return REG_NOERROR;
+}
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
+		   Idx str_idx, const re_node_set *candidates)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx node_idx, node;
+  re_sift_context_t local_sctx;
+  Idx first_idx = search_cur_bkref_entry (mctx, str_idx);
+
+  if (first_idx == REG_MISSING)
+    return REG_NOERROR;
+
+  local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
+
+  for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
+    {
+      Idx enabled_idx;
+      re_token_type_t type;
+      struct re_backref_cache_entry *entry;
+      node = candidates->elems[node_idx];
+      type = dfa->nodes[node].type;
+      /* Avoid infinite loop for the REs like "()\1+".  */
+      if (node == sctx->last_node && str_idx == sctx->last_str_idx)
+	continue;
+      if (type != OP_BACK_REF)
+	continue;
+
+      entry = mctx->bkref_ents + first_idx;
+      enabled_idx = first_idx;
+      do
+	{
+	  Idx subexp_len;
+	  Idx to_idx;
+	  Idx dst_node;
+	  bool ok;
+	  re_dfastate_t *cur_state;
+
+	  if (entry->node != node)
+	    continue;
+	  subexp_len = entry->subexp_to - entry->subexp_from;
+	  to_idx = str_idx + subexp_len;
+	  dst_node = (subexp_len ? dfa->nexts[node]
+		      : dfa->edests[node].elems[0]);
+
+	  if (to_idx > sctx->last_str_idx
+	      || sctx->sifted_states[to_idx] == NULL
+	      || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
+	      || check_dst_limits (mctx, &sctx->limits, node,
+				   str_idx, dst_node, to_idx))
+	    continue;
+
+	  if (local_sctx.sifted_states == NULL)
+	    {
+	      local_sctx = *sctx;
+	      err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  local_sctx.last_node = node;
+	  local_sctx.last_str_idx = str_idx;
+	  ok = re_node_set_insert (&local_sctx.limits, enabled_idx);
+	  if (BE (! ok, 0))
+	    {
+	      err = REG_ESPACE;
+	      goto free_return;
+	    }
+	  cur_state = local_sctx.sifted_states[str_idx];
+	  err = sift_states_backward (mctx, &local_sctx);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto free_return;
+	  if (sctx->limited_states != NULL)
+	    {
+	      err = merge_state_array (dfa, sctx->limited_states,
+				       local_sctx.sifted_states,
+				       str_idx + 1);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  local_sctx.sifted_states[str_idx] = cur_state;
+	  re_node_set_remove (&local_sctx.limits, enabled_idx);
+
+	  /* mctx->bkref_ents may have changed, reload the pointer.  */
+	  entry = mctx->bkref_ents + enabled_idx;
+	}
+      while (enabled_idx++, entry++->more);
+    }
+  err = REG_NOERROR;
+ free_return:
+  if (local_sctx.sifted_states != NULL)
+    {
+      re_node_set_free (&local_sctx.limits);
+    }
+
+  return err;
+}
+
+
+#ifdef RE_ENABLE_I18N
+static int
+internal_function
+sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx,
+		     Idx node_idx, Idx str_idx, Idx max_str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  int naccepted;
+  /* Check the node can accept `multi byte'.  */
+  naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx);
+  if (naccepted > 0 && str_idx + naccepted <= max_str_idx &&
+      !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted],
+			    dfa->nexts[node_idx]))
+    /* The node can't accept the `multi byte', or the
+       destination was already thrown away, then the node
+       could't accept the current input `multi byte'.   */
+    naccepted = 0;
+  /* Otherwise, it is sure that the node could accept
+     `naccepted' bytes input.  */
+  return naccepted;
+}
+#endif /* RE_ENABLE_I18N */
+
+

+/* Functions for state transition.  */
+
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte, and update STATE_LOG if necessary.
+   If STATE can accept a multibyte char/collating element/back reference
+   update the destination of STATE_LOG.  */
+
+static re_dfastate_t *
+internal_function __attribute_warn_unused_result__
+transit_state (reg_errcode_t *err, re_match_context_t *mctx,
+	       re_dfastate_t *state)
+{
+  re_dfastate_t **trtable;
+  unsigned char ch;
+
+#ifdef RE_ENABLE_I18N
+  /* If the current state can accept multibyte.  */
+  if (BE (state->accept_mb, 0))
+    {
+      *err = transit_state_mb (mctx, state);
+      if (BE (*err != REG_NOERROR, 0))
+	return NULL;
+    }
+#endif /* RE_ENABLE_I18N */
+
+  /* Then decide the next state with the single byte.  */
+#if 0
+  if (0)
+    /* don't use transition table  */
+    return transit_state_sb (err, mctx, state);
+#endif
+
+  /* Use transition table  */
+  ch = re_string_fetch_byte (&mctx->input);
+  for (;;)
+    {
+      trtable = state->trtable;
+      if (BE (trtable != NULL, 1))
+	return trtable[ch];
+
+      trtable = state->word_trtable;
+      if (BE (trtable != NULL, 1))
+	{
+	  unsigned int context;
+	  context
+	    = re_string_context_at (&mctx->input,
+				    re_string_cur_idx (&mctx->input) - 1,
+				    mctx->eflags);
+	  if (IS_WORD_CONTEXT (context))
+	    return trtable[ch + SBC_MAX];
+	  else
+	    return trtable[ch];
+	}
+
+      if (!build_trtable (mctx->dfa, state))
+	{
+	  *err = REG_ESPACE;
+	  return NULL;
+	}
+
+      /* Retry, we now have a transition table.  */
+    }
+}
+
+/* Update the state_log if we need */
+static re_dfastate_t *
+internal_function
+merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx,
+		      re_dfastate_t *next_state)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx cur_idx = re_string_cur_idx (&mctx->input);
+
+  if (cur_idx > mctx->state_log_top)
+    {
+      mctx->state_log[cur_idx] = next_state;
+      mctx->state_log_top = cur_idx;
+    }
+  else if (mctx->state_log[cur_idx] == 0)
+    {
+      mctx->state_log[cur_idx] = next_state;
+    }
+  else
+    {
+      re_dfastate_t *pstate;
+      unsigned int context;
+      re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
+      /* If (state_log[cur_idx] != 0), it implies that cur_idx is
+	 the destination of a multibyte char/collating element/
+	 back reference.  Then the next state is the union set of
+	 these destinations and the results of the transition table.  */
+      pstate = mctx->state_log[cur_idx];
+      log_nodes = pstate->entrance_nodes;
+      if (next_state != NULL)
+	{
+	  table_nodes = next_state->entrance_nodes;
+	  *err = re_node_set_init_union (&next_nodes, table_nodes,
+					     log_nodes);
+	  if (BE (*err != REG_NOERROR, 0))
+	    return NULL;
+	}
+      else
+	next_nodes = *log_nodes;
+      /* Note: We already add the nodes of the initial state,
+	 then we don't need to add them here.  */
+
+      context = re_string_context_at (&mctx->input,
+				      re_string_cur_idx (&mctx->input) - 1,
+				      mctx->eflags);
+      next_state = mctx->state_log[cur_idx]
+	= re_acquire_state_context (err, dfa, &next_nodes, context);
+      /* We don't need to check errors here, since the return value of
+	 this function is next_state and ERR is already set.  */
+
+      if (table_nodes != NULL)
+	re_node_set_free (&next_nodes);
+    }
+
+  if (BE (dfa->nbackref, 0) && next_state != NULL)
+    {
+      /* Check OP_OPEN_SUBEXP in the current state in case that we use them
+	 later.  We must check them here, since the back references in the
+	 next state might use them.  */
+      *err = check_subexp_matching_top (mctx, &next_state->nodes,
+					cur_idx);
+      if (BE (*err != REG_NOERROR, 0))
+	return NULL;
+
+      /* If the next state has back references.  */
+      if (next_state->has_backref)
+	{
+	  *err = transit_state_bkref (mctx, &next_state->nodes);
+	  if (BE (*err != REG_NOERROR, 0))
+	    return NULL;
+	  next_state = mctx->state_log[cur_idx];
+	}
+    }
+
+  return next_state;
+}
+
+/* Skip bytes in the input that correspond to part of a
+   multi-byte match, then look in the log for a state
+   from which to restart matching.  */
+static re_dfastate_t *
+internal_function
+find_recover_state (reg_errcode_t *err, re_match_context_t *mctx)
+{
+  re_dfastate_t *cur_state;
+  do
+    {
+      Idx max = mctx->state_log_top;
+      Idx cur_str_idx = re_string_cur_idx (&mctx->input);
+
+      do
+	{
+	  if (++cur_str_idx > max)
+	    return NULL;
+	  re_string_skip_bytes (&mctx->input, 1);
+	}
+      while (mctx->state_log[cur_str_idx] == NULL);
+
+      cur_state = merge_state_with_log (err, mctx, NULL);
+    }
+  while (*err == REG_NOERROR && cur_state == NULL);
+  return cur_state;
+}
+
+/* Helper functions for transit_state.  */
+
+/* From the node set CUR_NODES, pick up the nodes whose types are
+   OP_OPEN_SUBEXP and which have corresponding back references in the regular
+   expression. And register them to use them later for evaluating the
+   correspoding back references.  */
+
+static reg_errcode_t
+internal_function
+check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes,
+			   Idx str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx node_idx;
+  reg_errcode_t err;
+
+  /* TODO: This isn't efficient.
+	   Because there might be more than one nodes whose types are
+	   OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+	   nodes.
+	   E.g. RE: (a){2}  */
+  for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx)
+    {
+      Idx node = cur_nodes->elems[node_idx];
+      if (dfa->nodes[node].type == OP_OPEN_SUBEXP
+	  && dfa->nodes[node].opr.idx < BITSET_WORD_BITS
+	  && (dfa->used_bkref_map
+	      & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx)))
+	{
+	  err = match_ctx_add_subtop (mctx, node, str_idx);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+    }
+  return REG_NOERROR;
+}
+
+#if 0
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte.  */
+
+static re_dfastate_t *
+transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx,
+		  re_dfastate_t *state)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  re_node_set next_nodes;
+  re_dfastate_t *next_state;
+  Idx node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input);
+  unsigned int context;
+
+  *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1);
+  if (BE (*err != REG_NOERROR, 0))
+    return NULL;
+  for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt)
+    {
+      Idx cur_node = state->nodes.elems[node_cnt];
+      if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx))
+	{
+	  *err = re_node_set_merge (&next_nodes,
+				    dfa->eclosures + dfa->nexts[cur_node]);
+	  if (BE (*err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return NULL;
+	    }
+	}
+    }
+  context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags);
+  next_state = re_acquire_state_context (err, dfa, &next_nodes, context);
+  /* We don't need to check errors here, since the return value of
+     this function is next_state and ERR is already set.  */
+
+  re_node_set_free (&next_nodes);
+  re_string_skip_bytes (&mctx->input, 1);
+  return next_state;
+}
+#endif
+
+#ifdef RE_ENABLE_I18N
+static reg_errcode_t
+internal_function
+transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx i;
+
+  for (i = 0; i < pstate->nodes.nelem; ++i)
+    {
+      re_node_set dest_nodes, *new_nodes;
+      Idx cur_node_idx = pstate->nodes.elems[i];
+      int naccepted;
+      Idx dest_idx;
+      unsigned int context;
+      re_dfastate_t *dest_state;
+
+      if (!dfa->nodes[cur_node_idx].accept_mb)
+	continue;
+
+      if (dfa->nodes[cur_node_idx].constraint)
+	{
+	  context = re_string_context_at (&mctx->input,
+					  re_string_cur_idx (&mctx->input),
+					  mctx->eflags);
+	  if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint,
+					   context))
+	    continue;
+	}
+
+      /* How many bytes the node can accept?  */
+      naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input,
+					   re_string_cur_idx (&mctx->input));
+      if (naccepted == 0)
+	continue;
+
+      /* The node can accepts `naccepted' bytes.  */
+      dest_idx = re_string_cur_idx (&mctx->input) + naccepted;
+      mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted
+			       : mctx->max_mb_elem_len);
+      err = clean_state_log_if_needed (mctx, dest_idx);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+#ifdef DEBUG
+      assert (dfa->nexts[cur_node_idx] != REG_MISSING);
+#endif
+      new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx];
+
+      dest_state = mctx->state_log[dest_idx];
+      if (dest_state == NULL)
+	dest_nodes = *new_nodes;
+      else
+	{
+	  err = re_node_set_init_union (&dest_nodes,
+					dest_state->entrance_nodes, new_nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+      context = re_string_context_at (&mctx->input, dest_idx - 1,
+				      mctx->eflags);
+      mctx->state_log[dest_idx]
+	= re_acquire_state_context (&err, dfa, &dest_nodes, context);
+      if (dest_state != NULL)
+	re_node_set_free (&dest_nodes);
+      if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0))
+	return err;
+    }
+  return REG_NOERROR;
+}
+#endif /* RE_ENABLE_I18N */
+
+static reg_errcode_t
+internal_function
+transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx i;
+  Idx cur_str_idx = re_string_cur_idx (&mctx->input);
+
+  for (i = 0; i < nodes->nelem; ++i)
+    {
+      Idx dest_str_idx, prev_nelem, bkc_idx;
+      Idx node_idx = nodes->elems[i];
+      unsigned int context;
+      const re_token_t *node = dfa->nodes + node_idx;
+      re_node_set *new_dest_nodes;
+
+      /* Check whether `node' is a backreference or not.  */
+      if (node->type != OP_BACK_REF)
+	continue;
+
+      if (node->constraint)
+	{
+	  context = re_string_context_at (&mctx->input, cur_str_idx,
+					  mctx->eflags);
+	  if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+	    continue;
+	}
+
+      /* `node' is a backreference.
+	 Check the substring which the substring matched.  */
+      bkc_idx = mctx->nbkref_ents;
+      err = get_subexp (mctx, node_idx, cur_str_idx);
+      if (BE (err != REG_NOERROR, 0))
+	goto free_return;
+
+      /* And add the epsilon closures (which is `new_dest_nodes') of
+	 the backreference to appropriate state_log.  */
+#ifdef DEBUG
+      assert (dfa->nexts[node_idx] != REG_MISSING);
+#endif
+      for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx)
+	{
+	  Idx subexp_len;
+	  re_dfastate_t *dest_state;
+	  struct re_backref_cache_entry *bkref_ent;
+	  bkref_ent = mctx->bkref_ents + bkc_idx;
+	  if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
+	    continue;
+	  subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
+	  new_dest_nodes = (subexp_len == 0
+			    ? dfa->eclosures + dfa->edests[node_idx].elems[0]
+			    : dfa->eclosures + dfa->nexts[node_idx]);
+	  dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
+			  - bkref_ent->subexp_from);
+	  context = re_string_context_at (&mctx->input, dest_str_idx - 1,
+					  mctx->eflags);
+	  dest_state = mctx->state_log[dest_str_idx];
+	  prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
+			: mctx->state_log[cur_str_idx]->nodes.nelem);
+	  /* Add `new_dest_node' to state_log.  */
+	  if (dest_state == NULL)
+	    {
+	      mctx->state_log[dest_str_idx]
+		= re_acquire_state_context (&err, dfa, new_dest_nodes,
+					    context);
+	      if (BE (mctx->state_log[dest_str_idx] == NULL
+		      && err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  else
+	    {
+	      re_node_set dest_nodes;
+	      err = re_node_set_init_union (&dest_nodes,
+					    dest_state->entrance_nodes,
+					    new_dest_nodes);
+	      if (BE (err != REG_NOERROR, 0))
+		{
+		  re_node_set_free (&dest_nodes);
+		  goto free_return;
+		}
+	      mctx->state_log[dest_str_idx]
+		= re_acquire_state_context (&err, dfa, &dest_nodes, context);
+	      re_node_set_free (&dest_nodes);
+	      if (BE (mctx->state_log[dest_str_idx] == NULL
+		      && err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	  /* We need to check recursively if the backreference can epsilon
+	     transit.  */
+	  if (subexp_len == 0
+	      && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem)
+	    {
+	      err = check_subexp_matching_top (mctx, new_dest_nodes,
+					       cur_str_idx);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	      err = transit_state_bkref (mctx, new_dest_nodes);
+	      if (BE (err != REG_NOERROR, 0))
+		goto free_return;
+	    }
+	}
+    }
+  err = REG_NOERROR;
+ free_return:
+  return err;
+}
+
+/* Enumerate all the candidates which the backreference BKREF_NODE can match
+   at BKREF_STR_IDX, and register them by match_ctx_add_entry().
+   Note that we might collect inappropriate candidates here.
+   However, the cost of checking them strictly here is too high, then we
+   delay these checking for prune_impossible_nodes().  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+get_subexp (re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  Idx subexp_num, sub_top_idx;
+  const char *buf = (const char *) re_string_get_buffer (&mctx->input);
+  /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
+  Idx cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx);
+  if (cache_idx != REG_MISSING)
+    {
+      const struct re_backref_cache_entry *entry
+	= mctx->bkref_ents + cache_idx;
+      do
+	if (entry->node == bkref_node)
+	  return REG_NOERROR; /* We already checked it.  */
+      while (entry++->more);
+    }
+
+  subexp_num = dfa->nodes[bkref_node].opr.idx;
+
+  /* For each sub expression  */
+  for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx)
+    {
+      reg_errcode_t err;
+      re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
+      re_sub_match_last_t *sub_last;
+      Idx sub_last_idx, sl_str, bkref_str_off;
+
+      if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
+	continue; /* It isn't related.  */
+
+      sl_str = sub_top->str_idx;
+      bkref_str_off = bkref_str_idx;
+      /* At first, check the last node of sub expressions we already
+	 evaluated.  */
+      for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx)
+	{
+	  regoff_t sl_str_diff;
+	  sub_last = sub_top->lasts[sub_last_idx];
+	  sl_str_diff = sub_last->str_idx - sl_str;
+	  /* The matched string by the sub expression match with the substring
+	     at the back reference?  */
+	  if (sl_str_diff > 0)
+	    {
+	      if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0))
+		{
+		  /* Not enough chars for a successful match.  */
+		  if (bkref_str_off + sl_str_diff > mctx->input.len)
+		    break;
+
+		  err = clean_state_log_if_needed (mctx,
+						   bkref_str_off
+						   + sl_str_diff);
+		  if (BE (err != REG_NOERROR, 0))
+		    return err;
+		  buf = (const char *) re_string_get_buffer (&mctx->input);
+		}
+	      if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
+		/* We don't need to search this sub expression any more.  */
+		break;
+	    }
+	  bkref_str_off += sl_str_diff;
+	  sl_str += sl_str_diff;
+	  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+				bkref_str_idx);
+
+	  /* Reload buf, since the preceding call might have reallocated
+	     the buffer.  */
+	  buf = (const char *) re_string_get_buffer (&mctx->input);
+
+	  if (err == REG_NOMATCH)
+	    continue;
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+
+      if (sub_last_idx < sub_top->nlasts)
+	continue;
+      if (sub_last_idx > 0)
+	++sl_str;
+      /* Then, search for the other last nodes of the sub expression.  */
+      for (; sl_str <= bkref_str_idx; ++sl_str)
+	{
+	  Idx cls_node;
+	  regoff_t sl_str_off;
+	  const re_node_set *nodes;
+	  sl_str_off = sl_str - sub_top->str_idx;
+	  /* The matched string by the sub expression match with the substring
+	     at the back reference?  */
+	  if (sl_str_off > 0)
+	    {
+	      if (BE (bkref_str_off >= mctx->input.valid_len, 0))
+		{
+		  /* If we are at the end of the input, we cannot match.  */
+		  if (bkref_str_off >= mctx->input.len)
+		    break;
+
+		  err = extend_buffers (mctx);
+		  if (BE (err != REG_NOERROR, 0))
+		    return err;
+
+		  buf = (const char *) re_string_get_buffer (&mctx->input);
+		}
+	      if (buf [bkref_str_off++] != buf[sl_str - 1])
+		break; /* We don't need to search this sub expression
+			  any more.  */
+	    }
+	  if (mctx->state_log[sl_str] == NULL)
+	    continue;
+	  /* Does this state have a ')' of the sub expression?  */
+	  nodes = &mctx->state_log[sl_str]->nodes;
+	  cls_node = find_subexp_node (dfa, nodes, subexp_num,
+				       OP_CLOSE_SUBEXP);
+	  if (cls_node == REG_MISSING)
+	    continue; /* No.  */
+	  if (sub_top->path == NULL)
+	    {
+	      sub_top->path = calloc (sizeof (state_array_t),
+				      sl_str - sub_top->str_idx + 1);
+	      if (sub_top->path == NULL)
+		return REG_ESPACE;
+	    }
+	  /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
+	     in the current context?  */
+	  err = check_arrival (mctx, sub_top->path, sub_top->node,
+			       sub_top->str_idx, cls_node, sl_str,
+			       OP_CLOSE_SUBEXP);
+	  if (err == REG_NOMATCH)
+	      continue;
+	  if (BE (err != REG_NOERROR, 0))
+	      return err;
+	  sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str);
+	  if (BE (sub_last == NULL, 0))
+	    return REG_ESPACE;
+	  err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node,
+				bkref_str_idx);
+	  if (err == REG_NOMATCH)
+	    continue;
+	}
+    }
+  return REG_NOERROR;
+}
+
+/* Helper functions for get_subexp().  */
+
+/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
+   If it can arrive, register the sub expression expressed with SUB_TOP
+   and SUB_LAST.  */
+
+static reg_errcode_t
+internal_function
+get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top,
+		re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str)
+{
+  reg_errcode_t err;
+  Idx to_idx;
+  /* Can the subexpression arrive the back reference?  */
+  err = check_arrival (mctx, &sub_last->path, sub_last->node,
+		       sub_last->str_idx, bkref_node, bkref_str,
+		       OP_OPEN_SUBEXP);
+  if (err != REG_NOERROR)
+    return err;
+  err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx,
+			     sub_last->str_idx);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
+  return clean_state_log_if_needed (mctx, to_idx);
+}
+
+/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
+   Search '(' if FL_OPEN, or search ')' otherwise.
+   TODO: This function isn't efficient...
+	 Because there might be more than one nodes whose types are
+	 OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+	 nodes.
+	 E.g. RE: (a){2}  */
+
+static Idx
+internal_function
+find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes,
+		  Idx subexp_idx, int type)
+{
+  Idx cls_idx;
+  for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx)
+    {
+      Idx cls_node = nodes->elems[cls_idx];
+      const re_token_t *node = dfa->nodes + cls_node;
+      if (node->type == type
+	  && node->opr.idx == subexp_idx)
+	return cls_node;
+    }
+  return REG_MISSING;
+}
+
+/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
+   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
+   heavily reused.
+   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+check_arrival (re_match_context_t *mctx, state_array_t *path, Idx top_node,
+	       Idx top_str, Idx last_node, Idx last_str, int type)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err = REG_NOERROR;
+  Idx subexp_num, backup_cur_idx, str_idx, null_cnt;
+  re_dfastate_t *cur_state = NULL;
+  re_node_set *cur_nodes, next_nodes;
+  re_dfastate_t **backup_state_log;
+  unsigned int context;
+
+  subexp_num = dfa->nodes[top_node].opr.idx;
+  /* Extend the buffer if we need.  */
+  if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0))
+    {
+      re_dfastate_t **new_array;
+      Idx old_alloc = path->alloc;
+      Idx new_alloc = old_alloc + last_str + mctx->max_mb_elem_len + 1;
+      if (BE (new_alloc < old_alloc, 0)
+	  || BE (SIZE_MAX / sizeof (re_dfastate_t *) < new_alloc, 0))
+	return REG_ESPACE;
+      new_array = re_realloc (path->array, re_dfastate_t *, new_alloc);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      path->array = new_array;
+      path->alloc = new_alloc;
+      memset (new_array + old_alloc, '\0',
+	      sizeof (re_dfastate_t *) * (path->alloc - old_alloc));
+    }
+
+  str_idx = path->next_idx ? path->next_idx : top_str;
+
+  /* Temporary modify MCTX.  */
+  backup_state_log = mctx->state_log;
+  backup_cur_idx = mctx->input.cur_idx;
+  mctx->state_log = path->array;
+  mctx->input.cur_idx = str_idx;
+
+  /* Setup initial node set.  */
+  context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+  if (str_idx == top_str)
+    {
+      err = re_node_set_init_1 (&next_nodes, top_node);
+      if (BE (err != REG_NOERROR, 0))
+	return err;
+      err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+      if (BE (err != REG_NOERROR, 0))
+	{
+	  re_node_set_free (&next_nodes);
+	  return err;
+	}
+    }
+  else
+    {
+      cur_state = mctx->state_log[str_idx];
+      if (cur_state && cur_state->has_backref)
+	{
+	  err = re_node_set_init_copy (&next_nodes, &cur_state->nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+      else
+	re_node_set_init_empty (&next_nodes);
+    }
+  if (str_idx == top_str || (cur_state && cur_state->has_backref))
+    {
+      if (next_nodes.nelem)
+	{
+	  err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+				    subexp_num, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+	{
+	  re_node_set_free (&next_nodes);
+	  return err;
+	}
+      mctx->state_log[str_idx] = cur_state;
+    }
+
+  for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;)
+    {
+      re_node_set_empty (&next_nodes);
+      if (mctx->state_log[str_idx + 1])
+	{
+	  err = re_node_set_merge (&next_nodes,
+				   &mctx->state_log[str_idx + 1]->nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      if (cur_state)
+	{
+	  err = check_arrival_add_next_nodes (mctx, str_idx,
+					      &cur_state->non_eps_nodes,
+					      &next_nodes);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      ++str_idx;
+      if (next_nodes.nelem)
+	{
+	  err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	  err = expand_bkref_cache (mctx, &next_nodes, str_idx,
+				    subexp_num, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&next_nodes);
+	      return err;
+	    }
+	}
+      context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags);
+      cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context);
+      if (BE (cur_state == NULL && err != REG_NOERROR, 0))
+	{
+	  re_node_set_free (&next_nodes);
+	  return err;
+	}
+      mctx->state_log[str_idx] = cur_state;
+      null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
+    }
+  re_node_set_free (&next_nodes);
+  cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
+	       : &mctx->state_log[last_str]->nodes);
+  path->next_idx = str_idx;
+
+  /* Fix MCTX.  */
+  mctx->state_log = backup_state_log;
+  mctx->input.cur_idx = backup_cur_idx;
+
+  /* Then check the current node set has the node LAST_NODE.  */
+  if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node))
+    return REG_NOERROR;
+
+  return REG_NOMATCH;
+}
+
+/* Helper functions for check_arrival.  */
+
+/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
+   to NEXT_NODES.
+   TODO: This function is similar to the functions transit_state*(),
+	 however this function has many additional works.
+	 Can't we unify them?  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+check_arrival_add_next_nodes (re_match_context_t *mctx, Idx str_idx,
+			      re_node_set *cur_nodes, re_node_set *next_nodes)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  bool ok;
+  Idx cur_idx;
+#ifdef RE_ENABLE_I18N
+  reg_errcode_t err = REG_NOERROR;
+#endif
+  re_node_set union_set;
+  re_node_set_init_empty (&union_set);
+  for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx)
+    {
+      int naccepted = 0;
+      Idx cur_node = cur_nodes->elems[cur_idx];
+#ifdef DEBUG
+      re_token_type_t type = dfa->nodes[cur_node].type;
+      assert (!IS_EPSILON_NODE (type));
+#endif
+#ifdef RE_ENABLE_I18N
+      /* If the node may accept `multi byte'.  */
+      if (dfa->nodes[cur_node].accept_mb)
+	{
+	  naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input,
+					       str_idx);
+	  if (naccepted > 1)
+	    {
+	      re_dfastate_t *dest_state;
+	      Idx next_node = dfa->nexts[cur_node];
+	      Idx next_idx = str_idx + naccepted;
+	      dest_state = mctx->state_log[next_idx];
+	      re_node_set_empty (&union_set);
+	      if (dest_state)
+		{
+		  err = re_node_set_merge (&union_set, &dest_state->nodes);
+		  if (BE (err != REG_NOERROR, 0))
+		    {
+		      re_node_set_free (&union_set);
+		      return err;
+		    }
+		}
+	      ok = re_node_set_insert (&union_set, next_node);
+	      if (BE (! ok, 0))
+		{
+		  re_node_set_free (&union_set);
+		  return REG_ESPACE;
+		}
+	      mctx->state_log[next_idx] = re_acquire_state (&err, dfa,
+							    &union_set);
+	      if (BE (mctx->state_log[next_idx] == NULL
+		      && err != REG_NOERROR, 0))
+		{
+		  re_node_set_free (&union_set);
+		  return err;
+		}
+	    }
+	}
+#endif /* RE_ENABLE_I18N */
+      if (naccepted
+	  || check_node_accept (mctx, dfa->nodes + cur_node, str_idx))
+	{
+	  ok = re_node_set_insert (next_nodes, dfa->nexts[cur_node]);
+	  if (BE (! ok, 0))
+	    {
+	      re_node_set_free (&union_set);
+	      return REG_ESPACE;
+	    }
+	}
+    }
+  re_node_set_free (&union_set);
+  return REG_NOERROR;
+}
+
+/* For all the nodes in CUR_NODES, add the epsilon closures of them to
+   CUR_NODES, however exclude the nodes which are:
+    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
+    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
+*/
+
+static reg_errcode_t
+internal_function
+check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes,
+			  Idx ex_subexp, int type)
+{
+  reg_errcode_t err;
+  Idx idx, outside_node;
+  re_node_set new_nodes;
+#ifdef DEBUG
+  assert (cur_nodes->nelem);
+#endif
+  err = re_node_set_alloc (&new_nodes, cur_nodes->nelem);
+  if (BE (err != REG_NOERROR, 0))
+    return err;
+  /* Create a new node set NEW_NODES with the nodes which are epsilon
+     closures of the node in CUR_NODES.  */
+
+  for (idx = 0; idx < cur_nodes->nelem; ++idx)
+    {
+      Idx cur_node = cur_nodes->elems[idx];
+      const re_node_set *eclosure = dfa->eclosures + cur_node;
+      outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type);
+      if (outside_node == REG_MISSING)
+	{
+	  /* There are no problematic nodes, just merge them.  */
+	  err = re_node_set_merge (&new_nodes, eclosure);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&new_nodes);
+	      return err;
+	    }
+	}
+      else
+	{
+	  /* There are problematic nodes, re-calculate incrementally.  */
+	  err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node,
+					      ex_subexp, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    {
+	      re_node_set_free (&new_nodes);
+	      return err;
+	    }
+	}
+    }
+  re_node_set_free (cur_nodes);
+  *cur_nodes = new_nodes;
+  return REG_NOERROR;
+}
+
+/* Helper function for check_arrival_expand_ecl.
+   Check incrementally the epsilon closure of TARGET, and if it isn't
+   problematic append it to DST_NODES.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes,
+			      Idx target, Idx ex_subexp, int type)
+{
+  Idx cur_node;
+  for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);)
+    {
+      bool ok;
+
+      if (dfa->nodes[cur_node].type == type
+	  && dfa->nodes[cur_node].opr.idx == ex_subexp)
+	{
+	  if (type == OP_CLOSE_SUBEXP)
+	    {
+	      ok = re_node_set_insert (dst_nodes, cur_node);
+	      if (BE (! ok, 0))
+		return REG_ESPACE;
+	    }
+	  break;
+	}
+      ok = re_node_set_insert (dst_nodes, cur_node);
+      if (BE (! ok, 0))
+	return REG_ESPACE;
+      if (dfa->edests[cur_node].nelem == 0)
+	break;
+      if (dfa->edests[cur_node].nelem == 2)
+	{
+	  reg_errcode_t err;
+	  err = check_arrival_expand_ecl_sub (dfa, dst_nodes,
+					      dfa->edests[cur_node].elems[1],
+					      ex_subexp, type);
+	  if (BE (err != REG_NOERROR, 0))
+	    return err;
+	}
+      cur_node = dfa->edests[cur_node].elems[0];
+    }
+  return REG_NOERROR;
+}
+
+
+/* For all the back references in the current state, calculate the
+   destination of the back references by the appropriate entry
+   in MCTX->BKREF_ENTS.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes,
+		    Idx cur_str, Idx subexp_num, int type)
+{
+  const re_dfa_t *const dfa = mctx->dfa;
+  reg_errcode_t err;
+  Idx cache_idx_start = search_cur_bkref_entry (mctx, cur_str);
+  struct re_backref_cache_entry *ent;
+
+  if (cache_idx_start == REG_MISSING)
+    return REG_NOERROR;
+
+ restart:
+  ent = mctx->bkref_ents + cache_idx_start;
+  do
+    {
+      Idx to_idx, next_node;
+
+      /* Is this entry ENT is appropriate?  */
+      if (!re_node_set_contains (cur_nodes, ent->node))
+	continue; /* No.  */
+
+      to_idx = cur_str + ent->subexp_to - ent->subexp_from;
+      /* Calculate the destination of the back reference, and append it
+	 to MCTX->STATE_LOG.  */
+      if (to_idx == cur_str)
+	{
+	  /* The backreference did epsilon transit, we must re-check all the
+	     node in the current state.  */
+	  re_node_set new_dests;
+	  reg_errcode_t err2, err3;
+	  next_node = dfa->edests[ent->node].elems[0];
+	  if (re_node_set_contains (cur_nodes, next_node))
+	    continue;
+	  err = re_node_set_init_1 (&new_dests, next_node);
+	  err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type);
+	  err3 = re_node_set_merge (cur_nodes, &new_dests);
+	  re_node_set_free (&new_dests);
+	  if (BE (err != REG_NOERROR || err2 != REG_NOERROR
+		  || err3 != REG_NOERROR, 0))
+	    {
+	      err = (err != REG_NOERROR ? err
+		     : (err2 != REG_NOERROR ? err2 : err3));
+	      return err;
+	    }
+	  /* TODO: It is still inefficient...  */
+	  goto restart;
+	}
+      else
+	{
+	  re_node_set union_set;
+	  next_node = dfa->nexts[ent->node];
+	  if (mctx->state_log[to_idx])
+	    {
+	      bool ok;
+	      if (re_node_set_contains (&mctx->state_log[to_idx]->nodes,
+					next_node))
+		continue;
+	      err = re_node_set_init_copy (&union_set,
+					   &mctx->state_log[to_idx]->nodes);
+	      ok = re_node_set_insert (&union_set, next_node);
+	      if (BE (err != REG_NOERROR || ! ok, 0))
+		{
+		  re_node_set_free (&union_set);
+		  err = err != REG_NOERROR ? err : REG_ESPACE;
+		  return err;
+		}
+	    }
+	  else
+	    {
+	      err = re_node_set_init_1 (&union_set, next_node);
+	      if (BE (err != REG_NOERROR, 0))
+		return err;
+	    }
+	  mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set);
+	  re_node_set_free (&union_set);
+	  if (BE (mctx->state_log[to_idx] == NULL
+		  && err != REG_NOERROR, 0))
+	    return err;
+	}
+    }
+  while (ent++->more);
+  return REG_NOERROR;
+}
+
+/* Build transition table for the state.
+   Return true if successful.  */
+
+static bool
+internal_function
+build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
+{
+  reg_errcode_t err;
+  Idx i, j;
+  int ch;
+  bool need_word_trtable = false;
+  bitset_word_t elem, mask;
+  bool dests_node_malloced = false;
+  bool dest_states_malloced = false;
+  Idx ndests; /* Number of the destination states from `state'.  */
+  re_dfastate_t **trtable;
+  re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
+  re_node_set follows, *dests_node;
+  bitset_t *dests_ch;
+  bitset_t acceptable;
+
+  struct dests_alloc
+  {
+    re_node_set dests_node[SBC_MAX];
+    bitset_t dests_ch[SBC_MAX];
+  } *dests_alloc;
+
+  /* We build DFA states which corresponds to the destination nodes
+     from `state'.  `dests_node[i]' represents the nodes which i-th
+     destination state contains, and `dests_ch[i]' represents the
+     characters which i-th destination state accepts.  */
+  if (__libc_use_alloca (sizeof (struct dests_alloc)))
+    dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
+  else
+    {
+      dests_alloc = re_malloc (struct dests_alloc, 1);
+      if (BE (dests_alloc == NULL, 0))
+	return false;
+      dests_node_malloced = true;
+    }
+  dests_node = dests_alloc->dests_node;
+  dests_ch = dests_alloc->dests_ch;
+
+  /* Initialize transiton table.  */
+  state->word_trtable = state->trtable = NULL;
+
+  /* At first, group all nodes belonging to `state' into several
+     destinations.  */
+  ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
+  if (BE (! REG_VALID_NONZERO_INDEX (ndests), 0))
+    {
+      if (dests_node_malloced)
+	free (dests_alloc);
+      if (ndests == 0)
+	{
+	  state->trtable = (re_dfastate_t **)
+	    calloc (sizeof (re_dfastate_t *), SBC_MAX);
+          if (BE (state->trtable == NULL, 0))
+            return false;
+	  return true;
+	}
+      return false;
+    }
+
+  err = re_node_set_alloc (&follows, ndests + 1);
+  if (BE (err != REG_NOERROR, 0))
+    goto out_free;
+
+  /* Avoid arithmetic overflow in size calculation.  */
+  if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
+	    / (3 * sizeof (re_dfastate_t *)))
+	   < ndests),
+	  0))
+    goto out_free;
+
+  if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
+			 + ndests * 3 * sizeof (re_dfastate_t *)))
+    dest_states = (re_dfastate_t **)
+      alloca (ndests * 3 * sizeof (re_dfastate_t *));
+  else
+    {
+      dest_states = (re_dfastate_t **)
+	malloc (ndests * 3 * sizeof (re_dfastate_t *));
+      if (BE (dest_states == NULL, 0))
+	{
+out_free:
+	  if (dest_states_malloced)
+	    free (dest_states);
+	  re_node_set_free (&follows);
+	  for (i = 0; i < ndests; ++i)
+	    re_node_set_free (dests_node + i);
+	  if (dests_node_malloced)
+	    free (dests_alloc);
+	  return false;
+	}
+      dest_states_malloced = true;
+    }
+  dest_states_word = dest_states + ndests;
+  dest_states_nl = dest_states_word + ndests;
+  bitset_empty (acceptable);
+
+  /* Then build the states for all destinations.  */
+  for (i = 0; i < ndests; ++i)
+    {
+      Idx next_node;
+      re_node_set_empty (&follows);
+      /* Merge the follows of this destination states.  */
+      for (j = 0; j < dests_node[i].nelem; ++j)
+	{
+	  next_node = dfa->nexts[dests_node[i].elems[j]];
+	  if (next_node != REG_MISSING)
+	    {
+	      err = re_node_set_merge (&follows, dfa->eclosures + next_node);
+	      if (BE (err != REG_NOERROR, 0))
+		goto out_free;
+	    }
+	}
+      dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
+      if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0))
+	goto out_free;
+      /* If the new state has context constraint,
+	 build appropriate states for these contexts.  */
+      if (dest_states[i]->has_constraint)
+	{
+	  dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
+							  CONTEXT_WORD);
+	  if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0))
+	    goto out_free;
+
+	  if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
+	    need_word_trtable = true;
+
+	  dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+							CONTEXT_NEWLINE);
+	  if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0))
+	    goto out_free;
+	}
+      else
+	{
+	  dest_states_word[i] = dest_states[i];
+	  dest_states_nl[i] = dest_states[i];
+	}
+      bitset_merge (acceptable, dests_ch[i]);
+    }
+
+  if (!BE (need_word_trtable, 0))
+    {
+      /* We don't care about whether the following character is a word
+	 character, or we are in a single-byte character set so we can
+	 discern by looking at the character code: allocate a
+	 256-entry transition table.  */
+      trtable = state->trtable =
+	(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+      if (BE (trtable == NULL, 0))
+	goto out_free;
+
+      /* For all characters ch...:  */
+      for (i = 0; i < BITSET_WORDS; ++i)
+	for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+	     elem;
+	     mask <<= 1, elem >>= 1, ++ch)
+	  if (BE (elem & 1, 0))
+	    {
+	      /* There must be exactly one destination which accepts
+		 character ch.  See group_nodes_into_DFAstates.  */
+	      for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+		;
+
+	      /* j-th destination accepts the word character ch.  */
+	      if (dfa->word_char[i] & mask)
+		trtable[ch] = dest_states_word[j];
+	      else
+		trtable[ch] = dest_states[j];
+	    }
+    }
+  else
+    {
+      /* We care about whether the following character is a word
+	 character, and we are in a multi-byte character set: discern
+	 by looking at the character code: build two 256-entry
+	 transition tables, one starting at trtable[0] and one
+	 starting at trtable[SBC_MAX].  */
+      trtable = state->word_trtable =
+	(re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+      if (BE (trtable == NULL, 0))
+	goto out_free;
+
+      /* For all characters ch...:  */
+      for (i = 0; i < BITSET_WORDS; ++i)
+	for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+	     elem;
+	     mask <<= 1, elem >>= 1, ++ch)
+	  if (BE (elem & 1, 0))
+	    {
+	      /* There must be exactly one destination which accepts
+		 character ch.  See group_nodes_into_DFAstates.  */
+	      for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+		;
+
+	      /* j-th destination accepts the word character ch.  */
+	      trtable[ch] = dest_states[j];
+	      trtable[ch + SBC_MAX] = dest_states_word[j];
+	    }
+    }
+
+  /* new line */
+  if (bitset_contain (acceptable, NEWLINE_CHAR))
+    {
+      /* The current state accepts newline character.  */
+      for (j = 0; j < ndests; ++j)
+	if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
+	  {
+	    /* k-th destination accepts newline character.  */
+	    trtable[NEWLINE_CHAR] = dest_states_nl[j];
+	    if (need_word_trtable)
+	      trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
+	    /* There must be only one destination which accepts
+	       newline.  See group_nodes_into_DFAstates.  */
+	    break;
+	  }
+    }
+
+  if (dest_states_malloced)
+    free (dest_states);
+
+  re_node_set_free (&follows);
+  for (i = 0; i < ndests; ++i)
+    re_node_set_free (dests_node + i);
+
+  if (dests_node_malloced)
+    free (dests_alloc);
+
+  return true;
+}
+
+/* Group all nodes belonging to STATE into several destinations.
+   Then for all destinations, set the nodes belonging to the destination
+   to DESTS_NODE[i] and set the characters accepted by the destination
+   to DEST_CH[i].  This function return the number of destinations.  */
+
+static Idx
+internal_function
+group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+			    re_node_set *dests_node, bitset_t *dests_ch)
+{
+  reg_errcode_t err;
+  bool ok;
+  Idx i, j, k;
+  Idx ndests; /* Number of the destinations from `state'.  */
+  bitset_t accepts; /* Characters a node can accept.  */
+  const re_node_set *cur_nodes = &state->nodes;
+  bitset_empty (accepts);
+  ndests = 0;
+
+  /* For all the nodes belonging to `state',  */
+  for (i = 0; i < cur_nodes->nelem; ++i)
+    {
+      re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
+      re_token_type_t type = node->type;
+      unsigned int constraint = node->constraint;
+
+      /* Enumerate all single byte character this node can accept.  */
+      if (type == CHARACTER)
+	bitset_set (accepts, node->opr.c);
+      else if (type == SIMPLE_BRACKET)
+	{
+	  bitset_merge (accepts, node->opr.sbcset);
+	}
+      else if (type == OP_PERIOD)
+	{
+#ifdef RE_ENABLE_I18N
+	  if (dfa->mb_cur_max > 1)
+	    bitset_merge (accepts, dfa->sb_char);
+	  else
+#endif
+	    bitset_set_all (accepts);
+	  if (!(dfa->syntax & RE_DOT_NEWLINE))
+	    bitset_clear (accepts, '\n');
+	  if (dfa->syntax & RE_DOT_NOT_NULL)
+	    bitset_clear (accepts, '\0');
+	}
+#ifdef RE_ENABLE_I18N
+      else if (type == OP_UTF8_PERIOD)
+	{
+	  if (ASCII_CHARS % BITSET_WORD_BITS == 0)
+	    memset (accepts, -1, ASCII_CHARS / CHAR_BIT);
+	  else
+	    bitset_merge (accepts, utf8_sb_map);
+	  if (!(dfa->syntax & RE_DOT_NEWLINE))
+	    bitset_clear (accepts, '\n');
+	  if (dfa->syntax & RE_DOT_NOT_NULL)
+	    bitset_clear (accepts, '\0');
+	}
+#endif
+      else
+	continue;
+
+      /* Check the `accepts' and sift the characters which are not
+	 match it the context.  */
+      if (constraint)
+	{
+	  if (constraint & NEXT_NEWLINE_CONSTRAINT)
+	    {
+	      bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
+	      bitset_empty (accepts);
+	      if (accepts_newline)
+		bitset_set (accepts, NEWLINE_CHAR);
+	      else
+		continue;
+	    }
+	  if (constraint & NEXT_ENDBUF_CONSTRAINT)
+	    {
+	      bitset_empty (accepts);
+	      continue;
+	    }
+
+	  if (constraint & NEXT_WORD_CONSTRAINT)
+	    {
+	      bitset_word_t any_set = 0;
+	      if (type == CHARACTER && !node->word_char)
+		{
+		  bitset_empty (accepts);
+		  continue;
+		}
+#ifdef RE_ENABLE_I18N
+	      if (dfa->mb_cur_max > 1)
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j]));
+	      else
+#endif
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= dfa->word_char[j]);
+	      if (!any_set)
+		continue;
+	    }
+	  if (constraint & NEXT_NOTWORD_CONSTRAINT)
+	    {
+	      bitset_word_t any_set = 0;
+	      if (type == CHARACTER && node->word_char)
+		{
+		  bitset_empty (accepts);
+		  continue;
+		}
+#ifdef RE_ENABLE_I18N
+	      if (dfa->mb_cur_max > 1)
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j]));
+	      else
+#endif
+		for (j = 0; j < BITSET_WORDS; ++j)
+		  any_set |= (accepts[j] &= ~dfa->word_char[j]);
+	      if (!any_set)
+		continue;
+	    }
+	}
+
+      /* Then divide `accepts' into DFA states, or create a new
+	 state.  Above, we make sure that accepts is not empty.  */
+      for (j = 0; j < ndests; ++j)
+	{
+	  bitset_t intersec; /* Intersection sets, see below.  */
+	  bitset_t remains;
+	  /* Flags, see below.  */
+	  bitset_word_t has_intersec, not_subset, not_consumed;
+
+	  /* Optimization, skip if this state doesn't accept the character.  */
+	  if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
+	    continue;
+
+	  /* Enumerate the intersection set of this state and `accepts'.  */
+	  has_intersec = 0;
+	  for (k = 0; k < BITSET_WORDS; ++k)
+	    has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
+	  /* And skip if the intersection set is empty.  */
+	  if (!has_intersec)
+	    continue;
+
+	  /* Then check if this state is a subset of `accepts'.  */
+	  not_subset = not_consumed = 0;
+	  for (k = 0; k < BITSET_WORDS; ++k)
+	    {
+	      not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
+	      not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
+	    }
+
+	  /* If this state isn't a subset of `accepts', create a
+	     new group state, which has the `remains'. */
+	  if (not_subset)
+	    {
+	      bitset_copy (dests_ch[ndests], remains);
+	      bitset_copy (dests_ch[j], intersec);
+	      err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
+	      if (BE (err != REG_NOERROR, 0))
+		goto error_return;
+	      ++ndests;
+	    }
+
+	  /* Put the position in the current group. */
+	  ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
+	  if (BE (! ok, 0))
+	    goto error_return;
+
+	  /* If all characters are consumed, go to next node. */
+	  if (!not_consumed)
+	    break;
+	}
+      /* Some characters remain, create a new group. */
+      if (j == ndests)
+	{
+	  bitset_copy (dests_ch[ndests], accepts);
+	  err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
+	  if (BE (err != REG_NOERROR, 0))
+	    goto error_return;
+	  ++ndests;
+	  bitset_empty (accepts);
+	}
+    }
+  return ndests;
+ error_return:
+  for (j = 0; j < ndests; ++j)
+    re_node_set_free (dests_node + j);
+  return REG_MISSING;
+}
+
+#ifdef RE_ENABLE_I18N
+/* Check how many bytes the node `dfa->nodes[node_idx]' accepts.
+   Return the number of the bytes the node accepts.
+   STR_IDX is the current index of the input string.
+
+   This function handles the nodes which can accept one character, or
+   one collating element like '.', '[a-z]', opposite to the other nodes
+   can only accept one byte.  */
+
+static int
+internal_function
+check_node_accept_bytes (const re_dfa_t *dfa, Idx node_idx,
+			 const re_string_t *input, Idx str_idx)
+{
+  const re_token_t *node = dfa->nodes + node_idx;
+  int char_len, elem_len;
+  Idx i;
+
+  if (BE (node->type == OP_UTF8_PERIOD, 0))
+    {
+      unsigned char c = re_string_byte_at (input, str_idx), d;
+      if (BE (c < 0xc2, 1))
+	return 0;
+
+      if (str_idx + 2 > input->len)
+	return 0;
+
+      d = re_string_byte_at (input, str_idx + 1);
+      if (c < 0xe0)
+	return (d < 0x80 || d > 0xbf) ? 0 : 2;
+      else if (c < 0xf0)
+	{
+	  char_len = 3;
+	  if (c == 0xe0 && d < 0xa0)
+	    return 0;
+	}
+      else if (c < 0xf8)
+	{
+	  char_len = 4;
+	  if (c == 0xf0 && d < 0x90)
+	    return 0;
+	}
+      else if (c < 0xfc)
+	{
+	  char_len = 5;
+	  if (c == 0xf8 && d < 0x88)
+	    return 0;
+	}
+      else if (c < 0xfe)
+	{
+	  char_len = 6;
+	  if (c == 0xfc && d < 0x84)
+	    return 0;
+	}
+      else
+	return 0;
+
+      if (str_idx + char_len > input->len)
+	return 0;
+
+      for (i = 1; i < char_len; ++i)
+	{
+	  d = re_string_byte_at (input, str_idx + i);
+	  if (d < 0x80 || d > 0xbf)
+	    return 0;
+	}
+      return char_len;
+    }
+
+  char_len = re_string_char_size_at (input, str_idx);
+  if (node->type == OP_PERIOD)
+    {
+      if (char_len <= 1)
+	return 0;
+      /* FIXME: I don't think this if is needed, as both '\n'
+	 and '\0' are char_len == 1.  */
+      /* '.' accepts any one character except the following two cases.  */
+      if ((!(dfa->syntax & RE_DOT_NEWLINE) &&
+	   re_string_byte_at (input, str_idx) == '\n') ||
+	  ((dfa->syntax & RE_DOT_NOT_NULL) &&
+	   re_string_byte_at (input, str_idx) == '\0'))
+	return 0;
+      return char_len;
+    }
+
+  elem_len = re_string_elem_size_at (input, str_idx);
+  if ((elem_len <= 1 && char_len <= 1) || char_len == 0)
+    return 0;
+
+  if (node->type == COMPLEX_BRACKET)
+    {
+      const re_charset_t *cset = node->opr.mbcset;
+# ifdef _LIBC
+      const unsigned char *pin
+	= ((const unsigned char *) re_string_get_buffer (input) + str_idx);
+      Idx j;
+      uint32_t nrules;
+# endif /* _LIBC */
+      int match_len = 0;
+      wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars)
+		    ? re_string_wchar_at (input, str_idx) : 0);
+
+      /* match with multibyte character?  */
+      for (i = 0; i < cset->nmbchars; ++i)
+	if (wc == cset->mbchars[i])
+	  {
+	    match_len = char_len;
+	    goto check_node_accept_bytes_match;
+	  }
+      /* match with character_class?  */
+      for (i = 0; i < cset->nchar_classes; ++i)
+	{
+	  wctype_t wt = cset->char_classes[i];
+	  if (__iswctype (wc, wt))
+	    {
+	      match_len = char_len;
+	      goto check_node_accept_bytes_match;
+	    }
+	}
+
+# ifdef _LIBC
+      nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+      if (nrules != 0)
+	{
+	  unsigned int in_collseq = 0;
+	  const int32_t *table, *indirect;
+	  const unsigned char *weights, *extra;
+	  const char *collseqwc;
+	  int32_t idx;
+	  /* This #include defines a local function!  */
+#  include <locale/weight.h>
+
+	  /* match with collating_symbol?  */
+	  if (cset->ncoll_syms)
+	    extra = (const unsigned char *)
+	      _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+	  for (i = 0; i < cset->ncoll_syms; ++i)
+	    {
+	      const unsigned char *coll_sym = extra + cset->coll_syms[i];
+	      /* Compare the length of input collating element and
+		 the length of current collating element.  */
+	      if (*coll_sym != elem_len)
+		continue;
+	      /* Compare each bytes.  */
+	      for (j = 0; j < *coll_sym; j++)
+		if (pin[j] != coll_sym[1 + j])
+		  break;
+	      if (j == *coll_sym)
+		{
+		  /* Match if every bytes is equal.  */
+		  match_len = j;
+		  goto check_node_accept_bytes_match;
+		}
+	    }
+
+	  if (cset->nranges)
+	    {
+	      if (elem_len <= char_len)
+		{
+		  collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC);
+		  in_collseq = __collseq_table_lookup (collseqwc, wc);
+		}
+	      else
+		in_collseq = find_collation_sequence_value (pin, elem_len);
+	    }
+	  /* match with range expression?  */
+	  for (i = 0; i < cset->nranges; ++i)
+	    if (cset->range_starts[i] <= in_collseq
+		&& in_collseq <= cset->range_ends[i])
+	      {
+		match_len = elem_len;
+		goto check_node_accept_bytes_match;
+	      }
+
+	  /* match with equivalence_class?  */
+	  if (cset->nequiv_classes)
+	    {
+	      const unsigned char *cp = pin;
+	      table = (const int32_t *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB);
+	      weights = (const unsigned char *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB);
+	      extra = (const unsigned char *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB);
+	      indirect = (const int32_t *)
+		_NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB);
+	      int32_t idx = findidx (&cp);
+	      if (idx > 0)
+		for (i = 0; i < cset->nequiv_classes; ++i)
+		  {
+		    int32_t equiv_class_idx = cset->equiv_classes[i];
+		    size_t weight_len = weights[idx & 0xffffff];
+		    if (weight_len == weights[equiv_class_idx & 0xffffff]
+			&& (idx >> 24) == (equiv_class_idx >> 24))
+		      {
+			Idx cnt = 0;
+
+			idx &= 0xffffff;
+			equiv_class_idx &= 0xffffff;
+
+			while (cnt <= weight_len
+			       && (weights[equiv_class_idx + 1 + cnt]
+				   == weights[idx + 1 + cnt]))
+			  ++cnt;
+			if (cnt > weight_len)
+			  {
+			    match_len = elem_len;
+			    goto check_node_accept_bytes_match;
+			  }
+		      }
+		  }
+	    }
+	}
+      else
+# endif /* _LIBC */
+	{
+	  /* match with range expression?  */
+#if __GNUC__ >= 2 && ! (__STDC_VERSION__ < 199901L && __STRICT_ANSI__)
+	  wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'};
+#else
+	  wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'};
+	  cmp_buf[2] = wc;
+#endif
+	  for (i = 0; i < cset->nranges; ++i)
+	    {
+	      cmp_buf[0] = cset->range_starts[i];
+	      cmp_buf[4] = cset->range_ends[i];
+	      if (wcscoll (cmp_buf, cmp_buf + 2) <= 0
+		  && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0)
+		{
+		  match_len = char_len;
+		  goto check_node_accept_bytes_match;
+		}
+	    }
+	}
+    check_node_accept_bytes_match:
+      if (!cset->non_match)
+	return match_len;
+      else
+	{
+	  if (match_len > 0)
+	    return 0;
+	  else
+	    return (elem_len > char_len) ? elem_len : char_len;
+	}
+    }
+  return 0;
+}
+
+# ifdef _LIBC
+static unsigned int
+internal_function
+find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len)
+{
+  uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES);
+  if (nrules == 0)
+    {
+      if (mbs_len == 1)
+	{
+	  /* No valid character.  Match it as a single byte character.  */
+	  const unsigned char *collseq = (const unsigned char *)
+	    _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB);
+	  return collseq[mbs[0]];
+	}
+      return UINT_MAX;
+    }
+  else
+    {
+      int32_t idx;
+      const unsigned char *extra = (const unsigned char *)
+	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB);
+      int32_t extrasize = (const unsigned char *)
+	_NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra;
+
+      for (idx = 0; idx < extrasize;)
+	{
+	  int mbs_cnt;
+	  bool found = false;
+	  int32_t elem_mbs_len;
+	  /* Skip the name of collating element name.  */
+	  idx = idx + extra[idx] + 1;
+	  elem_mbs_len = extra[idx++];
+	  if (mbs_len == elem_mbs_len)
+	    {
+	      for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt)
+		if (extra[idx + mbs_cnt] != mbs[mbs_cnt])
+		  break;
+	      if (mbs_cnt == elem_mbs_len)
+		/* Found the entry.  */
+		found = true;
+	    }
+	  /* Skip the byte sequence of the collating element.  */
+	  idx += elem_mbs_len;
+	  /* Adjust for the alignment.  */
+	  idx = (idx + 3) & ~3;
+	  /* Skip the collation sequence value.  */
+	  idx += sizeof (uint32_t);
+	  /* Skip the wide char sequence of the collating element.  */
+	  idx = idx + sizeof (uint32_t) * (extra[idx] + 1);
+	  /* If we found the entry, return the sequence value.  */
+	  if (found)
+	    return *(uint32_t *) (extra + idx);
+	  /* Skip the collation sequence value.  */
+	  idx += sizeof (uint32_t);
+	}
+      return UINT_MAX;
+    }
+}
+# endif /* _LIBC */
+#endif /* RE_ENABLE_I18N */
+
+/* Check whether the node accepts the byte which is IDX-th
+   byte of the INPUT.  */
+
+static bool
+internal_function
+check_node_accept (const re_match_context_t *mctx, const re_token_t *node,
+		   Idx idx)
+{
+  unsigned char ch;
+  ch = re_string_byte_at (&mctx->input, idx);
+  switch (node->type)
+    {
+    case CHARACTER:
+      if (node->opr.c != ch)
+        return false;
+      break;
+
+    case SIMPLE_BRACKET:
+      if (!bitset_contain (node->opr.sbcset, ch))
+        return false;
+      break;
+
+#ifdef RE_ENABLE_I18N
+    case OP_UTF8_PERIOD:
+      if (ch >= ASCII_CHARS)
+        return false;
+      /* FALLTHROUGH */
+#endif
+    case OP_PERIOD:
+      if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
+	  || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
+	return false;
+      break;
+
+    default:
+      return false;
+    }
+
+  if (node->constraint)
+    {
+      /* The node has constraints.  Check whether the current context
+	 satisfies the constraints.  */
+      unsigned int context = re_string_context_at (&mctx->input, idx,
+						   mctx->eflags);
+      if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context))
+	return false;
+    }
+
+  return true;
+}
+
+/* Extend the buffers, if the buffers have run out.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+extend_buffers (re_match_context_t *mctx)
+{
+  reg_errcode_t ret;
+  re_string_t *pstr = &mctx->input;
+
+  /* Avoid overflow.  */
+  if (BE (SIZE_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0))
+    return REG_ESPACE;
+
+  /* Double the lengthes of the buffers.  */
+  ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2);
+  if (BE (ret != REG_NOERROR, 0))
+    return ret;
+
+  if (mctx->state_log != NULL)
+    {
+      /* And double the length of state_log.  */
+      /* XXX We have no indication of the size of this buffer.  If this
+	 allocation fail we have no indication that the state_log array
+	 does not have the right size.  */
+      re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *,
+					      pstr->bufs_len + 1);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      mctx->state_log = new_array;
+    }
+
+  /* Then reconstruct the buffers.  */
+  if (pstr->icase)
+    {
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+	{
+	  ret = build_wcs_upper_buffer (pstr);
+	  if (BE (ret != REG_NOERROR, 0))
+	    return ret;
+	}
+      else
+#endif /* RE_ENABLE_I18N  */
+	build_upper_buffer (pstr);
+    }
+  else
+    {
+#ifdef RE_ENABLE_I18N
+      if (pstr->mb_cur_max > 1)
+	build_wcs_buffer (pstr);
+      else
+#endif /* RE_ENABLE_I18N  */
+	{
+	  if (pstr->trans != NULL)
+	    re_string_translate_buffer (pstr);
+	}
+    }
+  return REG_NOERROR;
+}
+
+

+/* Functions for matching context.  */
+
+/* Initialize MCTX.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+match_ctx_init (re_match_context_t *mctx, int eflags, Idx n)
+{
+  mctx->eflags = eflags;
+  mctx->match_last = REG_MISSING;
+  if (n > 0)
+    {
+      /* Avoid overflow.  */
+      size_t max_object_size =
+	MAX (sizeof (struct re_backref_cache_entry),
+	     sizeof (re_sub_match_top_t *));
+      if (BE (SIZE_MAX / max_object_size < n, 0))
+	return REG_ESPACE;
+
+      mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n);
+      mctx->sub_tops = re_malloc (re_sub_match_top_t *, n);
+      if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0))
+	return REG_ESPACE;
+    }
+  /* Already zero-ed by the caller.
+     else
+       mctx->bkref_ents = NULL;
+     mctx->nbkref_ents = 0;
+     mctx->nsub_tops = 0;  */
+  mctx->abkref_ents = n;
+  mctx->max_mb_elem_len = 1;
+  mctx->asub_tops = n;
+  return REG_NOERROR;
+}
+
+/* Clean the entries which depend on the current input in MCTX.
+   This function must be invoked when the matcher changes the start index
+   of the input, or changes the input string.  */
+
+static void
+internal_function
+match_ctx_clean (re_match_context_t *mctx)
+{
+  Idx st_idx;
+  for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx)
+    {
+      Idx sl_idx;
+      re_sub_match_top_t *top = mctx->sub_tops[st_idx];
+      for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx)
+	{
+	  re_sub_match_last_t *last = top->lasts[sl_idx];
+	  re_free (last->path.array);
+	  re_free (last);
+	}
+      re_free (top->lasts);
+      if (top->path)
+	{
+	  re_free (top->path->array);
+	  re_free (top->path);
+	}
+      free (top);
+    }
+
+  mctx->nsub_tops = 0;
+  mctx->nbkref_ents = 0;
+}
+
+/* Free all the memory associated with MCTX.  */
+
+static void
+internal_function
+match_ctx_free (re_match_context_t *mctx)
+{
+  /* First, free all the memory associated with MCTX->SUB_TOPS.  */
+  match_ctx_clean (mctx);
+  re_free (mctx->sub_tops);
+  re_free (mctx->bkref_ents);
+}
+
+/* Add a new backreference entry to MCTX.
+   Note that we assume that caller never call this function with duplicate
+   entry, and call with STR_IDX which isn't smaller than any existing entry.
+*/
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+match_ctx_add_entry (re_match_context_t *mctx, Idx node, Idx str_idx, Idx from,
+		     Idx to)
+{
+  if (mctx->nbkref_ents >= mctx->abkref_ents)
+    {
+      struct re_backref_cache_entry* new_entry;
+      new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry,
+			      mctx->abkref_ents * 2);
+      if (BE (new_entry == NULL, 0))
+	{
+	  re_free (mctx->bkref_ents);
+	  return REG_ESPACE;
+	}
+      mctx->bkref_ents = new_entry;
+      memset (mctx->bkref_ents + mctx->nbkref_ents, '\0',
+	      sizeof (struct re_backref_cache_entry) * mctx->abkref_ents);
+      mctx->abkref_ents *= 2;
+    }
+  if (mctx->nbkref_ents > 0
+      && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
+    mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
+
+  mctx->bkref_ents[mctx->nbkref_ents].node = node;
+  mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
+  mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
+  mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
+
+  /* This is a cache that saves negative results of check_dst_limits_calc_pos.
+     If bit N is clear, means that this entry won't epsilon-transition to
+     an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If
+     it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
+     such node.
+
+     A backreference does not epsilon-transition unless it is empty, so set
+     to all zeros if FROM != TO.  */
+  mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
+    = (from == to ? -1 : 0);
+
+  mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
+  if (mctx->max_mb_elem_len < to - from)
+    mctx->max_mb_elem_len = to - from;
+  return REG_NOERROR;
+}
+
+/* Return the first entry with the same str_idx, or REG_MISSING if none is
+   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
+
+static Idx
+internal_function
+search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
+{
+  Idx left, right, mid, last;
+  last = right = mctx->nbkref_ents;
+  for (left = 0; left < right;)
+    {
+      mid = (left + right) / 2;
+      if (mctx->bkref_ents[mid].str_idx < str_idx)
+	left = mid + 1;
+      else
+	right = mid;
+    }
+  if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
+    return left;
+  else
+    return REG_MISSING;
+}
+
+/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
+   at STR_IDX.  */
+
+static reg_errcode_t
+internal_function __attribute_warn_unused_result__
+match_ctx_add_subtop (re_match_context_t *mctx, Idx node, Idx str_idx)
+{
+#ifdef DEBUG
+  assert (mctx->sub_tops != NULL);
+  assert (mctx->asub_tops > 0);
+#endif
+  if (BE (mctx->nsub_tops == mctx->asub_tops, 0))
+    {
+      Idx new_asub_tops = mctx->asub_tops * 2;
+      re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops,
+						   re_sub_match_top_t *,
+						   new_asub_tops);
+      if (BE (new_array == NULL, 0))
+	return REG_ESPACE;
+      mctx->sub_tops = new_array;
+      mctx->asub_tops = new_asub_tops;
+    }
+  mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t));
+  if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0))
+    return REG_ESPACE;
+  mctx->sub_tops[mctx->nsub_tops]->node = node;
+  mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
+  return REG_NOERROR;
+}
+
+/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
+   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
+
+static re_sub_match_last_t *
+internal_function
+match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
+{
+  re_sub_match_last_t *new_entry;
+  if (BE (subtop->nlasts == subtop->alasts, 0))
+    {
+      Idx new_alasts = 2 * subtop->alasts + 1;
+      re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
+						    re_sub_match_last_t *,
+						    new_alasts);
+      if (BE (new_array == NULL, 0))
+	return NULL;
+      subtop->lasts = new_array;
+      subtop->alasts = new_alasts;
+    }
+  new_entry = calloc (1, sizeof (re_sub_match_last_t));
+  if (BE (new_entry != NULL, 1))
+    {
+      subtop->lasts[subtop->nlasts] = new_entry;
+      new_entry->node = node;
+      new_entry->str_idx = str_idx;
+      ++subtop->nlasts;
+    }
+  return new_entry;
+}
+
+static void
+internal_function
+sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+	       re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx)
+{
+  sctx->sifted_states = sifted_sts;
+  sctx->limited_states = limited_sts;
+  sctx->last_node = last_node;
+  sctx->last_str_idx = last_str_idx;
+  re_node_set_init_empty (&sctx->limits);
+}
diff --git a/gl/stdbool.in.h b/gl/stdbool.in.h
new file mode 100644
index 0000000..0f33b19
--- /dev/null
+++ b/gl/stdbool.in.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 2001-2003, 2006-2011 Free Software Foundation, Inc.
+   Written by Bruno Haible <haible at clisp.cons.org>, 2001.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+#ifndef _GL_STDBOOL_H
+#define _GL_STDBOOL_H
+
+/* ISO C 99 <stdbool.h> for platforms that lack it.  */
+
+/* Usage suggestions:
+
+   Programs that use <stdbool.h> should be aware of some limitations
+   and standards compliance issues.
+
+   Standards compliance:
+
+       - <stdbool.h> must be #included before 'bool', 'false', 'true'
+         can be used.
+
+       - You cannot assume that sizeof (bool) == 1.
+
+       - Programs should not undefine the macros bool, true, and false,
+         as C99 lists that as an "obsolescent feature".
+
+   Limitations of this substitute, when used in a C89 environment:
+
+       - <stdbool.h> must be #included before the '_Bool' type can be used.
+
+       - You cannot assume that _Bool is a typedef; it might be a macro.
+
+       - Bit-fields of type 'bool' are not supported.  Portable code
+         should use 'unsigned int foo : 1;' rather than 'bool foo : 1;'.
+
+       - In C99, casts and automatic conversions to '_Bool' or 'bool' are
+         performed in such a way that every nonzero value gets converted
+         to 'true', and zero gets converted to 'false'.  This doesn't work
+         with this substitute.  With this substitute, only the values 0 and 1
+         give the expected result when converted to _Bool' or 'bool'.
+
+       - C99 allows the use of (_Bool)0.0 in constant expressions, but
+         this substitute cannot always provide this property.
+
+   Also, it is suggested that programs use 'bool' rather than '_Bool';
+   this isn't required, but 'bool' is more common.  */
+
+
+/* 7.16. Boolean type and values */
+
+/* BeOS <sys/socket.h> already #defines false 0, true 1.  We use the same
+   definitions below, but temporarily we have to #undef them.  */
+#if defined __BEOS__ && !defined __HAIKU__
+# include <OS.h> /* defines bool but not _Bool */
+# undef false
+# undef true
+#endif
+
+/* For the sake of symbolic names in gdb, we define true and false as
+   enum constants, not only as macros.
+   It is tempting to write
+      typedef enum { false = 0, true = 1 } _Bool;
+   so that gdb prints values of type 'bool' symbolically. But if we do
+   this, values of type '_Bool' may promote to 'int' or 'unsigned int'
+   (see ISO C 99 6.7.2.2.(4)); however, '_Bool' must promote to 'int'
+   (see ISO C 99 6.3.1.1.(2)).  So we add a negative value to the
+   enum; this ensures that '_Bool' promotes to 'int'.  */
+#if defined __cplusplus || (defined __BEOS__ && !defined __HAIKU__)
+  /* A compiler known to have 'bool'.  */
+  /* If the compiler already has both 'bool' and '_Bool', we can assume they
+     are the same types.  */
+# if !@HAVE__BOOL@
+typedef bool _Bool;
+# endif
+#else
+# if !defined __GNUC__
+   /* If @HAVE__BOOL@:
+        Some HP-UX cc and AIX IBM C compiler versions have compiler bugs when
+        the built-in _Bool type is used.  See
+          http://gcc.gnu.org/ml/gcc-patches/2003-12/msg02303.html
+          http://lists.gnu.org/archive/html/bug-coreutils/2005-11/msg00161.html
+          http://lists.gnu.org/archive/html/bug-coreutils/2005-10/msg00086.html
+        Similar bugs are likely with other compilers as well; this file
+        wouldn't be used if <stdbool.h> was working.
+        So we override the _Bool type.
+      If !@HAVE__BOOL@:
+        Need to define _Bool ourselves. As 'signed char' or as an enum type?
+        Use of a typedef, with SunPRO C, leads to a stupid
+          "warning: _Bool is a keyword in ISO C99".
+        Use of an enum type, with IRIX cc, leads to a stupid
+          "warning(1185): enumerated type mixed with another type".
+        Even the existence of an enum type, without a typedef,
+          "Invalid enumerator. (badenum)" with HP-UX cc on Tru64.
+        The only benefit of the enum, debuggability, is not important
+        with these compilers.  So use 'signed char' and no enum.  */
+#  define _Bool signed char
+# else
+   /* With this compiler, trust the _Bool type if the compiler has it.  */
+#  if !@HAVE__BOOL@
+typedef enum { _Bool_must_promote_to_int = -1, false = 0, true = 1 } _Bool;
+#  endif
+# endif
+#endif
+#define bool _Bool
+
+/* The other macros must be usable in preprocessor directives.  */
+#define false 0
+#define true 1
+#define __bool_true_false_are_defined 1
+
+#endif /* _GL_STDBOOL_H */
diff --git a/gl/stddef.in.h b/gl/stddef.in.h
new file mode 100644
index 0000000..70f5a86
--- /dev/null
+++ b/gl/stddef.in.h
@@ -0,0 +1,87 @@
+/* A substitute for POSIX 2008 <stddef.h>, for platforms that have issues.
+
+   Copyright (C) 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/* Written by Eric Blake.  */
+
+/*
+ * POSIX 2008 <stddef.h> for platforms that have issues.
+ * <http://www.opengroup.org/susv3xbd/stddef.h.html>
+ */
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+#if defined __need_wchar_t || defined __need_size_t  \
+  || defined __need_ptrdiff_t || defined __need_NULL \
+  || defined __need_wint_t
+/* Special invocation convention inside gcc header files.  In
+   particular, gcc provides a version of <stddef.h> that blindly
+   redefines NULL even when __need_wint_t was defined, even though
+   wint_t is not normally provided by <stddef.h>.  Hence, we must
+   remember if special invocation has ever been used to obtain wint_t,
+   in which case we need to clean up NULL yet again.  */
+
+# if !(defined _GL_STDDEF_H && defined _GL_STDDEF_WINT_T)
+#  ifdef __need_wint_t
+#   undef _GL_STDDEF_H
+#   define _GL_STDDEF_WINT_T
+#  endif
+#  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+# endif
+
+#else
+/* Normal invocation convention.  */
+
+# ifndef _GL_STDDEF_H
+
+/* The include_next requires a split double-inclusion guard.  */
+
+#  @INCLUDE_NEXT@ @NEXT_STDDEF_H@
+
+#  ifndef _GL_STDDEF_H
+#   define _GL_STDDEF_H
+
+/* On NetBSD 5.0, the definition of NULL lacks proper parentheses.  */
+#if @REPLACE_NULL@
+# undef NULL
+# ifdef __cplusplus
+   /* ISO C++ says that the macro NULL must expand to an integer constant
+      expression, hence '((void *) 0)' is not allowed in C++.  */
+#  if __GNUG__ >= 3
+    /* GNU C++ has a __null macro that behaves like an integer ('int' or
+       'long') but has the same size as a pointer.  Use that, to avoid
+       warnings.  */
+#   define NULL __null
+#  else
+#   define NULL 0L
+#  endif
+# else
+#  define NULL ((void *) 0)
+# endif
+#endif
+
+/* Some platforms lack wchar_t.  */
+#if !@HAVE_WCHAR_T@
+# define wchar_t int
+#endif
+
+#  endif /* _GL_STDDEF_H */
+# endif /* _GL_STDDEF_H */
+#endif /* __need_XXX */
diff --git a/gl/stdint.in.h b/gl/stdint.in.h
new file mode 100644
index 0000000..2502816
--- /dev/null
+++ b/gl/stdint.in.h
@@ -0,0 +1,582 @@
+/* Copyright (C) 2001-2002, 2004-2011 Free Software Foundation, Inc.
+   Written by Paul Eggert, Bruno Haible, Sam Steingold, Peter Burwood.
+   This file is part of gnulib.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/*
+ * ISO C 99 <stdint.h> for platforms that lack it.
+ * <http://www.opengroup.org/susv3xbd/stdint.h.html>
+ */
+
+#ifndef _GL_STDINT_H
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+/* When including a system file that in turn includes <inttypes.h>,
+   use the system <inttypes.h>, not our substitute.  This avoids
+   problems with (for example) VMS, whose <sys/bitypes.h> includes
+   <inttypes.h>.  */
+#define _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+
+/* Get those types that are already defined in other system include
+   files, so that we can "#define int8_t signed char" below without
+   worrying about a later system include file containing a "typedef
+   signed char int8_t;" that will get messed up by our macro.  Our
+   macros should all be consistent with the system versions, except
+   for the "fast" types and macros, which we recommend against using
+   in public interfaces due to compiler differences.  */
+
+#if @HAVE_STDINT_H@
+# if defined __sgi && ! defined __c99
+   /* Bypass IRIX's <stdint.h> if in C89 mode, since it merely annoys users
+      with "This header file is to be used only for c99 mode compilations"
+      diagnostics.  */
+#  define __STDINT_H__
+# endif
+  /* Other systems may have an incomplete or buggy <stdint.h>.
+     Include it before <inttypes.h>, since any "#include <stdint.h>"
+     in <inttypes.h> would reinclude us, skipping our contents because
+     _GL_STDINT_H is defined.
+     The include_next requires a split double-inclusion guard.  */
+# @INCLUDE_NEXT@ @NEXT_STDINT_H@
+#endif
+
+#if ! defined _GL_STDINT_H && ! defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H
+#define _GL_STDINT_H
+
+/* <sys/types.h> defines some of the stdint.h types as well, on glibc,
+   IRIX 6.5, and OpenBSD 3.8 (via <machine/types.h>).
+   AIX 5.2 <sys/types.h> isn't needed and causes troubles.
+   MacOS X 10.4.6 <sys/types.h> includes <stdint.h> (which is us), but
+   relies on the system <stdint.h> definitions, so include
+   <sys/types.h> after @NEXT_STDINT_H at .  */
+#if @HAVE_SYS_TYPES_H@ && ! defined _AIX
+# include <sys/types.h>
+#endif
+
+/* Get LONG_MIN, LONG_MAX, ULONG_MAX.  */
+#include <limits.h>
+
+#if @HAVE_INTTYPES_H@
+  /* In OpenBSD 3.8, <inttypes.h> includes <machine/types.h>, which defines
+     int{8,16,32,64}_t, uint{8,16,32,64}_t and __BIT_TYPES_DEFINED__.
+     <inttypes.h> also defines intptr_t and uintptr_t.  */
+# include <inttypes.h>
+#elif @HAVE_SYS_INTTYPES_H@
+  /* Solaris 7 <sys/inttypes.h> has the types except the *_fast*_t types, and
+     the macros except for *_FAST*_*, INTPTR_MIN, PTRDIFF_MIN, PTRDIFF_MAX.  */
+# include <sys/inttypes.h>
+#endif
+
+#if @HAVE_SYS_BITYPES_H@ && ! defined __BIT_TYPES_DEFINED__
+  /* Linux libc4 >= 4.6.7 and libc5 have a <sys/bitypes.h> that defines
+     int{8,16,32,64}_t and __BIT_TYPES_DEFINED__.  In libc5 >= 5.2.2 it is
+     included by <sys/types.h>.  */
+# include <sys/bitypes.h>
+#endif
+
+#undef _GL_JUST_INCLUDE_SYSTEM_INTTYPES_H
+
+/* Minimum and maximum values for a integer type under the usual assumption.
+   Return an unspecified value if BITS == 0, adding a check to pacify
+   picky compilers.  */
+
+#define _STDINT_MIN(signed, bits, zero) \
+  ((signed) ? (- ((zero) + 1) << ((bits) ? (bits) - 1 : 0)) : (zero))
+
+#define _STDINT_MAX(signed, bits, zero) \
+  ((signed) \
+   ? ~ _STDINT_MIN (signed, bits, zero) \
+   : /* The expression for the unsigned case.  The subtraction of (signed) \
+        is a nop in the unsigned case and avoids "signed integer overflow" \
+        warnings in the signed case.  */ \
+     ((((zero) + 1) << ((bits) ? (bits) - 1 - (signed) : 0)) - 1) * 2 + 1)
+
+/* 7.18.1.1. Exact-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits.  */
+
+#undef int8_t
+#undef uint8_t
+typedef signed char gl_int8_t;
+typedef unsigned char gl_uint8_t;
+#define int8_t gl_int8_t
+#define uint8_t gl_uint8_t
+
+#undef int16_t
+#undef uint16_t
+typedef short int gl_int16_t;
+typedef unsigned short int gl_uint16_t;
+#define int16_t gl_int16_t
+#define uint16_t gl_uint16_t
+
+#undef int32_t
+#undef uint32_t
+typedef int gl_int32_t;
+typedef unsigned int gl_uint32_t;
+#define int32_t gl_int32_t
+#define uint32_t gl_uint32_t
+
+/* If the system defines INT64_MAX, assume int64_t works.  That way,
+   if the underlying platform defines int64_t to be a 64-bit long long
+   int, the code below won't mistakenly define it to be a 64-bit long
+   int, which would mess up C++ name mangling.  We must use #ifdef
+   rather than #if, to avoid an error with HP-UX 10.20 cc.  */
+
+#ifdef INT64_MAX
+# define GL_INT64_T
+#else
+/* Do not undefine int64_t if gnulib is not being used with 64-bit
+   types, since otherwise it breaks platforms like Tandem/NSK.  */
+# if LONG_MAX >> 31 >> 31 == 1
+#  undef int64_t
+typedef long int gl_int64_t;
+#  define int64_t gl_int64_t
+#  define GL_INT64_T
+# elif defined _MSC_VER
+#  undef int64_t
+typedef __int64 gl_int64_t;
+#  define int64_t gl_int64_t
+#  define GL_INT64_T
+# elif @HAVE_LONG_LONG_INT@
+#  undef int64_t
+typedef long long int gl_int64_t;
+#  define int64_t gl_int64_t
+#  define GL_INT64_T
+# endif
+#endif
+
+#ifdef UINT64_MAX
+# define GL_UINT64_T
+#else
+# if ULONG_MAX >> 31 >> 31 >> 1 == 1
+#  undef uint64_t
+typedef unsigned long int gl_uint64_t;
+#  define uint64_t gl_uint64_t
+#  define GL_UINT64_T
+# elif defined _MSC_VER
+#  undef uint64_t
+typedef unsigned __int64 gl_uint64_t;
+#  define uint64_t gl_uint64_t
+#  define GL_UINT64_T
+# elif @HAVE_UNSIGNED_LONG_LONG_INT@
+#  undef uint64_t
+typedef unsigned long long int gl_uint64_t;
+#  define uint64_t gl_uint64_t
+#  define GL_UINT64_T
+# endif
+#endif
+
+/* Avoid collision with Solaris 2.5.1 <pthread.h> etc.  */
+#define _UINT8_T
+#define _UINT32_T
+#define _UINT64_T
+
+
+/* 7.18.1.2. Minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
+   are the same as the corresponding N_t types.  */
+
+#undef int_least8_t
+#undef uint_least8_t
+#undef int_least16_t
+#undef uint_least16_t
+#undef int_least32_t
+#undef uint_least32_t
+#undef int_least64_t
+#undef uint_least64_t
+#define int_least8_t int8_t
+#define uint_least8_t uint8_t
+#define int_least16_t int16_t
+#define uint_least16_t uint16_t
+#define int_least32_t int32_t
+#define uint_least32_t uint32_t
+#ifdef GL_INT64_T
+# define int_least64_t int64_t
+#endif
+#ifdef GL_UINT64_T
+# define uint_least64_t uint64_t
+#endif
+
+/* 7.18.1.3. Fastest minimum-width integer types */
+
+/* Note: Other <stdint.h> substitutes may define these types differently.
+   It is not recommended to use these types in public header files. */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
+   are taken from the same list of types.  Assume that 'long int'
+   is fast enough for all narrower integers.  */
+
+#undef int_fast8_t
+#undef uint_fast8_t
+#undef int_fast16_t
+#undef uint_fast16_t
+#undef int_fast32_t
+#undef uint_fast32_t
+#undef int_fast64_t
+#undef uint_fast64_t
+typedef long int gl_int_fast8_t;
+typedef unsigned long int gl_uint_fast8_t;
+typedef long int gl_int_fast16_t;
+typedef unsigned long int gl_uint_fast16_t;
+typedef long int gl_int_fast32_t;
+typedef unsigned long int gl_uint_fast32_t;
+#define int_fast8_t gl_int_fast8_t
+#define uint_fast8_t gl_uint_fast8_t
+#define int_fast16_t gl_int_fast16_t
+#define uint_fast16_t gl_uint_fast16_t
+#define int_fast32_t gl_int_fast32_t
+#define uint_fast32_t gl_uint_fast32_t
+#ifdef GL_INT64_T
+# define int_fast64_t int64_t
+#endif
+#ifdef GL_UINT64_T
+# define uint_fast64_t uint64_t
+#endif
+
+/* 7.18.1.4. Integer types capable of holding object pointers */
+
+#undef intptr_t
+#undef uintptr_t
+typedef long int gl_intptr_t;
+typedef unsigned long int gl_uintptr_t;
+#define intptr_t gl_intptr_t
+#define uintptr_t gl_uintptr_t
+
+/* 7.18.1.5. Greatest-width integer types */
+
+/* Note: These types are compiler dependent. It may be unwise to use them in
+   public header files. */
+
+#undef intmax_t
+#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+typedef long long int gl_intmax_t;
+# define intmax_t gl_intmax_t
+#elif defined GL_INT64_T
+# define intmax_t int64_t
+#else
+typedef long int gl_intmax_t;
+# define intmax_t gl_intmax_t
+#endif
+
+#undef uintmax_t
+#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+typedef unsigned long long int gl_uintmax_t;
+# define uintmax_t gl_uintmax_t
+#elif defined GL_UINT64_T
+# define uintmax_t uint64_t
+#else
+typedef unsigned long int gl_uintmax_t;
+# define uintmax_t gl_uintmax_t
+#endif
+
+/* Verify that intmax_t and uintmax_t have the same size.  Too much code
+   breaks if this is not the case.  If this check fails, the reason is likely
+   to be found in the autoconf macros.  */
+typedef int _verify_intmax_size[sizeof (intmax_t) == sizeof (uintmax_t)
+                                ? 1 : -1];
+
+/* 7.18.2. Limits of specified-width integer types */
+
+#if ! defined __cplusplus || defined __STDC_LIMIT_MACROS
+
+/* 7.18.2.1. Limits of exact-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits.  */
+
+#undef INT8_MIN
+#undef INT8_MAX
+#undef UINT8_MAX
+#define INT8_MIN  (~ INT8_MAX)
+#define INT8_MAX  127
+#define UINT8_MAX  255
+
+#undef INT16_MIN
+#undef INT16_MAX
+#undef UINT16_MAX
+#define INT16_MIN  (~ INT16_MAX)
+#define INT16_MAX  32767
+#define UINT16_MAX  65535
+
+#undef INT32_MIN
+#undef INT32_MAX
+#undef UINT32_MAX
+#define INT32_MIN  (~ INT32_MAX)
+#define INT32_MAX  2147483647
+#define UINT32_MAX  4294967295U
+
+#if defined GL_INT64_T && ! defined INT64_MAX
+/* Prefer (- INTMAX_C (1) << 63) over (~ INT64_MAX) because SunPRO C 5.0
+   evaluates the latter incorrectly in preprocessor expressions.  */
+# define INT64_MIN  (- INTMAX_C (1) << 63)
+# define INT64_MAX  INTMAX_C (9223372036854775807)
+#endif
+
+#if defined GL_UINT64_T && ! defined UINT64_MAX
+# define UINT64_MAX  UINTMAX_C (18446744073709551615)
+#endif
+
+/* 7.18.2.2. Limits of minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits. Therefore the leastN_t types
+   are the same as the corresponding N_t types.  */
+
+#undef INT_LEAST8_MIN
+#undef INT_LEAST8_MAX
+#undef UINT_LEAST8_MAX
+#define INT_LEAST8_MIN  INT8_MIN
+#define INT_LEAST8_MAX  INT8_MAX
+#define UINT_LEAST8_MAX  UINT8_MAX
+
+#undef INT_LEAST16_MIN
+#undef INT_LEAST16_MAX
+#undef UINT_LEAST16_MAX
+#define INT_LEAST16_MIN  INT16_MIN
+#define INT_LEAST16_MAX  INT16_MAX
+#define UINT_LEAST16_MAX  UINT16_MAX
+
+#undef INT_LEAST32_MIN
+#undef INT_LEAST32_MAX
+#undef UINT_LEAST32_MAX
+#define INT_LEAST32_MIN  INT32_MIN
+#define INT_LEAST32_MAX  INT32_MAX
+#define UINT_LEAST32_MAX  UINT32_MAX
+
+#undef INT_LEAST64_MIN
+#undef INT_LEAST64_MAX
+#ifdef GL_INT64_T
+# define INT_LEAST64_MIN  INT64_MIN
+# define INT_LEAST64_MAX  INT64_MAX
+#endif
+
+#undef UINT_LEAST64_MAX
+#ifdef GL_UINT64_T
+# define UINT_LEAST64_MAX  UINT64_MAX
+#endif
+
+/* 7.18.2.3. Limits of fastest minimum-width integer types */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits. Therefore the fastN_t types
+   are taken from the same list of types.  */
+
+#undef INT_FAST8_MIN
+#undef INT_FAST8_MAX
+#undef UINT_FAST8_MAX
+#define INT_FAST8_MIN  LONG_MIN
+#define INT_FAST8_MAX  LONG_MAX
+#define UINT_FAST8_MAX  ULONG_MAX
+
+#undef INT_FAST16_MIN
+#undef INT_FAST16_MAX
+#undef UINT_FAST16_MAX
+#define INT_FAST16_MIN  LONG_MIN
+#define INT_FAST16_MAX  LONG_MAX
+#define UINT_FAST16_MAX  ULONG_MAX
+
+#undef INT_FAST32_MIN
+#undef INT_FAST32_MAX
+#undef UINT_FAST32_MAX
+#define INT_FAST32_MIN  LONG_MIN
+#define INT_FAST32_MAX  LONG_MAX
+#define UINT_FAST32_MAX  ULONG_MAX
+
+#undef INT_FAST64_MIN
+#undef INT_FAST64_MAX
+#ifdef GL_INT64_T
+# define INT_FAST64_MIN  INT64_MIN
+# define INT_FAST64_MAX  INT64_MAX
+#endif
+
+#undef UINT_FAST64_MAX
+#ifdef GL_UINT64_T
+# define UINT_FAST64_MAX  UINT64_MAX
+#endif
+
+/* 7.18.2.4. Limits of integer types capable of holding object pointers */
+
+#undef INTPTR_MIN
+#undef INTPTR_MAX
+#undef UINTPTR_MAX
+#define INTPTR_MIN  LONG_MIN
+#define INTPTR_MAX  LONG_MAX
+#define UINTPTR_MAX  ULONG_MAX
+
+/* 7.18.2.5. Limits of greatest-width integer types */
+
+#undef INTMAX_MIN
+#undef INTMAX_MAX
+#ifdef INT64_MAX
+# define INTMAX_MIN  INT64_MIN
+# define INTMAX_MAX  INT64_MAX
+#else
+# define INTMAX_MIN  INT32_MIN
+# define INTMAX_MAX  INT32_MAX
+#endif
+
+#undef UINTMAX_MAX
+#ifdef UINT64_MAX
+# define UINTMAX_MAX  UINT64_MAX
+#else
+# define UINTMAX_MAX  UINT32_MAX
+#endif
+
+/* 7.18.3. Limits of other integer types */
+
+/* ptrdiff_t limits */
+#undef PTRDIFF_MIN
+#undef PTRDIFF_MAX
+#if @APPLE_UNIVERSAL_BUILD@
+# ifdef _LP64
+#  define PTRDIFF_MIN  _STDINT_MIN (1, 64, 0l)
+#  define PTRDIFF_MAX  _STDINT_MAX (1, 64, 0l)
+# else
+#  define PTRDIFF_MIN  _STDINT_MIN (1, 32, 0)
+#  define PTRDIFF_MAX  _STDINT_MAX (1, 32, 0)
+# endif
+#else
+# define PTRDIFF_MIN  \
+    _STDINT_MIN (1, @BITSIZEOF_PTRDIFF_T@, 0 at PTRDIFF_T_SUFFIX@)
+# define PTRDIFF_MAX  \
+    _STDINT_MAX (1, @BITSIZEOF_PTRDIFF_T@, 0 at PTRDIFF_T_SUFFIX@)
+#endif
+
+/* sig_atomic_t limits */
+#undef SIG_ATOMIC_MIN
+#undef SIG_ATOMIC_MAX
+#define SIG_ATOMIC_MIN  \
+   _STDINT_MIN (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
+                0 at SIG_ATOMIC_T_SUFFIX@)
+#define SIG_ATOMIC_MAX  \
+   _STDINT_MAX (@HAVE_SIGNED_SIG_ATOMIC_T@, @BITSIZEOF_SIG_ATOMIC_T@, \
+                0 at SIG_ATOMIC_T_SUFFIX@)
+
+
+/* size_t limit */
+#undef SIZE_MAX
+#if @APPLE_UNIVERSAL_BUILD@
+# ifdef _LP64
+#  define SIZE_MAX  _STDINT_MAX (0, 64, 0ul)
+# else
+#  define SIZE_MAX  _STDINT_MAX (0, 32, 0ul)
+# endif
+#else
+# define SIZE_MAX  _STDINT_MAX (0, @BITSIZEOF_SIZE_T@, 0 at SIZE_T_SUFFIX@)
+#endif
+
+/* wchar_t limits */
+/* Get WCHAR_MIN, WCHAR_MAX.
+   This include is not on the top, above, because on OSF/1 4.0 we have a
+   sequence of nested includes
+   <wchar.h> -> <stdio.h> -> <getopt.h> -> <stdlib.h>, and the latter includes
+   <stdint.h> and assumes its types are already defined.  */
+#if ! (defined WCHAR_MIN && defined WCHAR_MAX)
+# define _GL_JUST_INCLUDE_SYSTEM_WCHAR_H
+# include <wchar.h>
+# undef _GL_JUST_INCLUDE_SYSTEM_WCHAR_H
+#endif
+#undef WCHAR_MIN
+#undef WCHAR_MAX
+#define WCHAR_MIN  \
+   _STDINT_MIN (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0 at WCHAR_T_SUFFIX@)
+#define WCHAR_MAX  \
+   _STDINT_MAX (@HAVE_SIGNED_WCHAR_T@, @BITSIZEOF_WCHAR_T@, 0 at WCHAR_T_SUFFIX@)
+
+/* wint_t limits */
+#undef WINT_MIN
+#undef WINT_MAX
+#define WINT_MIN  \
+   _STDINT_MIN (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0 at WINT_T_SUFFIX@)
+#define WINT_MAX  \
+   _STDINT_MAX (@HAVE_SIGNED_WINT_T@, @BITSIZEOF_WINT_T@, 0 at WINT_T_SUFFIX@)
+
+#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */
+
+/* 7.18.4. Macros for integer constants */
+
+#if ! defined __cplusplus || defined __STDC_CONSTANT_MACROS
+
+/* 7.18.4.1. Macros for minimum-width integer constants */
+/* According to ISO C 99 Technical Corrigendum 1 */
+
+/* Here we assume a standard architecture where the hardware integer
+   types have 8, 16, 32, optionally 64 bits, and int is 32 bits.  */
+
+#undef INT8_C
+#undef UINT8_C
+#define INT8_C(x) x
+#define UINT8_C(x) x
+
+#undef INT16_C
+#undef UINT16_C
+#define INT16_C(x) x
+#define UINT16_C(x) x
+
+#undef INT32_C
+#undef UINT32_C
+#define INT32_C(x) x
+#define UINT32_C(x) x ## U
+
+#undef INT64_C
+#undef UINT64_C
+#if LONG_MAX >> 31 >> 31 == 1
+# define INT64_C(x) x##L
+#elif defined _MSC_VER
+# define INT64_C(x) x##i64
+#elif @HAVE_LONG_LONG_INT@
+# define INT64_C(x) x##LL
+#endif
+#if ULONG_MAX >> 31 >> 31 >> 1 == 1
+# define UINT64_C(x) x##UL
+#elif defined _MSC_VER
+# define UINT64_C(x) x##ui64
+#elif @HAVE_UNSIGNED_LONG_LONG_INT@
+# define UINT64_C(x) x##ULL
+#endif
+
+/* 7.18.4.2. Macros for greatest-width integer constants */
+
+#undef INTMAX_C
+#if @HAVE_LONG_LONG_INT@ && LONG_MAX >> 30 == 1
+# define INTMAX_C(x)   x##LL
+#elif defined GL_INT64_T
+# define INTMAX_C(x)   INT64_C(x)
+#else
+# define INTMAX_C(x)   x##L
+#endif
+
+#undef UINTMAX_C
+#if @HAVE_UNSIGNED_LONG_LONG_INT@ && ULONG_MAX >> 31 == 1
+# define UINTMAX_C(x)  x##ULL
+#elif defined GL_UINT64_T
+# define UINTMAX_C(x)  UINT64_C(x)
+#else
+# define UINTMAX_C(x)  x##UL
+#endif
+
+#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */
+
+#endif /* _GL_STDINT_H */
+#endif /* !defined _GL_STDINT_H && !defined _GL_JUST_INCLUDE_SYSTEM_STDINT_H */
diff --git a/gl/stdlib.in.h b/gl/stdlib.in.h
new file mode 100644
index 0000000..4e850e1
--- /dev/null
+++ b/gl/stdlib.in.h
@@ -0,0 +1,726 @@
+/* A GNU-like <stdlib.h>.
+
+   Copyright (C) 1995, 2001-2004, 2006-2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+#if defined __need_malloc_and_calloc
+/* Special invocation convention inside glibc header files.  */
+
+#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+
+#else
+/* Normal invocation convention.  */
+
+#ifndef _GL_STDLIB_H
+
+/* The include_next requires a split double-inclusion guard.  */
+#@INCLUDE_NEXT@ @NEXT_STDLIB_H@
+
+#ifndef _GL_STDLIB_H
+#define _GL_STDLIB_H
+
+/* NetBSD 5.0 mis-defines NULL.  */
+#include <stddef.h>
+
+/* MirBSD 10 defines WEXITSTATUS in <sys/wait.h>, not in <stdlib.h>.  */
+#if @GNULIB_SYSTEM_POSIX@ && !defined WEXITSTATUS
+# include <sys/wait.h>
+#endif
+
+/* Solaris declares getloadavg() in <sys/loadavg.h>.  */
+#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@
+# include <sys/loadavg.h>
+#endif
+
+/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included
+   from <stdlib.h> if _REENTRANT is defined.  Include it always.  */
+#if @HAVE_RANDOM_H@
+# include <random.h>
+#endif
+
+#if !@HAVE_STRUCT_RANDOM_DATA@ || (@GNULIB_RANDOM_R@ && !@HAVE_RANDOM_R@) \
+    || defined GNULIB_POSIXCHECK
+# include <stdint.h>
+#endif
+
+#if !@HAVE_STRUCT_RANDOM_DATA@
+/* Define 'struct random_data'.
+   But allow multiple gnulib generated <stdlib.h> replacements to coexist.  */
+# if !GNULIB_defined_struct_random_data
+struct random_data
+{
+  int32_t *fptr;                /* Front pointer.  */
+  int32_t *rptr;                /* Rear pointer.  */
+  int32_t *state;               /* Array of state values.  */
+  int rand_type;                /* Type of random number generator.  */
+  int rand_deg;                 /* Degree of random number generator.  */
+  int rand_sep;                 /* Distance between front and rear.  */
+  int32_t *end_ptr;             /* Pointer behind state table.  */
+};
+#  define GNULIB_defined_struct_random_data 1
+# endif
+#endif
+
+#if (@GNULIB_MKSTEMP@ || @GNULIB_GETSUBOPT@ || defined GNULIB_POSIXCHECK) && ! defined __GLIBC__ && !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+/* On MacOS X 10.3, only <unistd.h> declares mkstemp.  */
+/* On Cygwin 1.7.1, only <unistd.h> declares getsubopt.  */
+/* But avoid namespace pollution on glibc systems and native Windows.  */
+# include <unistd.h>
+#endif
+
+#ifndef __attribute__
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
+#  define __attribute__(Spec)   /* empty */
+# endif
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Some systems do not define EXIT_*, despite otherwise supporting C89.  */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere
+   with proper operation of xargs.  */
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#elif EXIT_FAILURE != 1
+# undef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+
+#if @GNULIB__EXIT@
+/* Terminate the current process with the given return code, without running
+   the 'atexit' handlers.  */
+# if !@HAVE__EXIT@
+_GL_FUNCDECL_SYS (_Exit, void, (int status) __attribute__ ((__noreturn__)));
+# endif
+_GL_CXXALIAS_SYS (_Exit, void, (int status));
+_GL_CXXALIASWARN (_Exit);
+#elif defined GNULIB_POSIXCHECK
+# undef _Exit
+# if HAVE_RAW_DECL__EXIT
+_GL_WARN_ON_USE (_Exit, "_Exit is unportable - "
+                 "use gnulib module _Exit for portability");
+# endif
+#endif
+
+
+#if @GNULIB_ATOLL@
+/* Parse a signed decimal integer.
+   Returns the value of the integer.  Errors are not detected.  */
+# if !@HAVE_ATOLL@
+_GL_FUNCDECL_SYS (atoll, long long, (const char *string) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (atoll, long long, (const char *string));
+_GL_CXXALIASWARN (atoll);
+#elif defined GNULIB_POSIXCHECK
+# undef atoll
+# if HAVE_RAW_DECL_ATOLL
+_GL_WARN_ON_USE (atoll, "atoll is unportable - "
+                 "use gnulib module atoll for portability");
+# endif
+#endif
+
+#if @GNULIB_CALLOC_POSIX@
+# if @REPLACE_CALLOC@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef calloc
+#   define calloc rpl_calloc
+#  endif
+_GL_FUNCDECL_RPL (calloc, void *, (size_t nmemb, size_t size));
+_GL_CXXALIAS_RPL (calloc, void *, (size_t nmemb, size_t size));
+# else
+_GL_CXXALIAS_SYS (calloc, void *, (size_t nmemb, size_t size));
+# endif
+_GL_CXXALIASWARN (calloc);
+#elif defined GNULIB_POSIXCHECK
+# undef calloc
+/* Assume calloc is always declared.  */
+_GL_WARN_ON_USE (calloc, "calloc is not POSIX compliant everywhere - "
+                 "use gnulib module calloc-posix for portability");
+#endif
+
+#if @GNULIB_CANONICALIZE_FILE_NAME@
+# if @REPLACE_CANONICALIZE_FILE_NAME@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define canonicalize_file_name rpl_canonicalize_file_name
+#  endif
+_GL_FUNCDECL_RPL (canonicalize_file_name, char *, (const char *name)
+                                                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (canonicalize_file_name, char *, (const char *name));
+# else
+#  if !@HAVE_CANONICALIZE_FILE_NAME@
+_GL_FUNCDECL_SYS (canonicalize_file_name, char *, (const char *name)
+                                                  _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (canonicalize_file_name, char *, (const char *name));
+# endif
+_GL_CXXALIASWARN (canonicalize_file_name);
+#elif defined GNULIB_POSIXCHECK
+# undef canonicalize_file_name
+# if HAVE_RAW_DECL_CANONICALIZE_FILE_NAME
+_GL_WARN_ON_USE (canonicalize_file_name,
+                 "canonicalize_file_name is unportable - "
+                 "use gnulib module canonicalize-lgpl for portability");
+# endif
+#endif
+
+#if @GNULIB_GETLOADAVG@
+/* Store max(NELEM,3) load average numbers in LOADAVG[].
+   The three numbers are the load average of the last 1 minute, the last 5
+   minutes, and the last 15 minutes, respectively.
+   LOADAVG is an array of NELEM numbers.  */
+# if !@HAVE_DECL_GETLOADAVG@
+_GL_FUNCDECL_SYS (getloadavg, int, (double loadavg[], int nelem)
+                                   _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (getloadavg, int, (double loadavg[], int nelem));
+_GL_CXXALIASWARN (getloadavg);
+#elif defined GNULIB_POSIXCHECK
+# undef getloadavg
+# if HAVE_RAW_DECL_GETLOADAVG
+_GL_WARN_ON_USE (getloadavg, "getloadavg is not portable - "
+                 "use gnulib module getloadavg for portability");
+# endif
+#endif
+
+#if @GNULIB_GETSUBOPT@
+/* Assuming *OPTIONP is a comma separated list of elements of the form
+   "token" or "token=value", getsubopt parses the first of these elements.
+   If the first element refers to a "token" that is member of the given
+   NULL-terminated array of tokens:
+     - It replaces the comma with a NUL byte, updates *OPTIONP to point past
+       the first option and the comma, sets *VALUEP to the value of the
+       element (or NULL if it doesn't contain an "=" sign),
+     - It returns the index of the "token" in the given array of tokens.
+   Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined.
+   For more details see the POSIX:2001 specification.
+   http://www.opengroup.org/susv3xsh/getsubopt.html */
+# if !@HAVE_GETSUBOPT@
+_GL_FUNCDECL_SYS (getsubopt, int,
+                  (char **optionp, char *const *tokens, char **valuep)
+                  _GL_ARG_NONNULL ((1, 2, 3)));
+# endif
+_GL_CXXALIAS_SYS (getsubopt, int,
+                  (char **optionp, char *const *tokens, char **valuep));
+_GL_CXXALIASWARN (getsubopt);
+#elif defined GNULIB_POSIXCHECK
+# undef getsubopt
+# if HAVE_RAW_DECL_GETSUBOPT
+_GL_WARN_ON_USE (getsubopt, "getsubopt is unportable - "
+                 "use gnulib module getsubopt for portability");
+# endif
+#endif
+
+#if @GNULIB_GRANTPT@
+/* Change the ownership and access permission of the slave side of the
+   pseudo-terminal whose master side is specified by FD.  */
+# if !@HAVE_GRANTPT@
+_GL_FUNCDECL_SYS (grantpt, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (grantpt, int, (int fd));
+_GL_CXXALIASWARN (grantpt);
+#elif defined GNULIB_POSIXCHECK
+# undef grantpt
+# if HAVE_RAW_DECL_GRANTPT
+_GL_WARN_ON_USE (ptsname, "grantpt is not portable - "
+                 "use gnulib module grantpt for portability");
+# endif
+#endif
+
+#if @GNULIB_MALLOC_POSIX@
+# if @REPLACE_MALLOC@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef malloc
+#   define malloc rpl_malloc
+#  endif
+_GL_FUNCDECL_RPL (malloc, void *, (size_t size));
+_GL_CXXALIAS_RPL (malloc, void *, (size_t size));
+# else
+_GL_CXXALIAS_SYS (malloc, void *, (size_t size));
+# endif
+_GL_CXXALIASWARN (malloc);
+#elif defined GNULIB_POSIXCHECK
+# undef malloc
+/* Assume malloc is always declared.  */
+_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
+                 "use gnulib module malloc-posix for portability");
+#endif
+
+#if @GNULIB_MKDTEMP@
+/* Create a unique temporary directory from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the directory name unique.
+   Returns TEMPLATE, or a null pointer if it cannot get a unique name.
+   The directory is created mode 700.  */
+# if !@HAVE_MKDTEMP@
+_GL_FUNCDECL_SYS (mkdtemp, char *, (char * /*template*/) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkdtemp, char *, (char * /*template*/));
+_GL_CXXALIASWARN (mkdtemp);
+#elif defined GNULIB_POSIXCHECK
+# undef mkdtemp
+# if HAVE_RAW_DECL_MKDTEMP
+_GL_WARN_ON_USE (mkdtemp, "mkdtemp is unportable - "
+                 "use gnulib module mkdtemp for portability");
+# endif
+#endif
+
+#if @GNULIB_MKOSTEMP@
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   The file is then created, with the specified flags, ensuring it didn't exist
+   before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+# if !@HAVE_MKOSTEMP@
+_GL_FUNCDECL_SYS (mkostemp, int, (char * /*template*/, int /*flags*/)
+                                 _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkostemp, int, (char * /*template*/, int /*flags*/));
+_GL_CXXALIASWARN (mkostemp);
+#elif defined GNULIB_POSIXCHECK
+# undef mkostemp
+# if HAVE_RAW_DECL_MKOSTEMP
+_GL_WARN_ON_USE (mkostemp, "mkostemp is unportable - "
+                 "use gnulib module mkostemp for portability");
+# endif
+#endif
+
+#if @GNULIB_MKOSTEMPS@
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE before a suffix of length
+   SUFFIXLEN must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   The file is then created, with the specified flags, ensuring it didn't exist
+   before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+# if !@HAVE_MKOSTEMPS@
+_GL_FUNCDECL_SYS (mkostemps, int,
+                  (char * /*template*/, int /*suffixlen*/, int /*flags*/)
+                  _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkostemps, int,
+                  (char * /*template*/, int /*suffixlen*/, int /*flags*/));
+_GL_CXXALIASWARN (mkostemps);
+#elif defined GNULIB_POSIXCHECK
+# undef mkostemps
+# if HAVE_RAW_DECL_MKOSTEMPS
+_GL_WARN_ON_USE (mkostemps, "mkostemps is unportable - "
+                 "use gnulib module mkostemps for portability");
+# endif
+#endif
+
+#if @GNULIB_MKSTEMP@
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The file is then created, ensuring it didn't exist before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+# if @REPLACE_MKSTEMP@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define mkstemp rpl_mkstemp
+#  endif
+_GL_FUNCDECL_RPL (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (mkstemp, int, (char * /*template*/));
+# else
+#  if ! @HAVE_MKSTEMP@
+_GL_FUNCDECL_SYS (mkstemp, int, (char * /*template*/) _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (mkstemp, int, (char * /*template*/));
+# endif
+_GL_CXXALIASWARN (mkstemp);
+#elif defined GNULIB_POSIXCHECK
+# undef mkstemp
+# if HAVE_RAW_DECL_MKSTEMP
+_GL_WARN_ON_USE (mkstemp, "mkstemp is unportable - "
+                 "use gnulib module mkstemp for portability");
+# endif
+#endif
+
+#if @GNULIB_MKSTEMPS@
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE prior to a suffix of length
+   SUFFIXLEN must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The file is then created, ensuring it didn't exist before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+# if !@HAVE_MKSTEMPS@
+_GL_FUNCDECL_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/)
+                                 _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (mkstemps, int, (char * /*template*/, int /*suffixlen*/));
+_GL_CXXALIASWARN (mkstemps);
+#elif defined GNULIB_POSIXCHECK
+# undef mkstemps
+# if HAVE_RAW_DECL_MKSTEMPS
+_GL_WARN_ON_USE (mkstemps, "mkstemps is unportable - "
+                 "use gnulib module mkstemps for portability");
+# endif
+#endif
+
+#if @GNULIB_PTSNAME@
+/* Return the pathname of the pseudo-terminal slave associated with
+   the master FD is open on, or NULL on errors.  */
+# if !@HAVE_PTSNAME@
+_GL_FUNCDECL_SYS (ptsname, char *, (int fd));
+# endif
+_GL_CXXALIAS_SYS (ptsname, char *, (int fd));
+_GL_CXXALIASWARN (ptsname);
+#elif defined GNULIB_POSIXCHECK
+# undef ptsname
+# if HAVE_RAW_DECL_PTSNAME
+_GL_WARN_ON_USE (ptsname, "ptsname is not portable - "
+                 "use gnulib module ptsname for portability");
+# endif
+#endif
+
+#if @GNULIB_PUTENV@
+# if @REPLACE_PUTENV@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef putenv
+#   define putenv rpl_putenv
+#  endif
+_GL_FUNCDECL_RPL (putenv, int, (char *string) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (putenv, int, (char *string));
+# else
+_GL_CXXALIAS_SYS (putenv, int, (char *string));
+# endif
+_GL_CXXALIASWARN (putenv);
+#endif
+
+
+#if @GNULIB_RANDOM_R@
+# if !@HAVE_RANDOM_R@
+#  ifndef RAND_MAX
+#   define RAND_MAX 2147483647
+#  endif
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (random_r, int, (struct random_data *buf, int32_t *result)
+                                 _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (random_r, int, (struct random_data *buf, int32_t *result));
+_GL_CXXALIASWARN (random_r);
+#elif defined GNULIB_POSIXCHECK
+# undef random_r
+# if HAVE_RAW_DECL_RANDOM_R
+_GL_WARN_ON_USE (random_r, "random_r is unportable - "
+                 "use gnulib module random_r for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (srandom_r, int,
+                  (unsigned int seed, struct random_data *rand_state)
+                  _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (srandom_r, int,
+                  (unsigned int seed, struct random_data *rand_state));
+_GL_CXXALIASWARN (srandom_r);
+#elif defined GNULIB_POSIXCHECK
+# undef srandom_r
+# if HAVE_RAW_DECL_SRANDOM_R
+_GL_WARN_ON_USE (srandom_r, "srandom_r is unportable - "
+                 "use gnulib module random_r for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (initstate_r, int,
+                  (unsigned int seed, char *buf, size_t buf_size,
+                   struct random_data *rand_state)
+                  _GL_ARG_NONNULL ((2, 4)));
+# endif
+_GL_CXXALIAS_SYS (initstate_r, int,
+                  (unsigned int seed, char *buf, size_t buf_size,
+                   struct random_data *rand_state));
+_GL_CXXALIASWARN (initstate_r);
+#elif defined GNULIB_POSIXCHECK
+# undef initstate_r
+# if HAVE_RAW_DECL_INITSTATE_R
+_GL_WARN_ON_USE (initstate_r, "initstate_r is unportable - "
+                 "use gnulib module random_r for portability");
+# endif
+#endif
+
+#if @GNULIB_RANDOM_R@
+# if !@HAVE_RANDOM_R@
+_GL_FUNCDECL_SYS (setstate_r, int,
+                  (char *arg_state, struct random_data *rand_state)
+                  _GL_ARG_NONNULL ((1, 2)));
+# endif
+_GL_CXXALIAS_SYS (setstate_r, int,
+                  (char *arg_state, struct random_data *rand_state));
+_GL_CXXALIASWARN (setstate_r);
+#elif defined GNULIB_POSIXCHECK
+# undef setstate_r
+# if HAVE_RAW_DECL_SETSTATE_R
+_GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
+                 "use gnulib module random_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_REALLOC_POSIX@
+# if @REPLACE_REALLOC@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef realloc
+#   define realloc rpl_realloc
+#  endif
+_GL_FUNCDECL_RPL (realloc, void *, (void *ptr, size_t size));
+_GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));
+# else
+_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size));
+# endif
+_GL_CXXALIASWARN (realloc);
+#elif defined GNULIB_POSIXCHECK
+# undef realloc
+/* Assume realloc is always declared.  */
+_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
+                 "use gnulib module realloc-posix for portability");
+#endif
+
+#if @GNULIB_REALPATH@
+# if @REPLACE_REALPATH@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define realpath rpl_realpath
+#  endif
+_GL_FUNCDECL_RPL (realpath, char *, (const char *name, char *resolved)
+                                    _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (realpath, char *, (const char *name, char *resolved));
+# else
+#  if !@HAVE_REALPATH@
+_GL_FUNCDECL_SYS (realpath, char *, (const char *name, char *resolved)
+                                    _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (realpath, char *, (const char *name, char *resolved));
+# endif
+_GL_CXXALIASWARN (realpath);
+#elif defined GNULIB_POSIXCHECK
+# undef realpath
+# if HAVE_RAW_DECL_REALPATH
+_GL_WARN_ON_USE (realpath, "realpath is unportable - use gnulib module "
+                 "canonicalize or canonicalize-lgpl for portability");
+# endif
+#endif
+
+#if @GNULIB_RPMATCH@
+/* Test a user response to a question.
+   Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear.  */
+# if !@HAVE_RPMATCH@
+_GL_FUNCDECL_SYS (rpmatch, int, (const char *response) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (rpmatch, int, (const char *response));
+_GL_CXXALIASWARN (rpmatch);
+#elif defined GNULIB_POSIXCHECK
+# undef rpmatch
+# if HAVE_RAW_DECL_RPMATCH
+_GL_WARN_ON_USE (rpmatch, "rpmatch is unportable - "
+                 "use gnulib module rpmatch for portability");
+# endif
+#endif
+
+#if @GNULIB_SETENV@
+/* Set NAME to VALUE in the environment.
+   If REPLACE is nonzero, overwrite an existing value.  */
+# if @REPLACE_SETENV@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef setenv
+#   define setenv rpl_setenv
+#  endif
+_GL_FUNCDECL_RPL (setenv, int,
+                  (const char *name, const char *value, int replace)
+                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (setenv, int,
+                  (const char *name, const char *value, int replace));
+# else
+#  if !@HAVE_DECL_SETENV@
+_GL_FUNCDECL_SYS (setenv, int,
+                  (const char *name, const char *value, int replace)
+                  _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (setenv, int,
+                  (const char *name, const char *value, int replace));
+# endif
+# if !(@REPLACE_SETENV@ && !@HAVE_DECL_SETENV@)
+_GL_CXXALIASWARN (setenv);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef setenv
+# if HAVE_RAW_DECL_SETENV
+_GL_WARN_ON_USE (setenv, "setenv is unportable - "
+                 "use gnulib module setenv for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOD@
+ /* Parse a double from STRING, updating ENDP if appropriate.  */
+# if @REPLACE_STRTOD@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define strtod rpl_strtod
+#  endif
+_GL_FUNCDECL_RPL (strtod, double, (const char *str, char **endp)
+                                  _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (strtod, double, (const char *str, char **endp));
+# else
+#  if !@HAVE_STRTOD@
+_GL_FUNCDECL_SYS (strtod, double, (const char *str, char **endp)
+                                  _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (strtod, double, (const char *str, char **endp));
+# endif
+_GL_CXXALIASWARN (strtod);
+#elif defined GNULIB_POSIXCHECK
+# undef strtod
+# if HAVE_RAW_DECL_STRTOD
+_GL_WARN_ON_USE (strtod, "strtod is unportable - "
+                 "use gnulib module strtod for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOLL@
+/* Parse a signed integer whose textual representation starts at STRING.
+   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+   it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+   "0x").
+   If ENDPTR is not NULL, the address of the first byte after the integer is
+   stored in *ENDPTR.
+   Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set
+   to ERANGE.  */
+# if !@HAVE_STRTOLL@
+_GL_FUNCDECL_SYS (strtoll, long long,
+                  (const char *string, char **endptr, int base)
+                  _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtoll, long long,
+                  (const char *string, char **endptr, int base));
+_GL_CXXALIASWARN (strtoll);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoll
+# if HAVE_RAW_DECL_STRTOLL
+_GL_WARN_ON_USE (strtoll, "strtoll is unportable - "
+                 "use gnulib module strtoll for portability");
+# endif
+#endif
+
+#if @GNULIB_STRTOULL@
+/* Parse an unsigned integer whose textual representation starts at STRING.
+   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+   it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+   "0x").
+   If ENDPTR is not NULL, the address of the first byte after the integer is
+   stored in *ENDPTR.
+   Upon overflow, the return value is ULLONG_MAX, and errno is set to
+   ERANGE.  */
+# if !@HAVE_STRTOULL@
+_GL_FUNCDECL_SYS (strtoull, unsigned long long,
+                  (const char *string, char **endptr, int base)
+                  _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (strtoull, unsigned long long,
+                  (const char *string, char **endptr, int base));
+_GL_CXXALIASWARN (strtoull);
+#elif defined GNULIB_POSIXCHECK
+# undef strtoull
+# if HAVE_RAW_DECL_STRTOULL
+_GL_WARN_ON_USE (strtoull, "strtoull is unportable - "
+                 "use gnulib module strtoull for portability");
+# endif
+#endif
+
+#if @GNULIB_UNLOCKPT@
+/* Unlock the slave side of the pseudo-terminal whose master side is specified
+   by FD, so that it can be opened.  */
+# if !@HAVE_UNLOCKPT@
+_GL_FUNCDECL_SYS (unlockpt, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (unlockpt, int, (int fd));
+_GL_CXXALIASWARN (unlockpt);
+#elif defined GNULIB_POSIXCHECK
+# undef unlockpt
+# if HAVE_RAW_DECL_UNLOCKPT
+_GL_WARN_ON_USE (unlockpt, "unlockpt is not portable - "
+                 "use gnulib module unlockpt for portability");
+# endif
+#endif
+
+#if @GNULIB_UNSETENV@
+/* Remove the variable NAME from the environment.  */
+# if @REPLACE_UNSETENV@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef unsetenv
+#   define unsetenv rpl_unsetenv
+#  endif
+_GL_FUNCDECL_RPL (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (unsetenv, int, (const char *name));
+# else
+#  if !@HAVE_DECL_UNSETENV@
+_GL_FUNCDECL_SYS (unsetenv, int, (const char *name) _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (unsetenv, int, (const char *name));
+# endif
+# if !(@REPLACE_UNSETENV@ && !@HAVE_DECL_UNSETENV@)
+_GL_CXXALIASWARN (unsetenv);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef unsetenv
+# if HAVE_RAW_DECL_UNSETENV
+_GL_WARN_ON_USE (unsetenv, "unsetenv is unportable - "
+                 "use gnulib module unsetenv for portability");
+# endif
+#endif
+
+
+#endif /* _GL_STDLIB_H */
+#endif /* _GL_STDLIB_H */
+#endif
diff --git a/gl/streq.h b/gl/streq.h
new file mode 100644
index 0000000..3b52893
--- /dev/null
+++ b/gl/streq.h
@@ -0,0 +1,176 @@
+/* Optimized string comparison.
+   Copyright (C) 2001-2002, 2007, 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation; either version 3 of the License, 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
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno at clisp.org>.  */
+
+#ifndef _GL_STREQ_H
+#define _GL_STREQ_H
+
+#include <string.h>
+
+/* STREQ allows to optimize string comparison with a small literal string.
+     STREQ (s, "EUC-KR", 'E', 'U', 'C', '-', 'K', 'R', 0, 0, 0)
+   is semantically equivalent to
+     strcmp (s, "EUC-KR") == 0
+   just faster.  */
+
+/* Help GCC to generate good code for string comparisons with
+   immediate strings. */
+#if defined (__GNUC__) && defined (__OPTIMIZE__)
+
+static inline int
+streq9 (const char *s1, const char *s2)
+{
+  return strcmp (s1 + 9, s2 + 9) == 0;
+}
+
+static inline int
+streq8 (const char *s1, const char *s2, char s28)
+{
+  if (s1[8] == s28)
+    {
+      if (s28 == 0)
+        return 1;
+      else
+        return streq9 (s1, s2);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq7 (const char *s1, const char *s2, char s27, char s28)
+{
+  if (s1[7] == s27)
+    {
+      if (s27 == 0)
+        return 1;
+      else
+        return streq8 (s1, s2, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq6 (const char *s1, const char *s2, char s26, char s27, char s28)
+{
+  if (s1[6] == s26)
+    {
+      if (s26 == 0)
+        return 1;
+      else
+        return streq7 (s1, s2, s27, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq5 (const char *s1, const char *s2, char s25, char s26, char s27, char s28)
+{
+  if (s1[5] == s25)
+    {
+      if (s25 == 0)
+        return 1;
+      else
+        return streq6 (s1, s2, s26, s27, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq4 (const char *s1, const char *s2, char s24, char s25, char s26, char s27, char s28)
+{
+  if (s1[4] == s24)
+    {
+      if (s24 == 0)
+        return 1;
+      else
+        return streq5 (s1, s2, s25, s26, s27, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq3 (const char *s1, const char *s2, char s23, char s24, char s25, char s26, char s27, char s28)
+{
+  if (s1[3] == s23)
+    {
+      if (s23 == 0)
+        return 1;
+      else
+        return streq4 (s1, s2, s24, s25, s26, s27, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq2 (const char *s1, const char *s2, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
+{
+  if (s1[2] == s22)
+    {
+      if (s22 == 0)
+        return 1;
+      else
+        return streq3 (s1, s2, s23, s24, s25, s26, s27, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq1 (const char *s1, const char *s2, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
+{
+  if (s1[1] == s21)
+    {
+      if (s21 == 0)
+        return 1;
+      else
+        return streq2 (s1, s2, s22, s23, s24, s25, s26, s27, s28);
+    }
+  else
+    return 0;
+}
+
+static inline int
+streq0 (const char *s1, const char *s2, char s20, char s21, char s22, char s23, char s24, char s25, char s26, char s27, char s28)
+{
+  if (s1[0] == s20)
+    {
+      if (s20 == 0)
+        return 1;
+      else
+        return streq1 (s1, s2, s21, s22, s23, s24, s25, s26, s27, s28);
+    }
+  else
+    return 0;
+}
+
+#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
+  streq0 (s1, s2, s20, s21, s22, s23, s24, s25, s26, s27, s28)
+
+#else
+
+#define STREQ(s1,s2,s20,s21,s22,s23,s24,s25,s26,s27,s28) \
+  (strcmp (s1, s2) == 0)
+
+#endif
+
+#endif /* _GL_STREQ_H */
diff --git a/gl/unistd.in.h b/gl/unistd.in.h
new file mode 100644
index 0000000..694e94f
--- /dev/null
+++ b/gl/unistd.in.h
@@ -0,0 +1,1378 @@
+/* Substitute for and wrapper around <unistd.h>.
+   Copyright (C) 2003-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+/* Special invocation convention:
+   - On mingw, several headers, including <winsock2.h>, include <unistd.h>,
+     but we need to ensure that both the system <unistd.h> and <winsock2.h>
+     are completely included before we replace gethostname.  */
+#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \
+  && !defined _GL_WINSOCK2_H_WITNESS && defined _WINSOCK2_H
+/* <unistd.h> is being indirectly included for the first time from
+   <winsock2.h>; avoid declaring any overrides.  */
+# if @HAVE_UNISTD_H@
+#  @INCLUDE_NEXT@ @NEXT_UNISTD_H@
+# else
+#  error unexpected; report this to bug-gnulib at gnu.org
+# endif
+# define _GL_WINSOCK2_H_WITNESS
+
+/* Normal invocation.  */
+#elif !defined _GL_UNISTD_H
+
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_UNISTD_H@
+# @INCLUDE_NEXT@ @NEXT_UNISTD_H@
+#endif
+
+/* Get all possible declarations of gethostname().  */
+#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@ \
+  && !defined _GL_INCLUDING_WINSOCK2_H
+# define _GL_INCLUDING_WINSOCK2_H
+# include <winsock2.h>
+# undef _GL_INCLUDING_WINSOCK2_H
+#endif
+
+#if !defined _GL_UNISTD_H && !defined _GL_INCLUDING_WINSOCK2_H
+#define _GL_UNISTD_H
+
+/* NetBSD 5.0 mis-defines NULL.  Also get size_t.  */
+#include <stddef.h>
+
+/* mingw doesn't define the SEEK_* or *_FILENO macros in <unistd.h>.  */
+/* Cygwin 1.7.1 declares symlinkat in <stdio.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \
+     || ((@GNULIB_SYMLINKAT@ || defined GNULIB_POSIXCHECK) \
+         && defined __CYGWIN__)) \
+    && ! defined __GLIBC__
+# include <stdio.h>
+#endif
+
+/* Cygwin 1.7.1 declares unlinkat in <fcntl.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if (@GNULIB_UNLINKAT@ || defined GNULIB_POSIXCHECK) && defined __CYGWIN__ \
+    && ! defined __GLIBC__
+# include <fcntl.h>
+#endif
+
+/* mingw fails to declare _exit in <unistd.h>.  */
+/* mingw, BeOS, Haiku declare environ in <stdlib.h>, not in <unistd.h>.  */
+/* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#ifndef __GLIBC__
+# include <stdlib.h>
+#endif
+
+/* mingw declares getcwd in <io.h>, not in <unistd.h>.  */
+#if ((@GNULIB_GETCWD@ || defined GNULIB_POSIXCHECK) \
+     && ((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__))
+# include <io.h>
+#endif
+
+/* AIX and OSF/1 5.1 declare getdomainname in <netdb.h>, not in <unistd.h>.
+   NonStop Kernel declares gethostname in <netdb.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if ((@GNULIB_GETDOMAINNAME@ && (defined _AIX || defined __osf__)) \
+     || (@GNULIB_GETHOSTNAME@ && defined __TANDEM)) \
+    && !defined __GLIBC__
+# include <netdb.h>
+#endif
+
+#if (@GNULIB_WRITE@ || @GNULIB_READLINK@ || @GNULIB_READLINKAT@ \
+     || @GNULIB_PREAD@ || @GNULIB_PWRITE@ || defined GNULIB_POSIXCHECK)
+/* Get ssize_t.  */
+# include <sys/types.h>
+#endif
+
+/* Get getopt(), optarg, optind, opterr, optopt.
+   But avoid namespace pollution on glibc systems.  */
+#if @GNULIB_UNISTD_H_GETOPT@ && !defined __GLIBC__ && !defined _GL_SYSTEM_GETOPT
+# include <getopt.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+#if @GNULIB_GETHOSTNAME@
+/* Get all possible declarations of gethostname().  */
+# if @UNISTD_H_HAVE_WINSOCK2_H@
+#  if !defined _GL_SYS_SOCKET_H
+#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef socket
+#    define socket              socket_used_without_including_sys_socket_h
+#    undef connect
+#    define connect             connect_used_without_including_sys_socket_h
+#    undef accept
+#    define accept              accept_used_without_including_sys_socket_h
+#    undef bind
+#    define bind                bind_used_without_including_sys_socket_h
+#    undef getpeername
+#    define getpeername         getpeername_used_without_including_sys_socket_h
+#    undef getsockname
+#    define getsockname         getsockname_used_without_including_sys_socket_h
+#    undef getsockopt
+#    define getsockopt          getsockopt_used_without_including_sys_socket_h
+#    undef listen
+#    define listen              listen_used_without_including_sys_socket_h
+#    undef recv
+#    define recv                recv_used_without_including_sys_socket_h
+#    undef send
+#    define send                send_used_without_including_sys_socket_h
+#    undef recvfrom
+#    define recvfrom            recvfrom_used_without_including_sys_socket_h
+#    undef sendto
+#    define sendto              sendto_used_without_including_sys_socket_h
+#    undef setsockopt
+#    define setsockopt          setsockopt_used_without_including_sys_socket_h
+#    undef shutdown
+#    define shutdown            shutdown_used_without_including_sys_socket_h
+#   else
+     _GL_WARN_ON_USE (socket,
+                      "socket() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (connect,
+                      "connect() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (accept,
+                      "accept() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (bind,
+                      "bind() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (getpeername,
+                      "getpeername() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (getsockname,
+                      "getsockname() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (getsockopt,
+                      "getsockopt() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (listen,
+                      "listen() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (recv,
+                      "recv() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (send,
+                      "send() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (recvfrom,
+                      "recvfrom() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (sendto,
+                      "sendto() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (setsockopt,
+                      "setsockopt() used without including <sys/socket.h>");
+     _GL_WARN_ON_USE (shutdown,
+                      "shutdown() used without including <sys/socket.h>");
+#   endif
+#  endif
+#  if !defined _GL_SYS_SELECT_H
+#   if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#    undef select
+#    define select              select_used_without_including_sys_select_h
+#   else
+     _GL_WARN_ON_USE (select,
+                      "select() used without including <sys/select.h>");
+#   endif
+#  endif
+# endif
+#endif
+
+
+/* OS/2 EMX lacks these macros.  */
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+/* Ensure *_OK macros exist.  */
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+
+/* Declare overridden functions.  */
+
+
+#if defined GNULIB_POSIXCHECK
+/* The access() function is a security risk.  */
+_GL_WARN_ON_USE (access, "the access function is a security risk - "
+                 "use the gnulib module faccessat instead");
+#endif
+
+
+#if @GNULIB_CHOWN@
+/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
+   to GID (if GID is not -1).  Follow symbolic links.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/chown.html>.  */
+# if @REPLACE_CHOWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef chown
+#   define chown rpl_chown
+#  endif
+_GL_FUNCDECL_RPL (chown, int, (const char *file, uid_t uid, gid_t gid)
+                              _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (chown, int, (const char *file, uid_t uid, gid_t gid));
+# else
+#  if !@HAVE_CHOWN@
+_GL_FUNCDECL_SYS (chown, int, (const char *file, uid_t uid, gid_t gid)
+                              _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (chown, int, (const char *file, uid_t uid, gid_t gid));
+# endif
+_GL_CXXALIASWARN (chown);
+#elif defined GNULIB_POSIXCHECK
+# undef chown
+# if HAVE_RAW_DECL_CHOWN
+_GL_WARN_ON_USE (chown, "chown fails to follow symlinks on some systems and "
+                 "doesn't treat a uid or gid of -1 on some systems - "
+                 "use gnulib module chown for portability");
+# endif
+#endif
+
+
+#if @GNULIB_CLOSE@
+# if @REPLACE_CLOSE@
+/* Automatically included by modules that need a replacement for close.  */
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef close
+#   define close rpl_close
+#  endif
+_GL_FUNCDECL_RPL (close, int, (int fd));
+_GL_CXXALIAS_RPL (close, int, (int fd));
+# else
+_GL_CXXALIAS_SYS (close, int, (int fd));
+# endif
+_GL_CXXALIASWARN (close);
+#elif @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+# undef close
+# define close close_used_without_requesting_gnulib_module_close
+#elif defined GNULIB_POSIXCHECK
+# undef close
+/* Assume close is always declared.  */
+_GL_WARN_ON_USE (close, "close does not portably work on sockets - "
+                 "use gnulib module close for portability");
+#endif
+
+
+#if @REPLACE_DUP@
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#  define dup rpl_dup
+# endif
+_GL_FUNCDECL_RPL (dup, int, (int oldfd));
+_GL_CXXALIAS_RPL (dup, int, (int oldfd));
+#else
+_GL_CXXALIAS_SYS (dup, int, (int oldfd));
+#endif
+_GL_CXXALIASWARN (dup);
+
+
+#if @GNULIB_DUP2@
+/* Copy the file descriptor OLDFD into file descriptor NEWFD.  Do nothing if
+   NEWFD = OLDFD, otherwise close NEWFD first if it is open.
+   Return newfd if successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/dup2.html>.  */
+# if @REPLACE_DUP2@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define dup2 rpl_dup2
+#  endif
+_GL_FUNCDECL_RPL (dup2, int, (int oldfd, int newfd));
+_GL_CXXALIAS_RPL (dup2, int, (int oldfd, int newfd));
+# else
+#  if !@HAVE_DUP2@
+_GL_FUNCDECL_SYS (dup2, int, (int oldfd, int newfd));
+#  endif
+_GL_CXXALIAS_SYS (dup2, int, (int oldfd, int newfd));
+# endif
+_GL_CXXALIASWARN (dup2);
+#elif defined GNULIB_POSIXCHECK
+# undef dup2
+# if HAVE_RAW_DECL_DUP2
+_GL_WARN_ON_USE (dup2, "dup2 is unportable - "
+                 "use gnulib module dup2 for portability");
+# endif
+#endif
+
+
+#if @GNULIB_DUP3@
+/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the
+   specified flags.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   Close NEWFD first if it is open.
+   Return newfd if successful, otherwise -1 and errno set.
+   See the Linux man page at
+   <http://www.kernel.org/doc/man-pages/online/pages/man2/dup3.2.html>.  */
+# if @HAVE_DUP3@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define dup3 rpl_dup3
+#  endif
+_GL_FUNCDECL_RPL (dup3, int, (int oldfd, int newfd, int flags));
+_GL_CXXALIAS_RPL (dup3, int, (int oldfd, int newfd, int flags));
+# else
+_GL_FUNCDECL_SYS (dup3, int, (int oldfd, int newfd, int flags));
+_GL_CXXALIAS_SYS (dup3, int, (int oldfd, int newfd, int flags));
+# endif
+_GL_CXXALIASWARN (dup3);
+#elif defined GNULIB_POSIXCHECK
+# undef dup3
+# if HAVE_RAW_DECL_DUP3
+_GL_WARN_ON_USE (dup3, "dup3 is unportable - "
+                 "use gnulib module dup3 for portability");
+# endif
+#endif
+
+
+#if @GNULIB_ENVIRON@
+# if !@HAVE_DECL_ENVIRON@
+/* Set of environment variables and values.  An array of strings of the form
+   "VARIABLE=VALUE", terminated with a NULL.  */
+#  if defined __APPLE__ && defined __MACH__
+#   include <crt_externs.h>
+#   define environ (*_NSGetEnviron ())
+#  else
+#   ifdef __cplusplus
+extern "C" {
+#   endif
+extern char **environ;
+#   ifdef __cplusplus
+}
+#   endif
+#  endif
+# endif
+#elif defined GNULIB_POSIXCHECK
+# if HAVE_RAW_DECL_ENVIRON
+static inline char ***
+rpl_environ (void)
+{
+  return &environ;
+}
+_GL_WARN_ON_USE (rpl_environ, "environ is unportable - "
+                 "use gnulib module environ for portability");
+#  undef environ
+#  define environ (*rpl_environ ())
+# endif
+#endif
+
+
+#if @GNULIB_EUIDACCESS@
+/* Like access(), except that it uses the effective user id and group id of
+   the current process.  */
+# if !@HAVE_EUIDACCESS@
+_GL_FUNCDECL_SYS (euidaccess, int, (const char *filename, int mode)
+                                   _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (euidaccess, int, (const char *filename, int mode));
+_GL_CXXALIASWARN (euidaccess);
+# if defined GNULIB_POSIXCHECK
+/* Like access(), this function is a security risk.  */
+_GL_WARN_ON_USE (euidaccess, "the euidaccess function is a security risk - "
+                 "use the gnulib module faccessat instead");
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef euidaccess
+# if HAVE_RAW_DECL_EUIDACCESS
+_GL_WARN_ON_USE (euidaccess, "euidaccess is unportable - "
+                 "use gnulib module euidaccess for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FACCESSAT@
+# if !@HAVE_FACCESSAT@
+_GL_FUNCDECL_SYS (faccessat, int,
+                  (int fd, char const *file, int mode, int flag)
+                  _GL_ARG_NONNULL ((2)));
+# endif
+_GL_CXXALIAS_SYS (faccessat, int,
+                  (int fd, char const *file, int mode, int flag));
+_GL_CXXALIASWARN (faccessat);
+#elif defined GNULIB_POSIXCHECK
+# undef faccessat
+# if HAVE_RAW_DECL_FACCESSAT
+_GL_WARN_ON_USE (faccessat, "faccessat is not portable - "
+                 "use gnulib module faccessat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FCHDIR@
+/* Change the process' current working directory to the directory on which
+   the given file descriptor is open.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/fchdir.html>.  */
+# if ! @HAVE_FCHDIR@
+_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));
+
+/* Gnulib internal hooks needed to maintain the fchdir metadata.  */
+_GL_EXTERN_C int _gl_register_fd (int fd, const char *filename)
+     _GL_ARG_NONNULL ((2));
+_GL_EXTERN_C void _gl_unregister_fd (int fd);
+_GL_EXTERN_C int _gl_register_dup (int oldfd, int newfd);
+_GL_EXTERN_C const char *_gl_directory_name (int fd);
+
+# else
+#  if !@HAVE_DECL_FCHDIR@
+_GL_FUNCDECL_SYS (fchdir, int, (int /*fd*/));
+#  endif
+# endif
+_GL_CXXALIAS_SYS (fchdir, int, (int /*fd*/));
+_GL_CXXALIASWARN (fchdir);
+#elif defined GNULIB_POSIXCHECK
+# undef fchdir
+# if HAVE_RAW_DECL_FCHDIR
+_GL_WARN_ON_USE (fchdir, "fchdir is unportable - "
+                 "use gnulib module fchdir for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FCHOWNAT@
+# if @REPLACE_FCHOWNAT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef fchownat
+#   define fchownat rpl_fchownat
+#  endif
+_GL_FUNCDECL_RPL (fchownat, int, (int fd, char const *file,
+                                  uid_t owner, gid_t group, int flag)
+                                 _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (fchownat, int, (int fd, char const *file,
+                                  uid_t owner, gid_t group, int flag));
+# else
+#  if !@HAVE_FCHOWNAT@
+_GL_FUNCDECL_SYS (fchownat, int, (int fd, char const *file,
+                                  uid_t owner, gid_t group, int flag)
+                                 _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (fchownat, int, (int fd, char const *file,
+                                  uid_t owner, gid_t group, int flag));
+# endif
+_GL_CXXALIASWARN (fchownat);
+#elif defined GNULIB_POSIXCHECK
+# undef fchownat
+# if HAVE_RAW_DECL_FCHOWNAT
+_GL_WARN_ON_USE (fchownat, "fchownat is not portable - "
+                 "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FSYNC@
+/* Synchronize changes to a file.
+   Return 0 if successful, otherwise -1 and errno set.
+   See POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/fsync.html>.  */
+# if !@HAVE_FSYNC@
+_GL_FUNCDECL_SYS (fsync, int, (int fd));
+# endif
+_GL_CXXALIAS_SYS (fsync, int, (int fd));
+_GL_CXXALIASWARN (fsync);
+#elif defined GNULIB_POSIXCHECK
+# undef fsync
+# if HAVE_RAW_DECL_FSYNC
+_GL_WARN_ON_USE (fsync, "fsync is unportable - "
+                 "use gnulib module fsync for portability");
+# endif
+#endif
+
+
+#if @GNULIB_FTRUNCATE@
+/* Change the size of the file to which FD is opened to become equal to LENGTH.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/ftruncate.html>.  */
+# if !@HAVE_FTRUNCATE@
+_GL_FUNCDECL_SYS (ftruncate, int, (int fd, off_t length));
+# endif
+_GL_CXXALIAS_SYS (ftruncate, int, (int fd, off_t length));
+_GL_CXXALIASWARN (ftruncate);
+#elif defined GNULIB_POSIXCHECK
+# undef ftruncate
+# if HAVE_RAW_DECL_FTRUNCATE
+_GL_WARN_ON_USE (ftruncate, "ftruncate is unportable - "
+                 "use gnulib module ftruncate for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETCWD@
+/* Get the name of the current working directory, and put it in SIZE bytes
+   of BUF.
+   Return BUF if successful, or NULL if the directory couldn't be determined
+   or SIZE was too small.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/getcwd.html>.
+   Additionally, the gnulib module 'getcwd' guarantees the following GNU
+   extension: If BUF is NULL, an array is allocated with 'malloc'; the array
+   is SIZE bytes long, unless SIZE == 0, in which case it is as big as
+   necessary.  */
+# if @REPLACE_GETCWD@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define getcwd rpl_getcwd
+#  endif
+_GL_FUNCDECL_RPL (getcwd, char *, (char *buf, size_t size));
+_GL_CXXALIAS_RPL (getcwd, char *, (char *buf, size_t size));
+# else
+/* Need to cast, because on mingw, the second parameter is
+                                                   int size.  */
+_GL_CXXALIAS_SYS_CAST (getcwd, char *, (char *buf, size_t size));
+# endif
+_GL_CXXALIASWARN (getcwd);
+#elif defined GNULIB_POSIXCHECK
+# undef getcwd
+# if HAVE_RAW_DECL_GETCWD
+_GL_WARN_ON_USE (getcwd, "getcwd is unportable - "
+                 "use gnulib module getcwd for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETDOMAINNAME@
+/* Return the NIS domain name of the machine.
+   WARNING! The NIS domain name is unrelated to the fully qualified host name
+            of the machine.  It is also unrelated to email addresses.
+   WARNING! The NIS domain name is usually the empty string or "(none)" when
+            not using NIS.
+
+   Put up to LEN bytes of the NIS domain name into NAME.
+   Null terminate it if the name is shorter than LEN.
+   If the NIS domain name is longer than LEN, set errno = EINVAL and return -1.
+   Return 0 if successful, otherwise set errno and return -1.  */
+# if @REPLACE_GETDOMAINNAME@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getdomainname
+#   define getdomainname rpl_getdomainname
+#  endif
+_GL_FUNCDECL_RPL (getdomainname, int, (char *name, size_t len)
+                                      _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getdomainname, int, (char *name, size_t len));
+# else
+#  if !@HAVE_DECL_GETDOMAINNAME@
+_GL_FUNCDECL_SYS (getdomainname, int, (char *name, size_t len)
+                                      _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (getdomainname, int, (char *name, size_t len));
+# endif
+_GL_CXXALIASWARN (getdomainname);
+#elif defined GNULIB_POSIXCHECK
+# undef getdomainname
+# if HAVE_RAW_DECL_GETDOMAINNAME
+_GL_WARN_ON_USE (getdomainname, "getdomainname is unportable - "
+                 "use gnulib module getdomainname for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETDTABLESIZE@
+/* Return the maximum number of file descriptors in the current process.
+   In POSIX, this is same as sysconf (_SC_OPEN_MAX).  */
+# if !@HAVE_GETDTABLESIZE@
+_GL_FUNCDECL_SYS (getdtablesize, int, (void));
+# endif
+_GL_CXXALIAS_SYS (getdtablesize, int, (void));
+_GL_CXXALIASWARN (getdtablesize);
+#elif defined GNULIB_POSIXCHECK
+# undef getdtablesize
+# if HAVE_RAW_DECL_GETDTABLESIZE
+_GL_WARN_ON_USE (getdtablesize, "getdtablesize is unportable - "
+                 "use gnulib module getdtablesize for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETGROUPS@
+/* Return the supplemental groups that the current process belongs to.
+   It is unspecified whether the effective group id is in the list.
+   If N is 0, return the group count; otherwise, N describes how many
+   entries are available in GROUPS.  Return -1 and set errno if N is
+   not 0 and not large enough.  Fails with ENOSYS on some systems.  */
+# if @REPLACE_GETGROUPS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef getgroups
+#   define getgroups rpl_getgroups
+#  endif
+_GL_FUNCDECL_RPL (getgroups, int, (int n, gid_t *groups));
+_GL_CXXALIAS_RPL (getgroups, int, (int n, gid_t *groups));
+# else
+#  if !@HAVE_GETGROUPS@
+_GL_FUNCDECL_SYS (getgroups, int, (int n, gid_t *groups));
+#  endif
+_GL_CXXALIAS_SYS (getgroups, int, (int n, gid_t *groups));
+# endif
+_GL_CXXALIASWARN (getgroups);
+#elif defined GNULIB_POSIXCHECK
+# undef getgroups
+# if HAVE_RAW_DECL_GETGROUPS
+_GL_WARN_ON_USE (getgroups, "getgroups is unportable - "
+                 "use gnulib module getgroups for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETHOSTNAME@
+/* Return the standard host name of the machine.
+   WARNING! The host name may or may not be fully qualified.
+
+   Put up to LEN bytes of the host name into NAME.
+   Null terminate it if the name is shorter than LEN.
+   If the host name is longer than LEN, set errno = EINVAL and return -1.
+   Return 0 if successful, otherwise set errno and return -1.  */
+# if @UNISTD_H_HAVE_WINSOCK2_H@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef gethostname
+#   define gethostname rpl_gethostname
+#  endif
+_GL_FUNCDECL_RPL (gethostname, int, (char *name, size_t len)
+                                    _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (gethostname, int, (char *name, size_t len));
+# else
+#  if !@HAVE_GETHOSTNAME@
+_GL_FUNCDECL_SYS (gethostname, int, (char *name, size_t len)
+                                    _GL_ARG_NONNULL ((1)));
+#  endif
+/* Need to cast, because on Solaris 10 and OSF/1 5.1 systems, the second
+   parameter is
+                                                      int len.  */
+_GL_CXXALIAS_SYS_CAST (gethostname, int, (char *name, size_t len));
+# endif
+_GL_CXXALIASWARN (gethostname);
+#elif @UNISTD_H_HAVE_WINSOCK2_H@
+# undef gethostname
+# define gethostname gethostname_used_without_requesting_gnulib_module_gethostname
+#elif defined GNULIB_POSIXCHECK
+# undef gethostname
+# if HAVE_RAW_DECL_GETHOSTNAME
+_GL_WARN_ON_USE (gethostname, "gethostname is unportable - "
+                 "use gnulib module gethostname for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETLOGIN@
+/* Returns the user's login name, or NULL if it cannot be found.  Upon error,
+   returns NULL with errno set.
+
+   See <http://www.opengroup.org/susv3xsh/getlogin.html>.
+
+   Most programs don't need to use this function, because the information is
+   available through environment variables:
+     ${LOGNAME-$USER}        on Unix platforms,
+     $USERNAME               on native Windows platforms.
+ */
+# if !@HAVE_GETLOGIN@
+_GL_FUNCDECL_SYS (getlogin, char *, (void));
+# endif
+_GL_CXXALIAS_SYS (getlogin, char *, (void));
+_GL_CXXALIASWARN (getlogin);
+#elif defined GNULIB_POSIXCHECK
+# undef getlogin
+# if HAVE_RAW_DECL_GETLOGIN
+_GL_WARN_ON_USE (getlogin, "getlogin is unportable - "
+                 "use gnulib module getlogin for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETLOGIN_R@
+/* Copies the user's login name to NAME.
+   The array pointed to by NAME has room for SIZE bytes.
+
+   Returns 0 if successful.  Upon error, an error number is returned, or -1 in
+   the case that the login name cannot be found but no specific error is
+   provided (this case is hopefully rare but is left open by the POSIX spec).
+
+   See <http://www.opengroup.org/susv3xsh/getlogin.html>.
+
+   Most programs don't need to use this function, because the information is
+   available through environment variables:
+     ${LOGNAME-$USER}        on Unix platforms,
+     $USERNAME               on native Windows platforms.
+ */
+# if @REPLACE_GETLOGIN_R@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define getlogin_r rpl_getlogin_r
+#  endif
+_GL_FUNCDECL_RPL (getlogin_r, int, (char *name, size_t size)
+                                   _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (getlogin_r, int, (char *name, size_t size));
+# else
+#  if !@HAVE_DECL_GETLOGIN_R@
+_GL_FUNCDECL_SYS (getlogin_r, int, (char *name, size_t size)
+                                   _GL_ARG_NONNULL ((1)));
+#  endif
+/* Need to cast, because on Solaris 10 systems, the second argument is
+                                                     int size.  */
+_GL_CXXALIAS_SYS_CAST (getlogin_r, int, (char *name, size_t size));
+# endif
+_GL_CXXALIASWARN (getlogin_r);
+#elif defined GNULIB_POSIXCHECK
+# undef getlogin_r
+# if HAVE_RAW_DECL_GETLOGIN_R
+_GL_WARN_ON_USE (getlogin_r, "getlogin_r is unportable - "
+                 "use gnulib module getlogin_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETPAGESIZE@
+# if @REPLACE_GETPAGESIZE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define getpagesize rpl_getpagesize
+#  endif
+_GL_FUNCDECL_RPL (getpagesize, int, (void));
+_GL_CXXALIAS_RPL (getpagesize, int, (void));
+# else
+#  if !@HAVE_GETPAGESIZE@
+#   if !defined getpagesize
+/* This is for POSIX systems.  */
+#    if !defined _gl_getpagesize && defined _SC_PAGESIZE
+#     if ! (defined __VMS && __VMS_VER < 70000000)
+#      define _gl_getpagesize() sysconf (_SC_PAGESIZE)
+#     endif
+#    endif
+/* This is for older VMS.  */
+#    if !defined _gl_getpagesize && defined __VMS
+#     ifdef __ALPHA
+#      define _gl_getpagesize() 8192
+#     else
+#      define _gl_getpagesize() 512
+#     endif
+#    endif
+/* This is for BeOS.  */
+#    if !defined _gl_getpagesize && @HAVE_OS_H@
+#     include <OS.h>
+#     if defined B_PAGE_SIZE
+#      define _gl_getpagesize() B_PAGE_SIZE
+#     endif
+#    endif
+/* This is for AmigaOS4.0.  */
+#    if !defined _gl_getpagesize && defined __amigaos4__
+#     define _gl_getpagesize() 2048
+#    endif
+/* This is for older Unix systems.  */
+#    if !defined _gl_getpagesize && @HAVE_SYS_PARAM_H@
+#     include <sys/param.h>
+#     ifdef EXEC_PAGESIZE
+#      define _gl_getpagesize() EXEC_PAGESIZE
+#     else
+#      ifdef NBPG
+#       ifndef CLSIZE
+#        define CLSIZE 1
+#       endif
+#       define _gl_getpagesize() (NBPG * CLSIZE)
+#      else
+#       ifdef NBPC
+#        define _gl_getpagesize() NBPC
+#       endif
+#      endif
+#     endif
+#    endif
+#    if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#     define getpagesize() _gl_getpagesize ()
+#    else
+static inline int
+getpagesize ()
+{
+  return _gl_getpagesize ();
+}
+#    endif
+#   endif
+#  endif
+/* Need to cast, because on Cygwin 1.5.x systems, the return type is size_t.  */
+_GL_CXXALIAS_SYS_CAST (getpagesize, int, (void));
+# endif
+# if @HAVE_DECL_GETPAGESIZE@
+_GL_CXXALIASWARN (getpagesize);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef getpagesize
+# if HAVE_RAW_DECL_GETPAGESIZE
+_GL_WARN_ON_USE (getpagesize, "getpagesize is unportable - "
+                 "use gnulib module getpagesize for portability");
+# endif
+#endif
+
+
+#if @GNULIB_GETUSERSHELL@
+/* Return the next valid login shell on the system, or NULL when the end of
+   the list has been reached.  */
+# if !@HAVE_DECL_GETUSERSHELL@
+_GL_FUNCDECL_SYS (getusershell, char *, (void));
+# endif
+_GL_CXXALIAS_SYS (getusershell, char *, (void));
+_GL_CXXALIASWARN (getusershell);
+#elif defined GNULIB_POSIXCHECK
+# undef getusershell
+# if HAVE_RAW_DECL_GETUSERSHELL
+_GL_WARN_ON_USE (getusershell, "getusershell is unportable - "
+                 "use gnulib module getusershell for portability");
+# endif
+#endif
+
+#if @GNULIB_GETUSERSHELL@
+/* Rewind to pointer that is advanced at each getusershell() call.  */
+# if !@HAVE_DECL_GETUSERSHELL@
+_GL_FUNCDECL_SYS (setusershell, void, (void));
+# endif
+_GL_CXXALIAS_SYS (setusershell, void, (void));
+_GL_CXXALIASWARN (setusershell);
+#elif defined GNULIB_POSIXCHECK
+# undef setusershell
+# if HAVE_RAW_DECL_SETUSERSHELL
+_GL_WARN_ON_USE (setusershell, "setusershell is unportable - "
+                 "use gnulib module getusershell for portability");
+# endif
+#endif
+
+#if @GNULIB_GETUSERSHELL@
+/* Free the pointer that is advanced at each getusershell() call and
+   associated resources.  */
+# if !@HAVE_DECL_GETUSERSHELL@
+_GL_FUNCDECL_SYS (endusershell, void, (void));
+# endif
+_GL_CXXALIAS_SYS (endusershell, void, (void));
+_GL_CXXALIASWARN (endusershell);
+#elif defined GNULIB_POSIXCHECK
+# undef endusershell
+# if HAVE_RAW_DECL_ENDUSERSHELL
+_GL_WARN_ON_USE (endusershell, "endusershell is unportable - "
+                 "use gnulib module getusershell for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LCHOWN@
+/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
+   to GID (if GID is not -1).  Do not follow symbolic links.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/lchown.html>.  */
+# if @REPLACE_LCHOWN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef lchown
+#   define lchown rpl_lchown
+#  endif
+_GL_FUNCDECL_RPL (lchown, int, (char const *file, uid_t owner, gid_t group)
+                               _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (lchown, int, (char const *file, uid_t owner, gid_t group));
+# else
+#  if !@HAVE_LCHOWN@
+_GL_FUNCDECL_SYS (lchown, int, (char const *file, uid_t owner, gid_t group)
+                               _GL_ARG_NONNULL ((1)));
+#  endif
+_GL_CXXALIAS_SYS (lchown, int, (char const *file, uid_t owner, gid_t group));
+# endif
+_GL_CXXALIASWARN (lchown);
+#elif defined GNULIB_POSIXCHECK
+# undef lchown
+# if HAVE_RAW_DECL_LCHOWN
+_GL_WARN_ON_USE (lchown, "lchown is unportable to pre-POSIX.1-2001 systems - "
+                 "use gnulib module lchown for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LINK@
+/* Create a new hard link for an existing file.
+   Return 0 if successful, otherwise -1 and errno set.
+   See POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/link.html>.  */
+# if @REPLACE_LINK@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define link rpl_link
+#  endif
+_GL_FUNCDECL_RPL (link, int, (const char *path1, const char *path2)
+                             _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (link, int, (const char *path1, const char *path2));
+# else
+#  if !@HAVE_LINK@
+_GL_FUNCDECL_SYS (link, int, (const char *path1, const char *path2)
+                             _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (link, int, (const char *path1, const char *path2));
+# endif
+_GL_CXXALIASWARN (link);
+#elif defined GNULIB_POSIXCHECK
+# undef link
+# if HAVE_RAW_DECL_LINK
+_GL_WARN_ON_USE (link, "link is unportable - "
+                 "use gnulib module link for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LINKAT@
+/* Create a new hard link for an existing file, relative to two
+   directories.  FLAG controls whether symlinks are followed.
+   Return 0 if successful, otherwise -1 and errno set.  */
+# if @REPLACE_LINKAT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef linkat
+#   define linkat rpl_linkat
+#  endif
+_GL_FUNCDECL_RPL (linkat, int,
+                  (int fd1, const char *path1, int fd2, const char *path2,
+                   int flag)
+                  _GL_ARG_NONNULL ((2, 4)));
+_GL_CXXALIAS_RPL (linkat, int,
+                  (int fd1, const char *path1, int fd2, const char *path2,
+                   int flag));
+# else
+#  if !@HAVE_LINKAT@
+_GL_FUNCDECL_SYS (linkat, int,
+                  (int fd1, const char *path1, int fd2, const char *path2,
+                   int flag)
+                  _GL_ARG_NONNULL ((2, 4)));
+#  endif
+_GL_CXXALIAS_SYS (linkat, int,
+                  (int fd1, const char *path1, int fd2, const char *path2,
+                   int flag));
+# endif
+_GL_CXXALIASWARN (linkat);
+#elif defined GNULIB_POSIXCHECK
+# undef linkat
+# if HAVE_RAW_DECL_LINKAT
+_GL_WARN_ON_USE (linkat, "linkat is unportable - "
+                 "use gnulib module linkat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_LSEEK@
+/* Set the offset of FD relative to SEEK_SET, SEEK_CUR, or SEEK_END.
+   Return the new offset if successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/lseek.html>.  */
+# if @REPLACE_LSEEK@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define lseek rpl_lseek
+#  endif
+_GL_FUNCDECL_RPL (lseek, off_t, (int fd, off_t offset, int whence));
+_GL_CXXALIAS_RPL (lseek, off_t, (int fd, off_t offset, int whence));
+# else
+_GL_CXXALIAS_SYS (lseek, off_t, (int fd, off_t offset, int whence));
+# endif
+_GL_CXXALIASWARN (lseek);
+#elif defined GNULIB_POSIXCHECK
+# undef lseek
+# if HAVE_RAW_DECL_LSEEK
+_GL_WARN_ON_USE (lseek, "lseek does not fail with ESPIPE on pipes on some "
+                 "systems - use gnulib module lseek for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PIPE@
+/* Create a pipe, defaulting to O_BINARY mode.
+   Store the read-end as fd[0] and the write-end as fd[1].
+   Return 0 upon success, or -1 with errno set upon failure.  */
+# if !@HAVE_PIPE@
+_GL_FUNCDECL_SYS (pipe, int, (int fd[2]) _GL_ARG_NONNULL ((1)));
+# endif
+_GL_CXXALIAS_SYS (pipe, int, (int fd[2]));
+_GL_CXXALIASWARN (pipe);
+#elif defined GNULIB_POSIXCHECK
+# undef pipe
+# if HAVE_RAW_DECL_PIPE
+_GL_WARN_ON_USE (pipe, "pipe is unportable - "
+                 "use gnulib module pipe-posix for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PIPE2@
+/* Create a pipe, applying the given flags when opening the read-end of the
+   pipe and the write-end of the pipe.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   Store the read-end as fd[0] and the write-end as fd[1].
+   Return 0 upon success, or -1 with errno set upon failure.
+   See also the Linux man page at
+   <http://www.kernel.org/doc/man-pages/online/pages/man2/pipe2.2.html>.  */
+# if @HAVE_PIPE2@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define pipe2 rpl_pipe2
+#  endif
+_GL_FUNCDECL_RPL (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (pipe2, int, (int fd[2], int flags));
+# else
+_GL_FUNCDECL_SYS (pipe2, int, (int fd[2], int flags) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_SYS (pipe2, int, (int fd[2], int flags));
+# endif
+_GL_CXXALIASWARN (pipe2);
+#elif defined GNULIB_POSIXCHECK
+# undef pipe2
+# if HAVE_RAW_DECL_PIPE2
+_GL_WARN_ON_USE (pipe2, "pipe2 is unportable - "
+                 "use gnulib module pipe2 for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PREAD@
+/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET.
+   Return the number of bytes placed into BUF if successful, otherwise
+   set errno and return -1.  0 indicates EOF.  See the POSIX:2001
+   specification <http://www.opengroup.org/susv3xsh/pread.html>.  */
+# if @REPLACE_PREAD@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define pread rpl_pread
+#  endif
+_GL_FUNCDECL_RPL (pread, ssize_t,
+                  (int fd, void *buf, size_t bufsize, off_t offset)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (pread, ssize_t,
+                  (int fd, void *buf, size_t bufsize, off_t offset));
+# else
+#  if !@HAVE_PREAD@
+_GL_FUNCDECL_SYS (pread, ssize_t,
+                  (int fd, void *buf, size_t bufsize, off_t offset)
+                  _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (pread, ssize_t,
+                  (int fd, void *buf, size_t bufsize, off_t offset));
+# endif
+_GL_CXXALIASWARN (pread);
+#elif defined GNULIB_POSIXCHECK
+# undef pread
+# if HAVE_RAW_DECL_PREAD
+_GL_WARN_ON_USE (pread, "pread is unportable - "
+                 "use gnulib module pread for portability");
+# endif
+#endif
+
+
+#if @GNULIB_PWRITE@
+/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET.
+   Return the number of bytes written if successful, otherwise
+   set errno and return -1.  0 indicates nothing written.  See the
+   POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/pwrite.html>.  */
+# if @REPLACE_PWRITE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define pwrite rpl_pwrite
+#  endif
+_GL_FUNCDECL_RPL (pwrite, ssize_t,
+                  (int fd, const void *buf, size_t bufsize, off_t offset)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (pwrite, ssize_t,
+                  (int fd, const void *buf, size_t bufsize, off_t offset));
+# else
+#  if !@HAVE_PWRITE@
+_GL_FUNCDECL_SYS (pwrite, ssize_t,
+                  (int fd, const void *buf, size_t bufsize, off_t offset)
+                  _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (pwrite, ssize_t,
+                  (int fd, const void *buf, size_t bufsize, off_t offset));
+# endif
+_GL_CXXALIASWARN (pwrite);
+#elif defined GNULIB_POSIXCHECK
+# undef pwrite
+# if HAVE_RAW_DECL_PWRITE
+_GL_WARN_ON_USE (pwrite, "pwrite is unportable - "
+                 "use gnulib module pwrite for portability");
+# endif
+#endif
+
+
+#if @GNULIB_READLINK@
+/* Read the contents of the symbolic link FILE and place the first BUFSIZE
+   bytes of it into BUF.  Return the number of bytes placed into BUF if
+   successful, otherwise -1 and errno set.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/readlink.html>.  */
+# if @REPLACE_READLINK@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define readlink rpl_readlink
+#  endif
+_GL_FUNCDECL_RPL (readlink, ssize_t,
+                  (const char *file, char *buf, size_t bufsize)
+                  _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (readlink, ssize_t,
+                  (const char *file, char *buf, size_t bufsize));
+# else
+#  if !@HAVE_READLINK@
+_GL_FUNCDECL_SYS (readlink, ssize_t,
+                  (const char *file, char *buf, size_t bufsize)
+                  _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (readlink, ssize_t,
+                  (const char *file, char *buf, size_t bufsize));
+# endif
+_GL_CXXALIASWARN (readlink);
+#elif defined GNULIB_POSIXCHECK
+# undef readlink
+# if HAVE_RAW_DECL_READLINK
+_GL_WARN_ON_USE (readlink, "readlink is unportable - "
+                 "use gnulib module readlink for portability");
+# endif
+#endif
+
+
+#if @GNULIB_READLINKAT@
+# if !@HAVE_READLINKAT@
+_GL_FUNCDECL_SYS (readlinkat, ssize_t,
+                  (int fd, char const *file, char *buf, size_t len)
+                  _GL_ARG_NONNULL ((2, 3)));
+# endif
+_GL_CXXALIAS_SYS (readlinkat, ssize_t,
+                  (int fd, char const *file, char *buf, size_t len));
+_GL_CXXALIASWARN (readlinkat);
+#elif defined GNULIB_POSIXCHECK
+# undef readlinkat
+# if HAVE_RAW_DECL_READLINKAT
+_GL_WARN_ON_USE (readlinkat, "readlinkat is not portable - "
+                 "use gnulib module readlinkat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_RMDIR@
+/* Remove the directory DIR.  */
+# if @REPLACE_RMDIR@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define rmdir rpl_rmdir
+#  endif
+_GL_FUNCDECL_RPL (rmdir, int, (char const *name) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (rmdir, int, (char const *name));
+# else
+_GL_CXXALIAS_SYS (rmdir, int, (char const *name));
+# endif
+_GL_CXXALIASWARN (rmdir);
+#elif defined GNULIB_POSIXCHECK
+# undef rmdir
+# if HAVE_RAW_DECL_RMDIR
+_GL_WARN_ON_USE (rmdir, "rmdir is unportable - "
+                 "use gnulib module rmdir for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SLEEP@
+/* Pause the execution of the current thread for N seconds.
+   Returns the number of seconds left to sleep.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/sleep.html>.  */
+# if @REPLACE_SLEEP@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef sleep
+#   define sleep rpl_sleep
+#  endif
+_GL_FUNCDECL_RPL (sleep, unsigned int, (unsigned int n));
+_GL_CXXALIAS_RPL (sleep, unsigned int, (unsigned int n));
+# else
+#  if !@HAVE_SLEEP@
+_GL_FUNCDECL_SYS (sleep, unsigned int, (unsigned int n));
+#  endif
+_GL_CXXALIAS_SYS (sleep, unsigned int, (unsigned int n));
+# endif
+_GL_CXXALIASWARN (sleep);
+#elif defined GNULIB_POSIXCHECK
+# undef sleep
+# if HAVE_RAW_DECL_SLEEP
+_GL_WARN_ON_USE (sleep, "sleep is unportable - "
+                 "use gnulib module sleep for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SYMLINK@
+# if @REPLACE_SYMLINK@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef symlink
+#   define symlink rpl_symlink
+#  endif
+_GL_FUNCDECL_RPL (symlink, int, (char const *contents, char const *file)
+                                _GL_ARG_NONNULL ((1, 2)));
+_GL_CXXALIAS_RPL (symlink, int, (char const *contents, char const *file));
+# else
+#  if !@HAVE_SYMLINK@
+_GL_FUNCDECL_SYS (symlink, int, (char const *contents, char const *file)
+                                _GL_ARG_NONNULL ((1, 2)));
+#  endif
+_GL_CXXALIAS_SYS (symlink, int, (char const *contents, char const *file));
+# endif
+_GL_CXXALIASWARN (symlink);
+#elif defined GNULIB_POSIXCHECK
+# undef symlink
+# if HAVE_RAW_DECL_SYMLINK
+_GL_WARN_ON_USE (symlink, "symlink is not portable - "
+                 "use gnulib module symlink for portability");
+# endif
+#endif
+
+
+#if @GNULIB_SYMLINKAT@
+# if !@HAVE_SYMLINKAT@
+_GL_FUNCDECL_SYS (symlinkat, int,
+                  (char const *contents, int fd, char const *file)
+                  _GL_ARG_NONNULL ((1, 3)));
+# endif
+_GL_CXXALIAS_SYS (symlinkat, int,
+                  (char const *contents, int fd, char const *file));
+_GL_CXXALIASWARN (symlinkat);
+#elif defined GNULIB_POSIXCHECK
+# undef symlinkat
+# if HAVE_RAW_DECL_SYMLINKAT
+_GL_WARN_ON_USE (symlinkat, "symlinkat is not portable - "
+                 "use gnulib module symlinkat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_TTYNAME_R@
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
+   open on in BUF.  Return 0 on success, otherwise an error number.  */
+# if @REPLACE_TTYNAME_R@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef ttyname_r
+#   define ttyname_r rpl_ttyname_r
+#  endif
+_GL_FUNCDECL_RPL (ttyname_r, int,
+                  (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (ttyname_r, int,
+                  (int fd, char *buf, size_t buflen));
+# else
+#  if !@HAVE_DECL_TTYNAME_R@
+_GL_FUNCDECL_SYS (ttyname_r, int,
+                  (int fd, char *buf, size_t buflen) _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (ttyname_r, int,
+                  (int fd, char *buf, size_t buflen));
+# endif
+_GL_CXXALIASWARN (ttyname_r);
+#elif defined GNULIB_POSIXCHECK
+# undef ttyname_r
+# if HAVE_RAW_DECL_TTYNAME_R
+_GL_WARN_ON_USE (ttyname_r, "ttyname_r is not portable - "
+                 "use gnulib module ttyname_r for portability");
+# endif
+#endif
+
+
+#if @GNULIB_UNLINK@
+# if @REPLACE_UNLINK@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef unlink
+#   define unlink rpl_unlink
+#  endif
+_GL_FUNCDECL_RPL (unlink, int, (char const *file) _GL_ARG_NONNULL ((1)));
+_GL_CXXALIAS_RPL (unlink, int, (char const *file));
+# else
+_GL_CXXALIAS_SYS (unlink, int, (char const *file));
+# endif
+_GL_CXXALIASWARN (unlink);
+#elif defined GNULIB_POSIXCHECK
+# undef unlink
+# if HAVE_RAW_DECL_UNLINK
+_GL_WARN_ON_USE (unlink, "unlink is not portable - "
+                 "use gnulib module unlink for portability");
+# endif
+#endif
+
+
+#if @GNULIB_UNLINKAT@
+# if @REPLACE_UNLINKAT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef unlinkat
+#   define unlinkat rpl_unlinkat
+#  endif
+_GL_FUNCDECL_RPL (unlinkat, int, (int fd, char const *file, int flag)
+                                 _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (unlinkat, int, (int fd, char const *file, int flag));
+# else
+#  if !@HAVE_UNLINKAT@
+_GL_FUNCDECL_SYS (unlinkat, int, (int fd, char const *file, int flag)
+                                 _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (unlinkat, int, (int fd, char const *file, int flag));
+# endif
+_GL_CXXALIASWARN (unlinkat);
+#elif defined GNULIB_POSIXCHECK
+# undef unlinkat
+# if HAVE_RAW_DECL_UNLINKAT
+_GL_WARN_ON_USE (unlinkat, "unlinkat is not portable - "
+                 "use gnulib module openat for portability");
+# endif
+#endif
+
+
+#if @GNULIB_USLEEP@
+/* Pause the execution of the current thread for N microseconds.
+   Returns 0 on completion, or -1 on range error.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/sleep.html>.  */
+# if @REPLACE_USLEEP@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef usleep
+#   define usleep rpl_usleep
+#  endif
+_GL_FUNCDECL_RPL (usleep, int, (useconds_t n));
+_GL_CXXALIAS_RPL (usleep, int, (useconds_t n));
+# else
+#  if !@HAVE_USLEEP@
+_GL_FUNCDECL_SYS (usleep, int, (useconds_t n));
+#  endif
+_GL_CXXALIAS_SYS (usleep, int, (useconds_t n));
+# endif
+_GL_CXXALIASWARN (usleep);
+#elif defined GNULIB_POSIXCHECK
+# undef usleep
+# if HAVE_RAW_DECL_USLEEP
+_GL_WARN_ON_USE (usleep, "usleep is unportable - "
+                 "use gnulib module usleep for portability");
+# endif
+#endif
+
+
+#if @GNULIB_WRITE@
+/* Write up to COUNT bytes starting at BUF to file descriptor FD.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/write.html>.  */
+# if @REPLACE_WRITE@ && @GNULIB_UNISTD_H_SIGPIPE@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef write
+#   define write rpl_write
+#  endif
+_GL_FUNCDECL_RPL (write, ssize_t, (int fd, const void *buf, size_t count)
+                                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (write, ssize_t, (int fd, const void *buf, size_t count));
+# else
+/* Need to cast, because on mingw, the third parameter is
+                                                             unsigned int count
+   and the return type is 'int'.  */
+_GL_CXXALIAS_SYS_CAST (write, ssize_t, (int fd, const void *buf, size_t count));
+# endif
+_GL_CXXALIASWARN (write);
+#endif
+
+
+#endif /* _GL_UNISTD_H */
+#endif /* _GL_UNISTD_H */
diff --git a/gl/verify.h b/gl/verify.h
new file mode 100644
index 0000000..a40d58a
--- /dev/null
+++ b/gl/verify.h
@@ -0,0 +1,163 @@
+/* Compile-time assert-like macros.
+
+   Copyright (C) 2005-2006, 2009-2011 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert, Bruno Haible, and Jim Meyering.  */
+
+#ifndef VERIFY_H
+# define VERIFY_H 1
+
+/* Each of these macros verifies that its argument R is nonzero.  To
+   be portable, R should be an integer constant expression.  Unlike
+   assert (R), there is no run-time overhead.
+
+   There are two macros, since no single macro can be used in all
+   contexts in C.  verify_true (R) is for scalar contexts, including
+   integer constant expression contexts.  verify (R) is for declaration
+   contexts, e.g., the top level.
+
+   Symbols ending in "__" are private to this header.
+
+   The code below uses several ideas.
+
+   * The first step is ((R) ? 1 : -1).  Given an expression R, of
+     integral or boolean or floating-point type, this yields an
+     expression of integral type, whose value is later verified to be
+     constant and nonnegative.
+
+   * Next this expression W is wrapped in a type
+     struct verify_type__ { unsigned int verify_error_if_negative_size__: W; }.
+     If W is negative, this yields a compile-time error.  No compiler can
+     deal with a bit-field of negative size.
+
+     One might think that an array size check would have the same
+     effect, that is, that the type struct { unsigned int dummy[W]; }
+     would work as well.  However, inside a function, some compilers
+     (such as C++ compilers and GNU C) allow local parameters and
+     variables inside array size expressions.  With these compilers,
+     an array size check would not properly diagnose this misuse of
+     the verify macro:
+
+       void function (int n) { verify (n < 0); }
+
+   * For the verify macro, the struct verify_type__ will need to
+     somehow be embedded into a declaration.  To be portable, this
+     declaration must declare an object, a constant, a function, or a
+     typedef name.  If the declared entity uses the type directly,
+     such as in
+
+       struct dummy {...};
+       typedef struct {...} dummy;
+       extern struct {...} *dummy;
+       extern void dummy (struct {...} *);
+       extern struct {...} *dummy (void);
+
+     two uses of the verify macro would yield colliding declarations
+     if the entity names are not disambiguated.  A workaround is to
+     attach the current line number to the entity name:
+
+       #define _GL_CONCAT0(x, y) x##y
+       #define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+       extern struct {...} * _GL_CONCAT (dummy, __LINE__);
+
+     But this has the problem that two invocations of verify from
+     within the same macro would collide, since the __LINE__ value
+     would be the same for both invocations.  (The GCC __COUNTER__
+     macro solves this problem, but is not portable.)
+
+     A solution is to use the sizeof operator.  It yields a number,
+     getting rid of the identity of the type.  Declarations like
+
+       extern int dummy [sizeof (struct {...})];
+       extern void dummy (int [sizeof (struct {...})]);
+       extern int (*dummy (void)) [sizeof (struct {...})];
+
+     can be repeated.
+
+   * Should the implementation use a named struct or an unnamed struct?
+     Which of the following alternatives can be used?
+
+       extern int dummy [sizeof (struct {...})];
+       extern int dummy [sizeof (struct verify_type__ {...})];
+       extern void dummy (int [sizeof (struct {...})]);
+       extern void dummy (int [sizeof (struct verify_type__ {...})]);
+       extern int (*dummy (void)) [sizeof (struct {...})];
+       extern int (*dummy (void)) [sizeof (struct verify_type__ {...})];
+
+     In the second and sixth case, the struct type is exported to the
+     outer scope; two such declarations therefore collide.  GCC warns
+     about the first, third, and fourth cases.  So the only remaining
+     possibility is the fifth case:
+
+       extern int (*dummy (void)) [sizeof (struct {...})];
+
+   * GCC warns about duplicate declarations of the dummy function if
+     -Wredundant_decls is used.  GCC 4.3 and later have a builtin
+     __COUNTER__ macro that can let us generate unique identifiers for
+     each dummy function, to suppress this warning.
+
+   * This implementation exploits the fact that GCC does not warn about
+     the last declaration mentioned above.  If a future version of GCC
+     introduces a warning for this, the problem could be worked around
+     by using code specialized to GCC, just as __COUNTER__ is already
+     being used if available.
+
+       #if 4 <= __GNUC__
+       # define verify(R) [another version to keep GCC happy]
+       #endif
+
+   * In C++, any struct definition inside sizeof is invalid.
+     Use a template type to work around the problem.  */
+
+/* Concatenate two preprocessor tokens.  */
+# define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
+# define _GL_CONCAT0(x, y) x##y
+
+/* _GL_COUNTER is an integer, preferably one that changes each time we
+   use it.  Use __COUNTER__ if it works, falling back on __LINE__
+   otherwise.  __LINE__ isn't perfect, but it's better than a
+   constant.  */
+# if defined __COUNTER__ && __COUNTER__ != __COUNTER__
+#  define _GL_COUNTER __COUNTER__
+# else
+#  define _GL_COUNTER __LINE__
+# endif
+
+/* Generate a symbol with the given prefix, making it unique if
+   possible.  */
+# define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
+
+/* Verify requirement R at compile-time, as an integer constant expression.
+   Return 1.  */
+
+# ifdef __cplusplus
+template <int w>
+  struct verify_type__ { unsigned int verify_error_if_negative_size__: w; };
+#  define verify_true(R) \
+     (!!sizeof (verify_type__<(R) ? 1 : -1>))
+# else
+#  define verify_true(R) \
+     (!!sizeof \
+      (struct { unsigned int verify_error_if_negative_size__: (R) ? 1 : -1; }))
+# endif
+
+/* Verify requirement R at compile-time, as a declaration without a
+   trailing ';'.  */
+
+# define verify(R) \
+    extern int (* _GL_GENSYM (verify_function) (void)) [verify_true (R)]
+
+#endif
diff --git a/gl/wchar.in.h b/gl/wchar.in.h
new file mode 100644
index 0000000..3ef65aa
--- /dev/null
+++ b/gl/wchar.in.h
@@ -0,0 +1,433 @@
+/* A substitute for ISO C99 <wchar.h>, for platforms that have issues.
+
+   Copyright (C) 2007-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/* Written by Eric Blake.  */
+
+/*
+ * ISO C 99 <wchar.h> for platforms that have issues.
+ * <http://www.opengroup.org/susv3xbd/wchar.h.html>
+ *
+ * For now, this just ensures proper prerequisite inclusion order and
+ * the declaration of wcwidth().
+ */
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+#if defined __need_mbstate_t || defined __need_wint_t || (defined __hpux && ((defined _INTTYPES_INCLUDED && !defined strtoimax) || defined _GL_JUST_INCLUDE_SYSTEM_WCHAR_H)) || defined _GL_ALREADY_INCLUDING_WCHAR_H
+/* Special invocation convention:
+   - Inside glibc and uClibc header files.
+   - On HP-UX 11.00 we have a sequence of nested includes
+     <wchar.h> -> <stdlib.h> -> <stdint.h>, and the latter includes <wchar.h>,
+     once indirectly <stdint.h> -> <sys/types.h> -> <inttypes.h> -> <wchar.h>
+     and once directly.  In both situations 'wint_t' is not yet defined,
+     therefore we cannot provide the function overrides; instead include only
+     the system's <wchar.h>.
+   - On IRIX 6.5, similarly, we have an include <wchar.h> -> <wctype.h>, and
+     the latter includes <wchar.h>.  But here, we have no way to detect whether
+     <wctype.h> is completely included or is still being included.  */
+
+#@INCLUDE_NEXT@ @NEXT_WCHAR_H@
+
+#else
+/* Normal invocation convention.  */
+
+#ifndef _GL_WCHAR_H
+
+#define _GL_ALREADY_INCLUDING_WCHAR_H
+
+#if @HAVE_FEATURES_H@
+# include <features.h> /* for __GLIBC__ */
+#endif
+
+/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.
+   But avoid namespace pollution on glibc systems.  */
+#ifndef __GLIBC__
+# include <stddef.h>
+# include <stdio.h>
+# include <time.h>
+#endif
+
+/* Include the original <wchar.h> if it exists.
+   Some builds of uClibc lack it.  */
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_WCHAR_H@
+# @INCLUDE_NEXT@ @NEXT_WCHAR_H@
+#endif
+
+#undef _GL_ALREADY_INCLUDING_WCHAR_H
+
+#ifndef _GL_WCHAR_H
+#define _GL_WCHAR_H
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Define wint_t and WEOF.  (Also done in wctype.in.h.)  */
+#if !@HAVE_WINT_T@ && !defined wint_t
+# define wint_t int
+# ifndef WEOF
+#  define WEOF -1
+# endif
+#else
+# ifndef WEOF
+#  define WEOF ((wint_t) -1)
+# endif
+#endif
+
+
+/* Override mbstate_t if it is too small.
+   On IRIX 6.5, sizeof (mbstate_t) == 1, which is not sufficient for
+   implementing mbrtowc for encodings like UTF-8.  */
+#if !(@HAVE_MBSINIT@ && @HAVE_MBRTOWC@) || @REPLACE_MBSTATE_T@
+typedef int rpl_mbstate_t;
+# undef mbstate_t
+# define mbstate_t rpl_mbstate_t
+# define GNULIB_defined_mbstate_t 1
+#endif
+
+
+/* Convert a single-byte character to a wide character.  */
+#if @GNULIB_BTOWC@
+# if @REPLACE_BTOWC@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef btowc
+#   define btowc rpl_btowc
+#  endif
+_GL_FUNCDECL_RPL (btowc, wint_t, (int c));
+_GL_CXXALIAS_RPL (btowc, wint_t, (int c));
+# else
+#  if !@HAVE_BTOWC@
+_GL_FUNCDECL_SYS (btowc, wint_t, (int c));
+#  endif
+_GL_CXXALIAS_SYS (btowc, wint_t, (int c));
+# endif
+_GL_CXXALIASWARN (btowc);
+#elif defined GNULIB_POSIXCHECK
+# undef btowc
+# if HAVE_RAW_DECL_BTOWC
+_GL_WARN_ON_USE (btowc, "btowc is unportable - "
+                 "use gnulib module btowc for portability");
+# endif
+#endif
+
+
+/* Convert a wide character to a single-byte character.  */
+#if @GNULIB_WCTOB@
+# if @REPLACE_WCTOB@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wctob
+#   define wctob rpl_wctob
+#  endif
+_GL_FUNCDECL_RPL (wctob, int, (wint_t wc));
+_GL_CXXALIAS_RPL (wctob, int, (wint_t wc));
+# else
+#  if !defined wctob && !@HAVE_DECL_WCTOB@
+/* wctob is provided by gnulib, or wctob exists but is not declared.  */
+_GL_FUNCDECL_SYS (wctob, int, (wint_t wc));
+#  endif
+_GL_CXXALIAS_SYS (wctob, int, (wint_t wc));
+# endif
+_GL_CXXALIASWARN (wctob);
+#elif defined GNULIB_POSIXCHECK
+# undef wctob
+# if HAVE_RAW_DECL_WCTOB
+_GL_WARN_ON_USE (wctob, "wctob is unportable - "
+                 "use gnulib module wctob for portability");
+# endif
+#endif
+
+
+/* Test whether *PS is in the initial state.  */
+#if @GNULIB_MBSINIT@
+# if @REPLACE_MBSINIT@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef mbsinit
+#   define mbsinit rpl_mbsinit
+#  endif
+_GL_FUNCDECL_RPL (mbsinit, int, (const mbstate_t *ps));
+_GL_CXXALIAS_RPL (mbsinit, int, (const mbstate_t *ps));
+# else
+#  if !@HAVE_MBSINIT@
+_GL_FUNCDECL_SYS (mbsinit, int, (const mbstate_t *ps));
+#  endif
+_GL_CXXALIAS_SYS (mbsinit, int, (const mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (mbsinit);
+#elif defined GNULIB_POSIXCHECK
+# undef mbsinit
+# if HAVE_RAW_DECL_MBSINIT
+_GL_WARN_ON_USE (mbsinit, "mbsinit is unportable - "
+                 "use gnulib module mbsinit for portability");
+# endif
+#endif
+
+
+/* Convert a multibyte character to a wide character.  */
+#if @GNULIB_MBRTOWC@
+# if @REPLACE_MBRTOWC@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef mbrtowc
+#   define mbrtowc rpl_mbrtowc
+#  endif
+_GL_FUNCDECL_RPL (mbrtowc, size_t,
+                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+_GL_CXXALIAS_RPL (mbrtowc, size_t,
+                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+# else
+#  if !@HAVE_MBRTOWC@
+_GL_FUNCDECL_SYS (mbrtowc, size_t,
+                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+#  endif
+_GL_CXXALIAS_SYS (mbrtowc, size_t,
+                  (wchar_t *pwc, const char *s, size_t n, mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (mbrtowc);
+#elif defined GNULIB_POSIXCHECK
+# undef mbrtowc
+# if HAVE_RAW_DECL_MBRTOWC
+_GL_WARN_ON_USE (mbrtowc, "mbrtowc is unportable - "
+                 "use gnulib module mbrtowc for portability");
+# endif
+#endif
+
+
+/* Recognize a multibyte character.  */
+#if @GNULIB_MBRLEN@
+# if @REPLACE_MBRLEN@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef mbrlen
+#   define mbrlen rpl_mbrlen
+#  endif
+_GL_FUNCDECL_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+_GL_CXXALIAS_RPL (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+# else
+#  if !@HAVE_MBRLEN@
+_GL_FUNCDECL_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+#  endif
+_GL_CXXALIAS_SYS (mbrlen, size_t, (const char *s, size_t n, mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (mbrlen);
+#elif defined GNULIB_POSIXCHECK
+# undef mbrlen
+# if HAVE_RAW_DECL_MBRLEN
+_GL_WARN_ON_USE (mbrlen, "mbrlen is unportable - "
+                 "use gnulib module mbrlen for portability");
+# endif
+#endif
+
+
+/* Convert a string to a wide string.  */
+#if @GNULIB_MBSRTOWCS@
+# if @REPLACE_MBSRTOWCS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef mbsrtowcs
+#   define mbsrtowcs rpl_mbsrtowcs
+#  endif
+_GL_FUNCDECL_RPL (mbsrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (mbsrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t len,
+                   mbstate_t *ps));
+# else
+#  if !@HAVE_MBSRTOWCS@
+_GL_FUNCDECL_SYS (mbsrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t len, mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (mbsrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t len,
+                   mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (mbsrtowcs);
+#elif defined GNULIB_POSIXCHECK
+# undef mbsrtowcs
+# if HAVE_RAW_DECL_MBSRTOWCS
+_GL_WARN_ON_USE (mbsrtowcs, "mbsrtowcs is unportable - "
+                 "use gnulib module mbsrtowcs for portability");
+# endif
+#endif
+
+
+/* Convert a string to a wide string.  */
+#if @GNULIB_MBSNRTOWCS@
+# if @REPLACE_MBSNRTOWCS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef mbsnrtowcs
+#   define mbsnrtowcs rpl_mbsnrtowcs
+#  endif
+_GL_FUNCDECL_RPL (mbsnrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (mbsnrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps));
+# else
+#  if !@HAVE_MBSNRTOWCS@
+_GL_FUNCDECL_SYS (mbsnrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (mbsnrtowcs, size_t,
+                  (wchar_t *dest, const char **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (mbsnrtowcs);
+#elif defined GNULIB_POSIXCHECK
+# undef mbsnrtowcs
+# if HAVE_RAW_DECL_MBSNRTOWCS
+_GL_WARN_ON_USE (mbsnrtowcs, "mbsnrtowcs is unportable - "
+                 "use gnulib module mbsnrtowcs for portability");
+# endif
+#endif
+
+
+/* Convert a wide character to a multibyte character.  */
+#if @GNULIB_WCRTOMB@
+# if @REPLACE_WCRTOMB@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wcrtomb
+#   define wcrtomb rpl_wcrtomb
+#  endif
+_GL_FUNCDECL_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+_GL_CXXALIAS_RPL (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+# else
+#  if !@HAVE_WCRTOMB@
+_GL_FUNCDECL_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+#  endif
+_GL_CXXALIAS_SYS (wcrtomb, size_t, (char *s, wchar_t wc, mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (wcrtomb);
+#elif defined GNULIB_POSIXCHECK
+# undef wcrtomb
+# if HAVE_RAW_DECL_WCRTOMB
+_GL_WARN_ON_USE (wcrtomb, "wcrtomb is unportable - "
+                 "use gnulib module wcrtomb for portability");
+# endif
+#endif
+
+
+/* Convert a wide string to a string.  */
+#if @GNULIB_WCSRTOMBS@
+# if @REPLACE_WCSRTOMBS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wcsrtombs
+#   define wcsrtombs rpl_wcsrtombs
+#  endif
+_GL_FUNCDECL_RPL (wcsrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (wcsrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t len,
+                   mbstate_t *ps));
+# else
+#  if !@HAVE_WCSRTOMBS@
+_GL_FUNCDECL_SYS (wcsrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t len, mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (wcsrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t len,
+                   mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (wcsrtombs);
+#elif defined GNULIB_POSIXCHECK
+# undef wcsrtombs
+# if HAVE_RAW_DECL_WCSRTOMBS
+_GL_WARN_ON_USE (wcsrtombs, "wcsrtombs is unportable - "
+                 "use gnulib module wcsrtombs for portability");
+# endif
+#endif
+
+
+/* Convert a wide string to a string.  */
+#if @GNULIB_WCSNRTOMBS@
+# if @REPLACE_WCSNRTOMBS@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wcsnrtombs
+#   define wcsnrtombs rpl_wcsnrtombs
+#  endif
+_GL_FUNCDECL_RPL (wcsnrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+_GL_CXXALIAS_RPL (wcsnrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps));
+# else
+#  if !@HAVE_WCSNRTOMBS@
+_GL_FUNCDECL_SYS (wcsnrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps)
+                  _GL_ARG_NONNULL ((2)));
+#  endif
+_GL_CXXALIAS_SYS (wcsnrtombs, size_t,
+                  (char *dest, const wchar_t **srcp, size_t srclen, size_t len,
+                   mbstate_t *ps));
+# endif
+_GL_CXXALIASWARN (wcsnrtombs);
+#elif defined GNULIB_POSIXCHECK
+# undef wcsnrtombs
+# if HAVE_RAW_DECL_WCSNRTOMBS
+_GL_WARN_ON_USE (wcsnrtombs, "wcsnrtombs is unportable - "
+                 "use gnulib module wcsnrtombs for portability");
+# endif
+#endif
+
+
+/* Return the number of screen columns needed for WC.  */
+#if @GNULIB_WCWIDTH@
+# if @REPLACE_WCWIDTH@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef wcwidth
+#   define wcwidth rpl_wcwidth
+#  endif
+_GL_FUNCDECL_RPL (wcwidth, int, (wchar_t));
+_GL_CXXALIAS_RPL (wcwidth, int, (wchar_t));
+# else
+#  if !@HAVE_DECL_WCWIDTH@
+/* wcwidth exists but is not declared.  */
+_GL_FUNCDECL_SYS (wcwidth, int, (wchar_t));
+#  endif
+_GL_CXXALIAS_SYS (wcwidth, int, (wchar_t));
+# endif
+_GL_CXXALIASWARN (wcwidth);
+#elif defined GNULIB_POSIXCHECK
+# undef wcwidth
+# if HAVE_RAW_DECL_WCWIDTH
+_GL_WARN_ON_USE (wcwidth, "wcwidth is unportable - "
+                 "use gnulib module wcwidth for portability");
+# endif
+#endif
+
+
+#endif /* _GL_WCHAR_H */
+#endif /* _GL_WCHAR_H */
+#endif
diff --git a/gl/wcrtomb.c b/gl/wcrtomb.c
new file mode 100644
index 0000000..ce9184f
--- /dev/null
+++ b/gl/wcrtomb.c
@@ -0,0 +1,53 @@
+/* Convert wide character to multibyte character.
+   Copyright (C) 2008-2011 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno at clisp.org>, 2008.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3 of the License, 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <wchar.h>
+
+#include <errno.h>
+#include <stdlib.h>
+
+
+size_t
+wcrtomb (char *s, wchar_t wc, mbstate_t *ps)
+{
+  /* This implementation of wcrtomb on top of wctomb() supports only
+     stateless encodings.  ps must be in the initial state.  */
+  if (ps != NULL && !mbsinit (ps))
+    {
+      errno = EINVAL;
+      return (size_t)(-1);
+    }
+
+  if (s == NULL)
+    /* We know the NUL wide character corresponds to the NUL character.  */
+    return 1;
+  else
+    {
+      int ret = wctomb (s, wc);
+
+      if (ret >= 0)
+        return ret;
+      else
+        {
+          errno = EILSEQ;
+          return (size_t)(-1);
+        }
+    }
+}
diff --git a/gl/wctype.in.h b/gl/wctype.in.h
new file mode 100644
index 0000000..ddb6b49
--- /dev/null
+++ b/gl/wctype.in.h
@@ -0,0 +1,385 @@
+/* A substitute for ISO C99 <wctype.h>, for platforms that lack it.
+
+   Copyright (C) 2006-2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser 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.  */
+
+/* Written by Bruno Haible and Paul Eggert.  */
+
+/*
+ * ISO C 99 <wctype.h> for platforms that lack it.
+ * <http://www.opengroup.org/susv3xbd/wctype.h.html>
+ *
+ * iswctype, towctrans, towlower, towupper, wctrans, wctype,
+ * wctrans_t, and wctype_t are not yet implemented.
+ */
+
+#ifndef _GL_WCTYPE_H
+
+#if __GNUC__ >= 3
+ at PRAGMA_SYSTEM_HEADER@
+#endif
+ at PRAGMA_COLUMNS@
+
+#if @HAVE_WINT_T@
+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>.
+   Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
+   <wchar.h>.
+   BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
+   included before <wchar.h>.  */
+# include <stddef.h>
+# include <stdio.h>
+# include <time.h>
+# include <wchar.h>
+#endif
+
+/* Include the original <wctype.h> if it exists.
+   BeOS 5 has the functions but no <wctype.h>.  */
+/* The include_next requires a split double-inclusion guard.  */
+#if @HAVE_WCTYPE_H@
+# @INCLUDE_NEXT@ @NEXT_WCTYPE_H@
+#endif
+
+#ifndef _GL_WCTYPE_H
+#define _GL_WCTYPE_H
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* Define wint_t and WEOF.  (Also done in wchar.in.h.)  */
+#if !@HAVE_WINT_T@ && !defined wint_t
+# define wint_t int
+# ifndef WEOF
+#  define WEOF -1
+# endif
+#else
+# ifndef WEOF
+#  define WEOF ((wint_t) -1)
+# endif
+#endif
+
+
+/* FreeBSD 4.4 to 4.11 has <wctype.h> but lacks the functions.
+   Linux libc5 has <wctype.h> and the functions but they are broken.
+   Assume all 11 functions (all isw* except iswblank) are implemented the
+   same way, or not at all.  */
+#if ! @HAVE_ISWCNTRL@ || @REPLACE_ISWCNTRL@
+
+/* IRIX 5.3 has macros but no functions, its isw* macros refer to an
+   undefined variable _ctmp_ and to <ctype.h> macros like _P, and they
+   refer to system functions like _iswctype that are not in the
+   standard C library.  Rather than try to get ancient buggy
+   implementations like this to work, just disable them.  */
+# undef iswalnum
+# undef iswalpha
+# undef iswblank
+# undef iswcntrl
+# undef iswdigit
+# undef iswgraph
+# undef iswlower
+# undef iswprint
+# undef iswpunct
+# undef iswspace
+# undef iswupper
+# undef iswxdigit
+# undef towlower
+# undef towupper
+
+/* Linux libc5 has <wctype.h> and the functions but they are broken.  */
+# if @REPLACE_ISWCNTRL@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define iswalnum rpl_iswalnum
+#   define iswalpha rpl_iswalpha
+#   define iswblank rpl_iswblank
+#   define iswcntrl rpl_iswcntrl
+#   define iswdigit rpl_iswdigit
+#   define iswgraph rpl_iswgraph
+#   define iswlower rpl_iswlower
+#   define iswprint rpl_iswprint
+#   define iswpunct rpl_iswpunct
+#   define iswspace rpl_iswspace
+#   define iswupper rpl_iswupper
+#   define iswxdigit rpl_iswxdigit
+#   define towlower rpl_towlower
+#   define towupper rpl_towupper
+#  endif
+# endif
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswalnum
+# else
+iswalnum
+# endif
+         (wint_t wc)
+{
+  return ((wc >= '0' && wc <= '9')
+          || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z'));
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswalpha
+# else
+iswalpha
+# endif
+         (wint_t wc)
+{
+  return (wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswblank
+# else
+iswblank
+# endif
+         (wint_t wc)
+{
+  return wc == ' ' || wc == '\t';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswcntrl
+# else
+iswcntrl
+# endif
+        (wint_t wc)
+{
+  return (wc & ~0x1f) == 0 || wc == 0x7f;
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswdigit
+# else
+iswdigit
+# endif
+         (wint_t wc)
+{
+  return wc >= '0' && wc <= '9';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswgraph
+# else
+iswgraph
+# endif
+         (wint_t wc)
+{
+  return wc >= '!' && wc <= '~';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswlower
+# else
+iswlower
+# endif
+         (wint_t wc)
+{
+  return wc >= 'a' && wc <= 'z';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswprint
+# else
+iswprint
+# endif
+         (wint_t wc)
+{
+  return wc >= ' ' && wc <= '~';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswpunct
+# else
+iswpunct
+# endif
+         (wint_t wc)
+{
+  return (wc >= '!' && wc <= '~'
+          && !((wc >= '0' && wc <= '9')
+               || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'Z')));
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswspace
+# else
+iswspace
+# endif
+         (wint_t wc)
+{
+  return (wc == ' ' || wc == '\t'
+          || wc == '\n' || wc == '\v' || wc == '\f' || wc == '\r');
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswupper
+# else
+iswupper
+# endif
+         (wint_t wc)
+{
+  return wc >= 'A' && wc <= 'Z';
+}
+
+static inline int
+# if @REPLACE_ISWCNTRL@
+rpl_iswxdigit
+# else
+iswxdigit
+# endif
+          (wint_t wc)
+{
+  return ((wc >= '0' && wc <= '9')
+          || ((wc & ~0x20) >= 'A' && (wc & ~0x20) <= 'F'));
+}
+
+static inline wint_t
+# if @REPLACE_ISWCNTRL@
+rpl_towlower
+# else
+towlower
+# endif
+         (wint_t wc)
+{
+  return (wc >= 'A' && wc <= 'Z' ? wc - 'A' + 'a' : wc);
+}
+
+static inline wint_t
+# if @REPLACE_ISWCNTRL@
+rpl_towupper
+# else
+towupper
+# endif
+         (wint_t wc)
+{
+  return (wc >= 'a' && wc <= 'z' ? wc - 'a' + 'A' : wc);
+}
+
+#elif ! @HAVE_ISWBLANK@ || @REPLACE_ISWBLANK@
+/* Only the iswblank function is missing.  */
+
+# if @REPLACE_ISWBLANK@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   define iswblank rpl_iswblank
+#  endif
+_GL_FUNCDECL_RPL (iswblank, int, (wint_t wc));
+# else
+_GL_FUNCDECL_SYS (iswblank, int, (wint_t wc));
+# endif
+
+#endif
+
+#if defined __MINGW32__
+
+/* On native Windows, wchar_t is uint16_t, and wint_t is uint32_t.
+   The functions towlower and towupper are implemented in the MSVCRT library
+   to take a wchar_t argument and return a wchar_t result.  mingw declares
+   these functions to take a wint_t argument and return a wint_t result.
+   This means that:
+   1. When the user passes an argument outside the range 0x0000..0xFFFF, the
+      function will look only at the lower 16 bits.  This is allowed according
+      to POSIX.
+   2. The return value is returned in the lower 16 bits of the result register.
+      The upper 16 bits are random: whatever happened to be in that part of the
+      result register.  We need to fix this by adding a zero-extend from
+      wchar_t to wint_t after the call.  */
+
+static inline wint_t
+rpl_towlower (wint_t wc)
+{
+  return (wint_t) (wchar_t) towlower (wc);
+}
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#  define towlower rpl_towlower
+# endif
+
+static inline wint_t
+rpl_towupper (wint_t wc)
+{
+  return (wint_t) (wchar_t) towupper (wc);
+}
+# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#  define towupper rpl_towupper
+# endif
+
+#endif /* __MINGW32__ */
+
+#if @REPLACE_ISWCNTRL@
+_GL_CXXALIAS_RPL (iswalnum, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswalpha, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswcntrl, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswdigit, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswgraph, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswlower, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswprint, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswpunct, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswspace, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswupper, int, (wint_t wc));
+_GL_CXXALIAS_RPL (iswxdigit, int, (wint_t wc));
+#else
+_GL_CXXALIAS_SYS (iswalnum, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswalpha, int, (wint_t wc));
+# if @REPLACE_ISWBLANK@
+_GL_CXXALIAS_RPL (iswblank, int, (wint_t wc));
+# else
+_GL_CXXALIAS_SYS (iswblank, int, (wint_t wc));
+# endif
+_GL_CXXALIAS_SYS (iswcntrl, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswdigit, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswgraph, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswlower, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswprint, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswpunct, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswspace, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswupper, int, (wint_t wc));
+_GL_CXXALIAS_SYS (iswxdigit, int, (wint_t wc));
+#endif
+_GL_CXXALIASWARN (iswalnum);
+_GL_CXXALIASWARN (iswalpha);
+_GL_CXXALIASWARN (iswblank);
+_GL_CXXALIASWARN (iswcntrl);
+_GL_CXXALIASWARN (iswdigit);
+_GL_CXXALIASWARN (iswgraph);
+_GL_CXXALIASWARN (iswlower);
+_GL_CXXALIASWARN (iswprint);
+_GL_CXXALIASWARN (iswpunct);
+_GL_CXXALIASWARN (iswspace);
+_GL_CXXALIASWARN (iswupper);
+_GL_CXXALIASWARN (iswxdigit);
+
+#if @REPLACE_ISWCNTRL@ || defined __MINGW32__
+_GL_CXXALIAS_RPL (towlower, wint_t, (wint_t wc));
+_GL_CXXALIAS_RPL (towupper, wint_t, (wint_t wc));
+#else
+_GL_CXXALIAS_SYS (towlower, wint_t, (wint_t wc));
+_GL_CXXALIAS_SYS (towupper, wint_t, (wint_t wc));
+#endif
+_GL_CXXALIASWARN (towlower);
+_GL_CXXALIASWARN (towupper);
+
+
+#endif /* _GL_WCTYPE_H */
+#endif /* _GL_WCTYPE_H */
diff --git a/gse.lex b/gse.lex
new file mode 100644
index 0000000..f550815
--- /dev/null
+++ b/gse.lex
@@ -0,0 +1,174 @@
+
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1999
+*/ 
+
+/*
+  Scanner for grid selection sub-expressions. The scanner is not reentrant,
+  but can share a name space with other scanners.
+
+   Note:
+   1) The `defines' file gse.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `gse_lex'.
+   3) When bison builds the gse.tab.h file, it uses `gse_' instead
+   of `yy' for variable name prefixes (e.g., yylval --> gse_lval).
+
+   1/13/99 jhrg
+*/
+
+%{
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: gse.lex 18500 2008-03-19 19:39:45Z jimg $"};
+
+#include <string>
+#include <cstring>
+
+#include "Error.h"
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_DECL int gse_lex YY_PROTO(( void ))
+#define ID_MAX 256
+#define YY_NO_UNPUT 1
+#define YY_NO_INPUT 1
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning grid constraint expression text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+#include "gse.tab.hh"
+
+using namespace std;
+using namespace libdap;
+
+static void store_int32();
+static void store_float64();
+static void store_id();
+static void store_op(int op);
+
+%}
+
+%option noyywrap
+%option prefix="gse_"
+%option outfile="lex.gse_.cc"
+
+NAN     [Nn][Aa][Nn]
+INF     [Ii][Nn][Ff]
+
+SCAN_INT	[-+]?[0-9]+
+
+SCAN_MANTISA	([0-9]+\.?[0-9]*)|([0-9]*\.?[0-9]+)
+SCAN_EXPONENT	(E|e)[-+]?[0-9]+
+
+SCAN_FLOAT	([-+]?{SCAN_MANTISA}{SCAN_EXPONENT}?)|({NAN})|({INF})
+
+/* See das.lex for comments about the characters allowed in a WORD.
+   10/31/2001 jhrg */
+
+SCAN_WORD	[-+a-zA-Z0-9_/%.\\][-+a-zA-Z0-9_/%.\\#]*
+
+SCAN_EQUAL	=
+SCAN_NOT_EQUAL	!=
+SCAN_GREATER	>
+SCAN_GREATER_EQL >=
+SCAN_LESS	<
+SCAN_LESS_EQL	<=
+
+NEVER		[^a-zA-Z0-9_/%.#:+\-,]
+
+%%
+
+{SCAN_INT}	store_int32(); return SCAN_INT;
+{SCAN_FLOAT}	store_float64(); return SCAN_FLOAT;
+
+{SCAN_WORD}	store_id(); return SCAN_WORD;
+
+{SCAN_EQUAL}	store_op(SCAN_EQUAL); return SCAN_EQUAL;
+{SCAN_NOT_EQUAL} store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+{SCAN_GREATER}	store_op(SCAN_GREATER); return SCAN_GREATER;
+{SCAN_GREATER_EQL} store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+{SCAN_LESS}	store_op(SCAN_LESS); return SCAN_LESS;
+{SCAN_LESS_EQL}	store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+
+%%
+
+// Three glue routines for string scanning. These are not declared in the
+// header gse.tab.h nor is YY_BUFFER_STATE. Including these here allows them
+// to see the type definitions in lex.gse.c (where YY_BUFFER_STATE is
+// defined) and allows callers to declare them (since callers outside of this
+// file cannot declare YY_BUFFER_STATE variable).
+
+void *
+gse_string(const char *str)
+{
+    return (void *)gse__scan_string(str);
+}
+
+void
+gse_switch_to_buffer(void *buf)
+{
+    gse__switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+gse_delete_buffer(void *buf)
+{
+    gse__delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+// Note that the grid() CE function only deals with numeric maps (8/28/2001
+// jhrg) and that all comparisons are done using doubles. 
+
+static void
+store_int32()
+{
+    gse_lval.val = atof(yytext);
+}
+
+static void
+store_float64()
+{
+    gse_lval.val = atof(yytext);
+}
+
+static void
+store_id()
+{
+    strncpy(gse_lval.id, yytext, ID_MAX-1);
+    gse_lval.id[ID_MAX-1] = '\0';
+}
+
+static void
+store_op(int op)
+{
+    gse_lval.op = op;
+}
+
diff --git a/gse.tab.cc b/gse.tab.cc
new file mode 100644
index 0000000..6ffb9b5
--- /dev/null
+++ b/gse.tab.cc
@@ -0,0 +1,1716 @@
+/* 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 0
+
+/* Using locations.  */
+#define YYLSP_NEEDED 0
+
+/* Substitute the variable and function names.  */
+#define yyparse gse_parse
+#define yylex   gse_lex
+#define yyerror gse_error
+#define yylval  gse_lval
+#define yychar  gse_char
+#define yydebug gse_debug
+#define yynerrs gse_nerrs
+
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_INT = 258,
+     SCAN_FLOAT = 259,
+     SCAN_WORD = 260,
+     SCAN_FIELD = 261,
+     SCAN_EQUAL = 262,
+     SCAN_NOT_EQUAL = 263,
+     SCAN_GREATER = 264,
+     SCAN_GREATER_EQL = 265,
+     SCAN_LESS = 266,
+     SCAN_LESS_EQL = 267
+   };
+#endif
+/* Tokens.  */
+#define SCAN_INT 258
+#define SCAN_FLOAT 259
+#define SCAN_WORD 260
+#define SCAN_FIELD 261
+#define SCAN_EQUAL 262
+#define SCAN_NOT_EQUAL 263
+#define SCAN_GREATER 264
+#define SCAN_GREATER_EQL 265
+#define SCAN_LESS 266
+#define SCAN_LESS_EQL 267
+
+
+
+
+/* Copy the first part of user declarations.  */
+#line 35 "gse.y"
+
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: gse.y 17856 2008-02-02 21:25:59Z pwest $"};
+
+#include <iostream>
+
+#include "Error.h"
+#include "GSEClause.h"
+#include "gse_parser.h"
+
+using std::cerr;
+using std::endl;
+using namespace libdap;
+
+// This macro is used to access the instance of a gse_arg class which is
+// passed to the parser through a void *. See parser.h.
+
+#define gse_arg(arg) ((gse_arg *)(arg))
+
+// Assume bison 1.25
+#define YYPARSE_PARAM arg
+
+int gse_lex(void);
+void gse_error(const char *str);
+GSEClause *build_gse_clause(gse_arg *arg, char id[ID_MAX], int op, double val);
+GSEClause *build_rev_gse_clause(gse_arg *arg, char id[ID_MAX], int op,
+				double val);
+GSEClause *
+build_dual_gse_clause(gse_arg *arg, char id[ID_MAX], int op1, double val1, 
+		      int op2, double val2);
+
+
+
+/* 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
+#line 70 "gse.y"
+{
+    bool boolean;
+
+    int op;
+    char id[ID_MAX];
+    double val;
+}
+/* Line 187 of yacc.c.  */
+#line 171 "gse.tab.cc"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+
+
+/* Copy the second part of user declarations.  */
+
+
+/* Line 216 of yacc.c.  */
+#line 184 "gse.tab.cc"
+
+#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__
+# elif defined size_t
+#  define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYSIZE_T size_t
+# else
+#  define YYSIZE_T unsigned int
+# 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 YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+  };
+
+/* 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)) \
+      + 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  7
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   17
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  13
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  5
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  13
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  20
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   267
+
+#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,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     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
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     7,    11,    17,    19,    21,    23,    25,
+      27,    29,    31,    33
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      14,     0,    -1,    15,    17,    16,    -1,    16,    17,    15,
+      -1,    16,    17,    15,    17,    16,    -1,     5,    -1,     3,
+      -1,     4,    -1,     7,    -1,     8,    -1,     9,    -1,    10,
+      -1,    11,    -1,    12,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint8 yyrline[] =
+{
+       0,    98,    98,   104,   110,   119,   122,   123,   126,   127,
+     128,   129,   130,   131
+};
+#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", "SCAN_INT", "SCAN_FLOAT", "SCAN_WORD",
+  "SCAN_FIELD", "SCAN_EQUAL", "SCAN_NOT_EQUAL", "SCAN_GREATER",
+  "SCAN_GREATER_EQL", "SCAN_LESS", "SCAN_LESS_EQL", "$accept", "clause",
+  "identifier", "constant", "relop", 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
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    13,    14,    14,    14,    15,    16,    16,    17,    17,
+      17,    17,    17,    17
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     3,     3,     5,     1,     1,     1,     1,     1,
+       1,     1,     1,     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[] =
+{
+       0,     6,     7,     5,     0,     0,     0,     1,     8,     9,
+      10,    11,    12,    13,     0,     0,     2,     3,     0,     4
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     4,     5,     6,    14
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -7
+static const yytype_int8 yypact[] =
+{
+      12,    -7,    -7,    -7,     1,    -5,    -5,    -7,    -7,    -7,
+      -7,    -7,    -7,    -7,     5,     7,    -7,    -5,     5,    -7
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+      -7,    -7,    -2,    -4,    -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[] =
+{
+      15,     7,     8,     9,    10,    11,    12,    13,     1,     2,
+      16,    18,     3,    17,    19,     1,     2,     3
+};
+
+static const yytype_uint8 yycheck[] =
+{
+       6,     0,     7,     8,     9,    10,    11,    12,     3,     4,
+      14,    17,     5,    15,    18,     3,     4,     5
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,     3,     4,     5,    14,    15,    16,     0,     7,     8,
+       9,    10,    11,    12,    17,    17,    16,    15,    17,    16
+};
+
+#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 (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 (YYLEX_PARAM)
+#else
+# define YYLEX yylex ()
+#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); \
+      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)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (!yyvaluep)
+    return;
+# 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)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep);
+  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, int yyrule)
+#else
+static void
+yy_reduce_print (yyvsp, yyrule)
+    YYSTYPE *yyvsp;
+    int yyrule;
+#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)])
+		       		       );
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, Rule); \
+} 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)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+#endif
+{
+  YYUSE (yyvaluep);
+
+  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 (void);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+/* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+
+
+
+/*----------.
+| 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 (void)
+#else
+int
+yyparse ()
+
+#endif
+#endif
+{
+  
+  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;
+
+
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+
+
+  /* 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;
+
+  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;
+
+
+	/* 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),
+
+		    &yystacksize);
+
+	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);
+
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + 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;
+
+  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];
+
+
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 2:
+#line 99 "gse.y"
+    {
+		    ((gse_arg *)arg)->set_gsec(
+			build_gse_clause((gse_arg *)(arg), (yyvsp[(1) - (3)].id), (yyvsp[(2) - (3)].op), (yyvsp[(3) - (3)].val)));
+		    (yyval.boolean) = true;
+		;}
+    break;
+
+  case 3:
+#line 105 "gse.y"
+    {
+		    ((gse_arg *)arg)->set_gsec(
+		       build_rev_gse_clause((gse_arg *)(arg), (yyvsp[(3) - (3)].id), (yyvsp[(2) - (3)].op), (yyvsp[(1) - (3)].val)));
+		    (yyval.boolean) = true;
+		;}
+    break;
+
+  case 4:
+#line 111 "gse.y"
+    {
+		    ((gse_arg *)arg)->set_gsec(
+		       build_dual_gse_clause((gse_arg *)(arg), (yyvsp[(3) - (5)].id), (yyvsp[(2) - (5)].op), (yyvsp[(1) - (5)].val), (yyvsp[(4) - (5)].op),
+					     (yyvsp[(5) - (5)].val)));
+		    (yyval.boolean) = true;
+		;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+#line 1407 "gse.tab.cc"
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+
+
+  /* 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 (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 (yymsg);
+	  }
+	else
+	  {
+	    yyerror (YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+
+
+  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);
+	  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;
+
+  /* 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;
+
+
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+
+  /* 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 (YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval);
+  /* 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);
+      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);
+}
+
+
+#line 134 "gse.y"
+
+
+void
+gse_error(const char *)
+{
+    throw Error(
+"An expression passed to the grid() function could not be parsed.\n\
+Examples of expressions that will work are: \"i>=10.0\" or \"23.6<i<56.0\"\n\
+where \"i\" is the name of one of the Grid's map vectors.");
+}
+
+static relop
+decode_relop(int op)
+{
+    switch (op) {
+      case SCAN_GREATER:
+	return dods_greater_op;
+      case SCAN_GREATER_EQL:
+	return dods_greater_equal_op;
+      case SCAN_LESS:
+	return dods_less_op;
+      case SCAN_LESS_EQL:
+	return dods_less_equal_op;
+      case SCAN_EQUAL:
+	return dods_equal_op;
+      default:
+	throw Error(malformed_expr, "Unrecognized relational operator");
+    }
+}
+
+static relop
+decode_inverse_relop(int op)
+{
+    switch (op) {
+      case SCAN_GREATER:
+	return dods_less_op;
+      case SCAN_GREATER_EQL:
+	return dods_less_equal_op;
+      case SCAN_LESS:
+	return dods_greater_op;
+      case SCAN_LESS_EQL:
+	return dods_greater_equal_op;
+      case SCAN_EQUAL:
+	return dods_equal_op;
+      default:
+	throw Error(malformed_expr, "Unrecognized relational operator");
+    }
+}
+
+GSEClause *
+build_gse_clause(gse_arg *arg, char id[ID_MAX], int op, double val)
+{
+    return new GSEClause(arg->get_grid(), (string)id, val, decode_relop(op));
+}
+
+// Build a GSE Clause given that the operands are reversed.
+
+GSEClause *
+build_rev_gse_clause(gse_arg *arg, char id[ID_MAX], int op, double val)
+{
+    return new GSEClause(arg->get_grid(), (string)id, val, 
+			 decode_inverse_relop(op));
+}
+
+GSEClause *
+build_dual_gse_clause(gse_arg *arg, char id[ID_MAX], int op1, double val1, 
+		      int op2, double val2)
+{
+    // Check that the operands (op1 and op2) and the values (val1 and val2)
+    // describe a monotonic interval.
+    relop rop1 = decode_inverse_relop(op1);
+    relop rop2 = decode_relop(op2);
+
+    switch (rop1) {
+      case dods_less_op:
+      case dods_less_equal_op:
+	if (rop2 == dods_less_op || rop2 == dods_less_equal_op)
+	    throw Error(malformed_expr, 
+"GSE Clause operands must define a monotonic interval.");
+	break;
+      case dods_greater_op:
+      case dods_greater_equal_op:
+	if (rop2 == dods_greater_op || rop2 == dods_greater_equal_op)
+	    throw Error(malformed_expr, 
+"GSE Clause operands must define a monotonic interval.");
+	break;
+      case dods_equal_op:
+	break;
+      default:
+	throw Error(malformed_expr, "Unrecognized relational operator.");
+    }
+
+    return new GSEClause(arg->get_grid(), (string)id, val1, rop1, val2, rop2);
+}
+
+
diff --git a/gse.tab.hh b/gse.tab.hh
new file mode 100644
index 0000000..88ab857
--- /dev/null
+++ b/gse.tab.hh
@@ -0,0 +1,88 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton interface 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.  */
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     SCAN_INT = 258,
+     SCAN_FLOAT = 259,
+     SCAN_WORD = 260,
+     SCAN_FIELD = 261,
+     SCAN_EQUAL = 262,
+     SCAN_NOT_EQUAL = 263,
+     SCAN_GREATER = 264,
+     SCAN_GREATER_EQL = 265,
+     SCAN_LESS = 266,
+     SCAN_LESS_EQL = 267
+   };
+#endif
+/* Tokens.  */
+#define SCAN_INT 258
+#define SCAN_FLOAT 259
+#define SCAN_WORD 260
+#define SCAN_FIELD 261
+#define SCAN_EQUAL 262
+#define SCAN_NOT_EQUAL 263
+#define SCAN_GREATER 264
+#define SCAN_GREATER_EQL 265
+#define SCAN_LESS 266
+#define SCAN_LESS_EQL 267
+
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 70 "gse.y"
+{
+    bool boolean;
+
+    int op;
+    char id[ID_MAX];
+    double val;
+}
+/* Line 1489 of yacc.c.  */
+#line 81 "gse.tab.hh"
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+extern YYSTYPE gse_lval;
+
diff --git a/gse.y b/gse.y
new file mode 100644
index 0000000..9dbc926
--- /dev/null
+++ b/gse.y
@@ -0,0 +1,228 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Parse a Grid selection expression. This parser is a little different than
+// the other parsers and uses its own argument class. See parser.h.
+
+%{
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: gse.y 17856 2008-02-02 21:25:59Z pwest $"};
+
+#include <iostream>
+
+#include "Error.h"
+#include "GSEClause.h"
+#include "gse_parser.h"
+
+using std::cerr;
+using std::endl;
+using namespace libdap;
+
+// This macro is used to access the instance of a gse_arg class which is
+// passed to the parser through a void *. See parser.h.
+
+#define gse_arg(arg) ((gse_arg *)(arg))
+
+// Assume bison 1.25
+#define YYPARSE_PARAM arg
+
+int gse_lex(void);
+void gse_error(const char *str);
+GSEClause *build_gse_clause(gse_arg *arg, char id[ID_MAX], int op, double val);
+GSEClause *build_rev_gse_clause(gse_arg *arg, char id[ID_MAX], int op,
+				double val);
+GSEClause *
+build_dual_gse_clause(gse_arg *arg, char id[ID_MAX], int op1, double val1, 
+		      int op2, double val2);
+
+%}
+
+%union {
+    bool boolean;
+
+    int op;
+    char id[ID_MAX];
+    double val;
+}
+
+%token <val> SCAN_INT
+%token <val> SCAN_FLOAT
+
+%token <id> SCAN_WORD
+%token <id> SCAN_FIELD
+
+%token <op> SCAN_EQUAL
+%token <op> SCAN_NOT_EQUAL
+%token <op> SCAN_GREATER
+%token <op> SCAN_GREATER_EQL
+%token <op> SCAN_LESS
+%token <op> SCAN_LESS_EQL
+
+%type <boolean> clause
+%type <id> identifier
+%type <op> relop
+%type <val> constant
+
+%%
+
+clause:		identifier relop constant
+                {
+		    ((gse_arg *)arg)->set_gsec(
+			build_gse_clause((gse_arg *)(arg), $1, $2, $3));
+		    $$ = true;
+		}
+		| constant relop identifier
+                {
+		    ((gse_arg *)arg)->set_gsec(
+		       build_rev_gse_clause((gse_arg *)(arg), $3, $2, $1));
+		    $$ = true;
+		}
+		| constant relop identifier relop constant
+                {
+		    ((gse_arg *)arg)->set_gsec(
+		       build_dual_gse_clause((gse_arg *)(arg), $3, $2, $1, $4,
+					     $5));
+		    $$ = true;
+		}
+;
+
+identifier:	SCAN_WORD 
+;
+
+constant:       SCAN_INT
+		| SCAN_FLOAT
+;
+
+relop:		SCAN_EQUAL
+                | SCAN_NOT_EQUAL
+		| SCAN_GREATER
+		| SCAN_GREATER_EQL
+		| SCAN_LESS
+		| SCAN_LESS_EQL
+;
+
+%%
+
+void
+gse_error(const char *)
+{
+    throw Error(
+"An expression passed to the grid() function could not be parsed.\n\
+Examples of expressions that will work are: \"i>=10.0\" or \"23.6<i<56.0\"\n\
+where \"i\" is the name of one of the Grid's map vectors.");
+}
+
+static relop
+decode_relop(int op)
+{
+    switch (op) {
+      case SCAN_GREATER:
+	return dods_greater_op;
+      case SCAN_GREATER_EQL:
+	return dods_greater_equal_op;
+      case SCAN_LESS:
+	return dods_less_op;
+      case SCAN_LESS_EQL:
+	return dods_less_equal_op;
+      case SCAN_EQUAL:
+	return dods_equal_op;
+      default:
+	throw Error(malformed_expr, "Unrecognized relational operator");
+    }
+}
+
+static relop
+decode_inverse_relop(int op)
+{
+    switch (op) {
+      case SCAN_GREATER:
+	return dods_less_op;
+      case SCAN_GREATER_EQL:
+	return dods_less_equal_op;
+      case SCAN_LESS:
+	return dods_greater_op;
+      case SCAN_LESS_EQL:
+	return dods_greater_equal_op;
+      case SCAN_EQUAL:
+	return dods_equal_op;
+      default:
+	throw Error(malformed_expr, "Unrecognized relational operator");
+    }
+}
+
+GSEClause *
+build_gse_clause(gse_arg *arg, char id[ID_MAX], int op, double val)
+{
+    return new GSEClause(arg->get_grid(), (string)id, val, decode_relop(op));
+}
+
+// Build a GSE Clause given that the operands are reversed.
+
+GSEClause *
+build_rev_gse_clause(gse_arg *arg, char id[ID_MAX], int op, double val)
+{
+    return new GSEClause(arg->get_grid(), (string)id, val, 
+			 decode_inverse_relop(op));
+}
+
+GSEClause *
+build_dual_gse_clause(gse_arg *arg, char id[ID_MAX], int op1, double val1, 
+		      int op2, double val2)
+{
+    // Check that the operands (op1 and op2) and the values (val1 and val2)
+    // describe a monotonic interval.
+    relop rop1 = decode_inverse_relop(op1);
+    relop rop2 = decode_relop(op2);
+
+    switch (rop1) {
+      case dods_less_op:
+      case dods_less_equal_op:
+	if (rop2 == dods_less_op || rop2 == dods_less_equal_op)
+	    throw Error(malformed_expr, 
+"GSE Clause operands must define a monotonic interval.");
+	break;
+      case dods_greater_op:
+      case dods_greater_equal_op:
+	if (rop2 == dods_greater_op || rop2 == dods_greater_equal_op)
+	    throw Error(malformed_expr, 
+"GSE Clause operands must define a monotonic interval.");
+	break;
+      case dods_equal_op:
+	break;
+      default:
+	throw Error(malformed_expr, "Unrecognized relational operator.");
+    }
+
+    return new GSEClause(arg->get_grid(), (string)id, val1, rop1, val2, rop2);
+}
+
diff --git a/gse_parser.h b/gse_parser.h
new file mode 100644
index 0000000..8a7c2c4
--- /dev/null
+++ b/gse_parser.h
@@ -0,0 +1,84 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef _gseclause_h
+#include "GSEClause.h"
+#endif
+
+#define YYDEBUG 1
+#undef YYERROR_VERBOSE
+#define YY_NO_UNPUT 1
+
+#define ID_MAX 256
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+namespace libdap
+{
+
+/** Argument to the GSE parser. Assumes all errors will be signaled by
+    throws; Error objects are not returned. */
+struct gse_arg
+{
+    GSEClause *_gsec;           // The gse parsed.
+    Grid *_grid;                // The Grid being constrained.
+    int _status;                // The parser's status.
+
+    gse_arg(): _gsec(0), _grid(0), _status(1)
+    {}
+    gse_arg(Grid *g): _gsec(0), _grid(g), _status(1)
+    {}
+    virtual ~gse_arg()
+    {}
+
+    void set_gsec(GSEClause *gsec)
+    {
+        _gsec = gsec;
+    }
+    GSEClause *get_gsec()
+    {
+        return _gsec;
+    }
+    void set_grid(Grid *g)
+    {
+        _grid = g;
+    }
+    Grid *get_grid()
+    {
+        return _grid;
+    }
+    void set_status(int stat)
+    {
+        _status = stat;
+    }
+    int get_status()
+    {
+        return _status;
+    }
+};
+
+} // namespace libdap
diff --git a/lex.Error.cc b/lex.Error.cc
new file mode 100644
index 0000000..a853290
--- /dev/null
+++ b/lex.Error.cc
@@ -0,0 +1,1971 @@
+#line 2 "lex.Error.cc"
+
+#line 4 "lex.Error.cc"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE Errorrestart(Errorin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int Errorleng;
+
+extern FILE *Errorin, *Errorout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up Errortext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up Errortext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via Errorrestart()), so that the user can continue scanning by
+	 * just pointing Errorin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when Errortext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int Errorleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow Errorwrap()'s to do buffer switches
+ * instead of setting up a fresh Errorin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void Errorrestart (FILE *input_file  );
+void Error_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE Error_create_buffer (FILE *file,int size  );
+void Error_delete_buffer (YY_BUFFER_STATE b  );
+void Error_flush_buffer (YY_BUFFER_STATE b  );
+void Errorpush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void Errorpop_buffer_state (void );
+
+static void Errorensure_buffer_stack (void );
+static void Error_load_buffer_state (void );
+static void Error_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER Error_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE Error_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE Error_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE Error_scan_bytes (yyconst char *bytes,int len  );
+
+void *Erroralloc (yy_size_t  );
+void *Errorrealloc (void *,yy_size_t  );
+void Errorfree (void *  );
+
+#define yy_new_buffer Error_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        Errorensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            Error_create_buffer(Errorin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        Errorensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            Error_create_buffer(Errorin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define Errorwrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *Errorin = (FILE *) 0, *Errorout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int Errorlineno;
+
+int Errorlineno = 1;
+
+extern char *Errortext;
+#define yytext_ptr Errortext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up Errortext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	(yytext_ptr) -= (yy_more_len); \
+	Errorleng = (size_t) (yy_cp - (yytext_ptr)); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 20
+#define YY_END_OF_BUFFER 21
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[71] =
+    {   0,
+        0,    0,   15,   15,   12,   12,   21,   19,    9,   10,
+       14,   11,   20,    4,    7,    8,   20,   20,   20,   20,
+       20,   20,    5,    6,   15,   16,   18,   20,   12,   13,
+        9,    4,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,   15,   16,   17,   12,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    2,    0,    0,    0,    0,    0,
+        0,    1,    0,    0,    0,    0,    0,    0,    3,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    4,    5,    1,    1,    1,    1,    1,
+        1,    1,    6,    6,    6,    6,    6,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    6,    8,    1,
+        9,    1,    1,    1,   10,    6,   11,   12,   13,    6,
+       14,    6,    6,    6,    6,    6,   15,    6,   16,    6,
+        6,   17,   18,    6,    6,    6,    6,    6,    6,    6,
+        1,   19,    1,    1,    6,    1,   20,    6,   21,   22,
+
+       23,    6,   24,    6,    6,    6,    6,    6,   25,    6,
+       26,    6,    6,   27,   28,    6,    6,    6,    6,    6,
+        6,    6,   29,    1,   30,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[31] =
+    {   0,
+        1,    1,    2,    3,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    3,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[76] =
+    {   0,
+        0,    0,   28,   30,   93,   92,   94,   97,   91,   97,
+       97,   97,   97,   85,   97,   97,   19,   19,   25,   65,
+       63,   66,   97,   97,   85,   97,   97,    0,    0,   97,
+       85,   79,   73,   62,   66,   55,   63,   52,   57,   51,
+       49,   73,   97,   97,    0,   62,   51,   57,   46,   53,
+       42,   46,   42,   39,   97,   49,   38,   54,   42,   32,
+       24,   97,   29,   18,   17,   27,   16,   14,   97,   97,
+       49,   52,   55,   57,   60
+    } ;
+
+static yyconst flex_int16_t yy_def[76] =
+    {   0,
+       70,    1,   71,   71,   72,   72,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   73,   70,   70,   74,   75,   70,
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   73,   70,   70,   75,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70,   70,   70,    0,
+       70,   70,   70,   70,   70
+    } ;
+
+static yyconst flex_int16_t yy_nxt[128] =
+    {   0,
+        8,    9,   10,   11,   12,   13,   14,   15,   16,   13,
+       17,   13,   18,   13,   19,   13,   13,   13,    8,   13,
+       20,   13,   21,   13,   22,   13,   13,   13,   23,   24,
+       26,   27,   26,   27,   33,   35,   69,   37,   69,   69,
+       68,   67,   66,   65,   34,   36,   28,   38,   28,   25,
+       25,   25,   29,   29,   29,   42,   42,   44,   62,   44,
+       45,   64,   45,   63,   62,   62,   61,   60,   55,   59,
+       58,   57,   56,   55,   55,   43,   54,   53,   52,   51,
+       50,   49,   48,   47,   46,   32,   31,   43,   41,   40,
+       39,   32,   31,   70,   30,   30,    7,   70,   70,   70,
+
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70
+    } ;
+
+static yyconst flex_int16_t yy_chk[128] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        3,    3,    4,    4,   17,   18,   68,   19,   67,   66,
+       65,   64,   63,   61,   17,   18,    3,   19,    4,   71,
+       71,   71,   72,   72,   72,   73,   73,   74,   60,   74,
+       75,   59,   75,   58,   57,   56,   54,   53,   52,   51,
+       50,   49,   48,   47,   46,   42,   41,   40,   39,   38,
+       37,   36,   35,   34,   33,   32,   31,   25,   22,   21,
+       20,   14,    9,    7,    6,    5,   70,   70,   70,   70,
+
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70,   70,   70,   70,
+       70,   70,   70,   70,   70,   70,   70
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int Error_flex_debug;
+int Error_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() ((yy_more_flag) = 1)
+#define YY_MORE_ADJ (yy_more_len)
+#define YY_RESTORE_YY_MORE_OFFSET
+char *Errortext;
+#line 1 "Error.lex"
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-1996,1998,1999
+*/ 
+/*
+  Scanner for the Error object. It recognizes the five keywords in the
+  persistent representation of the Error object plus some syntactic sugar
+  (`=', `{', ...). The object's persistent representation uses a keyword =
+  value notation, where the values are quoted strings or integers.
+
+  The scanner is not reentrant, but can share name spaces with other
+  scanners. It must be processed by GNU's flex scanner generator.
+*/
+#line 41 "Error.lex"
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: Error.lex 18315 2008-03-03 20:14:44Z jimg $"};
+
+#include <cstdlib>
+#include <cassert>
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_NO_UNPUT
+#define YY_DECL int Errorlex YY_PROTO(( void ))
+
+#include "Error.tab.hh"
+
+int error_line_num = 1;
+static int start_line;		/* used in quote and comment error handlers */
+
+void store_integer();
+void store_string();
+
+
+
+#line 570 "lex.Error.cc"
+
+#define INITIAL 0
+#define quote 1
+#define comment 2
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int Errorwrap (void );
+#else
+extern int Errorwrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( Errortext, Errorleng, 1, Errorout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( Errorin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( Errorin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, Errorin))==0 && ferror(Errorin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(Errorin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int Errorlex (void);
+
+#define YY_DECL int Errorlex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after Errortext and Errorleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 82 "Error.lex"
+
+
+
+#line 729 "lex.Error.cc"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! Errorin )
+			Errorin = stdin;
+
+		if ( ! Errorout )
+			Errorout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			Errorensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				Error_create_buffer(Errorin,YY_BUF_SIZE );
+		}
+
+		Error_load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		(yy_more_len) = 0;
+		if ( (yy_more_flag) )
+			{
+			(yy_more_len) = (yy_c_buf_p) - (yytext_ptr);
+			(yy_more_flag) = 0;
+			}
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of Errortext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 71 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 97 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 85 "Error.lex"
+store_string(); return SCAN_ERROR;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 87 "Error.lex"
+store_string(); return SCAN_CODE;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 88 "Error.lex"
+store_string(); return SCAN_MSG;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 90 "Error.lex"
+store_integer(); return SCAN_INT;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 92 "Error.lex"
+return (int)*Errortext;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 93 "Error.lex"
+return (int)*Errortext;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 94 "Error.lex"
+return (int)*Errortext;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 95 "Error.lex"
+return (int)*Errortext;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 97 "Error.lex"
+
+	YY_BREAK
+case 10:
+/* rule 10 can match eol */
+YY_RULE_SETUP
+#line 98 "Error.lex"
+++error_line_num;
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 99 "Error.lex"
+yy_init = 1; error_line_num = 1; yyterminate();
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 101 "Error.lex"
+BEGIN(comment);
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 102 "Error.lex"
+
+	YY_BREAK
+case 13:
+/* rule 13 can match eol */
+YY_RULE_SETUP
+#line 103 "Error.lex"
+++error_line_num; BEGIN(INITIAL);
+	YY_BREAK
+case YY_STATE_EOF(comment):
+#line 104 "Error.lex"
+yy_init = 1; error_line_num = 1; yyterminate();
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 106 "Error.lex"
+BEGIN(quote); start_line = error_line_num; yymore();
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 107 "Error.lex"
+yymore();
+	YY_BREAK
+case 16:
+/* rule 16 can match eol */
+YY_RULE_SETUP
+#line 108 "Error.lex"
+yymore(); ++error_line_num;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 109 "Error.lex"
+yymore();
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 110 "Error.lex"
+{ 
+    			  BEGIN(INITIAL); 
+			  store_string();
+			  return SCAN_STR;
+                        }
+	YY_BREAK
+case YY_STATE_EOF(quote):
+#line 115 "Error.lex"
+{
+                          char msg[256];
+			  sprintf(msg,
+				  "Unterminated quote (starts on line %d)\n",
+				  start_line);
+			  YY_FATAL_ERROR(msg);
+                        }
+	YY_BREAK
+case 19:
+/* rule 19 can match eol */
+YY_RULE_SETUP
+#line 123 "Error.lex"
+{
+                          if (Errortext) {	/* suppress msgs about `' chars */
+                            fprintf(stderr, "Character `%c' is not", *Errortext);
+                            fprintf(stderr, " allowed (except within");
+			    fprintf(stderr, " quotes) and has been ignored\n");
+			  }
+			}
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 130 "Error.lex"
+ECHO;
+	YY_BREAK
+#line 950 "lex.Error.cc"
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed Errorin at a new source and called
+			 * Errorlex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = Errorin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( Errorwrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * Errortext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of Errorlex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					Errorrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			Errorrestart(Errorin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 71 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 71 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 70);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up Errortext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					Errorrestart(Errorin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( Errorwrap( ) )
+						return 0;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve Errortext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void Errorrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        Errorensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            Error_create_buffer(Errorin,YY_BUF_SIZE );
+	}
+
+	Error_init_buffer(YY_CURRENT_BUFFER,input_file );
+	Error_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void Error_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		Errorpop_buffer_state();
+	 *		Errorpush_buffer_state(new_buffer);
+     */
+	Errorensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	Error_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (Errorwrap()) processing, but the only time this flag
+	 * is looked at is after Errorwrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void Error_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	Errorin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE Error_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) Erroralloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in Error_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) Erroralloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in Error_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	Error_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with Error_create_buffer()
+ * 
+ */
+    void Error_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		Errorfree((void *) b->yy_ch_buf  );
+
+	Errorfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a Errorrestart() or at EOF.
+ */
+    static void Error_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	Error_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then Error_init_buffer was _probably_
+     * called from Errorrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void Error_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		Error_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void Errorpush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	Errorensure_buffer_stack();
+
+	/* This block is copied from Error_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from Error_switch_to_buffer. */
+	Error_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void Errorpop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	Error_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		Error_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void Errorensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)Erroralloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)Errorrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE Error_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) Erroralloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in Error_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	Error_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to Errorlex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       Error_scan_bytes() instead.
+ */
+YY_BUFFER_STATE Error_scan_string (yyconst char * yystr )
+{
+    
+	return Error_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to Errorlex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE Error_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) Erroralloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in Error_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = Error_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in Error_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up Errortext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		Errortext[Errorleng] = (yy_hold_char); \
+		(yy_c_buf_p) = Errortext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		Errorleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int Errorget_lineno  (void)
+{
+        
+    return Errorlineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *Errorget_in  (void)
+{
+        return Errorin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *Errorget_out  (void)
+{
+        return Errorout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int Errorget_leng  (void)
+{
+        return Errorleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *Errorget_text  (void)
+{
+        return Errortext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void Errorset_lineno (int  line_number )
+{
+    
+    Errorlineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see Error_switch_to_buffer
+ */
+void Errorset_in (FILE *  in_str )
+{
+        Errorin = in_str ;
+}
+
+void Errorset_out (FILE *  out_str )
+{
+        Errorout = out_str ;
+}
+
+int Errorget_debug  (void)
+{
+        return Error_flex_debug;
+}
+
+void Errorset_debug (int  bdebug )
+{
+        Error_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from Errorlex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    Errorin = stdin;
+    Errorout = stdout;
+#else
+    Errorin = (FILE *) 0;
+    Errorout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * Errorlex_init()
+     */
+    return 0;
+}
+
+/* Errorlex_destroy is for both reentrant and non-reentrant scanners. */
+int Errorlex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		Error_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		Errorpop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	Errorfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * Errorlex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *Erroralloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *Errorrealloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void Errorfree (void * ptr )
+{
+	free( (char *) ptr );	/* see Errorrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 130 "Error.lex"
+
+
+
+// These three glue routines enable DDS to reclaim the memory used to parse a
+// DDS off the wire. They are here because this file can see the YY_*
+// symbols; the file DDS.cc cannot.
+
+void *
+Error_buffer(FILE *fp)
+{
+    return (void *)Error_create_buffer(fp, YY_BUF_SIZE);
+}
+
+void
+Error_switch_to_buffer(void *buf)
+{
+    Error_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+Error_delete_buffer(void *buf)
+{
+    Error_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+store_integer()
+{
+    Errorlval.integer = atoi(Errortext);
+}
+
+void
+store_string()
+{
+    Errorlval.string = Errortext;
+}
+
+
diff --git a/lex.ce_expr.cc b/lex.ce_expr.cc
new file mode 100644
index 0000000..6e93b0f
--- /dev/null
+++ b/lex.ce_expr.cc
@@ -0,0 +1,2008 @@
+#line 2 "lex.ce_expr.cc"
+
+#line 4 "lex.ce_expr.cc"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE ce_exprrestart(ce_exprin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int ce_exprleng;
+
+extern FILE *ce_exprin, *ce_exprout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up ce_exprtext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up ce_exprtext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via ce_exprrestart()), so that the user can continue scanning by
+	 * just pointing ce_exprin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when ce_exprtext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int ce_exprleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow ce_exprwrap()'s to do buffer switches
+ * instead of setting up a fresh ce_exprin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void ce_exprrestart (FILE *input_file  );
+void ce_expr_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE ce_expr_create_buffer (FILE *file,int size  );
+void ce_expr_delete_buffer (YY_BUFFER_STATE b  );
+void ce_expr_flush_buffer (YY_BUFFER_STATE b  );
+void ce_exprpush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void ce_exprpop_buffer_state (void );
+
+static void ce_exprensure_buffer_stack (void );
+static void ce_expr_load_buffer_state (void );
+static void ce_expr_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER ce_expr_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE ce_expr_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE ce_expr_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE ce_expr_scan_bytes (yyconst char *bytes,int len  );
+
+void *ce_expralloc (yy_size_t  );
+void *ce_exprrealloc (void *,yy_size_t  );
+void ce_exprfree (void *  );
+
+#define yy_new_buffer ce_expr_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        ce_exprensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        ce_exprensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define ce_exprwrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *ce_exprin = (FILE *) 0, *ce_exprout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int ce_exprlineno;
+
+int ce_exprlineno = 1;
+
+extern char *ce_exprtext;
+#define yytext_ptr ce_exprtext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up ce_exprtext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	(yytext_ptr) -= (yy_more_len); \
+	ce_exprleng = (size_t) (yy_cp - (yytext_ptr)); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 24
+#define YY_END_OF_BUFFER 25
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[36] =
+    {   0,
+        0,    0,   20,   20,   25,   23,   18,   23,   19,   24,
+       10,    5,    6,    7,    4,    3,   15,   11,   13,    1,
+        2,    8,    9,   20,   22,   24,   18,   12,   10,   16,
+       17,   14,   20,   21,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    4,    5,    6,    1,    7,    8,    1,    9,
+       10,    1,    7,   11,    7,    7,    7,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,   12,    1,   13,
+       14,   15,    1,    1,    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,
+       16,   17,   18,    1,    7,    1,    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,   19,    1,   20,   21,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[22] =
+    {   0,
+        1,    1,    2,    1,    3,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    3,    1,    1,    1,
+        1
+    } ;
+
+static yyconst flex_int16_t yy_base[39] =
+    {   0,
+        0,    0,   17,   18,   39,   50,   22,   24,   50,   50,
+       20,   50,   50,   50,   50,   50,   22,   12,   18,   50,
+       50,   50,   50,    0,   50,    0,   26,   50,   24,   50,
+       50,   50,    0,   50,   50,   41,   44,   46
+    } ;
+
+static yyconst flex_int16_t yy_def[39] =
+    {   0,
+       35,    1,   36,   36,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   37,   35,   38,   35,   35,   35,   35,
+       35,   35,   37,   35,    0,   35,   35,   35
+    } ;
+
+static yyconst flex_int16_t yy_nxt[72] =
+    {   0,
+        6,    7,    7,    8,    9,   10,   11,   12,   13,   14,
+       15,   16,   17,   18,   19,   20,   11,   21,   22,   23,
+       10,   25,   25,   27,   27,   29,   29,   27,   27,   29,
+       29,   32,   31,   26,   26,   30,   29,   28,   35,   35,
+       29,   24,   24,   24,   33,   33,   34,   35,   34,    5,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35
+    } ;
+
+static yyconst flex_int16_t yy_chk[72] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    3,    4,    7,    7,   11,   11,   27,   27,   29,
+       29,   19,   18,    3,    4,   17,   11,    8,    5,    0,
+       29,   36,   36,   36,   37,   37,   38,    0,   38,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35,   35,   35,   35,   35,   35,   35,   35,   35,   35,
+       35
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int ce_expr_flex_debug;
+int ce_expr_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() ((yy_more_flag) = 1)
+#define YY_MORE_ADJ (yy_more_len)
+#define YY_RESTORE_YY_MORE_OFFSET
+char *ce_exprtext;
+#line 1 "ce_expr.lex"
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-1999
+*/ 
+/*
+  Scanner for constraint expressions. The scanner returns tokens for each of
+  the relational and selection operators. It requires GNU flex version 2.5.2
+  or newer.
+
+  The scanner is not reentrant, but can share a name space with other
+  scanners. 
+
+   Note:
+   1) The `defines' file expr.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `exprlex'.
+   3) When bison builds the expr.tab.h file, it uses `expr' instead of `yy'
+   for variable name prefixes (e.g., yylval --> exprlval).
+
+  jhrg 9/5/95
+*/
+#line 48 "ce_expr.lex"
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: ce_expr.lex 20716 2009-04-08 19:50:54Z jimg $"};
+
+#include <cstdio>
+#include <string>
+#include <cstring>
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_DECL int ce_exprlex YY_PROTO(( void ))
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning constraint expression text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+#include "Error.h"
+#include "parser.h"
+#include "expr.h"
+#include "RValue.h"
+#include "ce_expr.tab.hh"
+#include "escaping.h"
+
+using namespace libdap ;
+
+static void store_id();
+static void store_str();
+static void store_op(int op);
+
+
+/* In the DAS and DDS parsers I removed the INT and FLOAT lexemes. However,
+   not having them here complicates parsing since you must check to see if a
+   word is a number (like 2.3) or a variable called `2.3.' I'm assuming that
+   people will always put some characters in variable names (e.g., they'll
+   use `2300.7%20MHz' and not just `2300.7'). If that turns out to be a bad
+   assumption, the we'll have to put more code in the parser to figure out
+   what exactly each word is; is it a constant or a variable name. Time will
+   tell. 10/31/2001 jhrg */
+/* See das.lex for comments about the characters allowed in a WORD.
+   10/31/2001 jhrg 
+
+   I've added '*' to the set of characters in a WORD for both the DDS and DAS
+   scanners, but not here because it'll conflict with the url dereference
+   operator. 6/10/2002 jhrg
+*/
+#line 577 "lex.ce_expr.cc"
+
+#define INITIAL 0
+#define quote 1
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int ce_exprwrap (void );
+#else
+extern int ce_exprwrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( ce_exprtext, ce_exprleng, 1, ce_exprout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( ce_exprin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( ce_exprin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, ce_exprin))==0 && ferror(ce_exprin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(ce_exprin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int ce_exprlex (void);
+
+#define YY_DECL int ce_exprlex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after ce_exprtext and ce_exprleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 119 "ce_expr.lex"
+
+
+#line 734 "lex.ce_expr.cc"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! ce_exprin )
+			ce_exprin = stdin;
+
+		if ( ! ce_exprout )
+			ce_exprout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			ce_exprensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+		}
+
+		ce_expr_load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		(yy_more_len) = 0;
+		if ( (yy_more_flag) )
+			{
+			(yy_more_len) = (yy_c_buf_p) - (yytext_ptr);
+			(yy_more_flag) = 0;
+			}
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of ce_exprtext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 36 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 50 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 121 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 122 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 123 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 124 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 125 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 126 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 127 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 128 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 129 "ce_expr.lex"
+return (int)*ce_exprtext;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 131 "ce_expr.lex"
+store_id(); return SCAN_WORD;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 133 "ce_expr.lex"
+store_op(SCAN_EQUAL); return SCAN_EQUAL;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 134 "ce_expr.lex"
+store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 135 "ce_expr.lex"
+store_op(SCAN_GREATER); return SCAN_GREATER;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 136 "ce_expr.lex"
+store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 137 "ce_expr.lex"
+store_op(SCAN_LESS); return SCAN_LESS;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 138 "ce_expr.lex"
+store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 139 "ce_expr.lex"
+store_op(SCAN_REGEXP); return SCAN_REGEXP;
+	YY_BREAK
+case 18:
+/* rule 18 can match eol */
+YY_RULE_SETUP
+#line 141 "ce_expr.lex"
+
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 142 "ce_expr.lex"
+yy_init = 1; yyterminate();
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 144 "ce_expr.lex"
+BEGIN(quote); yymore();
+	YY_BREAK
+case 20:
+/* rule 20 can match eol */
+YY_RULE_SETUP
+#line 145 "ce_expr.lex"
+yymore(); /*"*/
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 146 "ce_expr.lex"
+yymore();
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 147 "ce_expr.lex"
+{ 
+    		  BEGIN(INITIAL); 
+                  store_str();
+		  return SCAN_STR;
+                }
+	YY_BREAK
+case YY_STATE_EOF(quote):
+#line 152 "ce_expr.lex"
+{
+                  char msg[256];
+		  sprintf(msg, "Unterminated quote\n");
+		  YY_FATAL_ERROR(msg);
+                }
+	YY_BREAK
+case 23:
+/* rule 23 can match eol */
+YY_RULE_SETUP
+#line 158 "ce_expr.lex"
+{
+                  if (ce_exprtext) {	/* suppress msgs about `' chars */
+                    fprintf(stderr, "Character `%c' is not", *ce_exprtext);
+                    fprintf(stderr, " allowed and has been ignored\n");
+		  }
+		}
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 164 "ce_expr.lex"
+ECHO;
+	YY_BREAK
+#line 967 "lex.ce_expr.cc"
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed ce_exprin at a new source and called
+			 * ce_exprlex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = ce_exprin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( ce_exprwrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * ce_exprtext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of ce_exprlex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					ce_exprrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			ce_exprrestart(ce_exprin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 36 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 36 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 35);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up ce_exprtext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					ce_exprrestart(ce_exprin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( ce_exprwrap( ) )
+						return 0;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve ce_exprtext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void ce_exprrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        ce_exprensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            ce_expr_create_buffer(ce_exprin,YY_BUF_SIZE );
+	}
+
+	ce_expr_init_buffer(YY_CURRENT_BUFFER,input_file );
+	ce_expr_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void ce_expr_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		ce_exprpop_buffer_state();
+	 *		ce_exprpush_buffer_state(new_buffer);
+     */
+	ce_exprensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	ce_expr_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (ce_exprwrap()) processing, but the only time this flag
+	 * is looked at is after ce_exprwrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void ce_expr_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	ce_exprin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE ce_expr_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) ce_expralloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) ce_expralloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	ce_expr_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with ce_expr_create_buffer()
+ * 
+ */
+    void ce_expr_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		ce_exprfree((void *) b->yy_ch_buf  );
+
+	ce_exprfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a ce_exprrestart() or at EOF.
+ */
+    static void ce_expr_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	ce_expr_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then ce_expr_init_buffer was _probably_
+     * called from ce_exprrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void ce_expr_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		ce_expr_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void ce_exprpush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	ce_exprensure_buffer_stack();
+
+	/* This block is copied from ce_expr_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from ce_expr_switch_to_buffer. */
+	ce_expr_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void ce_exprpop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	ce_expr_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		ce_expr_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void ce_exprensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)ce_expralloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)ce_exprrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE ce_expr_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) ce_expralloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	ce_expr_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to ce_exprlex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       ce_expr_scan_bytes() instead.
+ */
+YY_BUFFER_STATE ce_expr_scan_string (yyconst char * yystr )
+{
+    
+	return ce_expr_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to ce_exprlex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE ce_expr_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) ce_expralloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in ce_expr_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = ce_expr_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in ce_expr_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up ce_exprtext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		ce_exprtext[ce_exprleng] = (yy_hold_char); \
+		(yy_c_buf_p) = ce_exprtext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		ce_exprleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int ce_exprget_lineno  (void)
+{
+        
+    return ce_exprlineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *ce_exprget_in  (void)
+{
+        return ce_exprin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *ce_exprget_out  (void)
+{
+        return ce_exprout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int ce_exprget_leng  (void)
+{
+        return ce_exprleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *ce_exprget_text  (void)
+{
+        return ce_exprtext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void ce_exprset_lineno (int  line_number )
+{
+    
+    ce_exprlineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see ce_expr_switch_to_buffer
+ */
+void ce_exprset_in (FILE *  in_str )
+{
+        ce_exprin = in_str ;
+}
+
+void ce_exprset_out (FILE *  out_str )
+{
+        ce_exprout = out_str ;
+}
+
+int ce_exprget_debug  (void)
+{
+        return ce_expr_flex_debug;
+}
+
+void ce_exprset_debug (int  bdebug )
+{
+        ce_expr_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from ce_exprlex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    ce_exprin = stdin;
+    ce_exprout = stdout;
+#else
+    ce_exprin = (FILE *) 0;
+    ce_exprout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * ce_exprlex_init()
+     */
+    return 0;
+}
+
+/* ce_exprlex_destroy is for both reentrant and non-reentrant scanners. */
+int ce_exprlex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		ce_expr_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		ce_exprpop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	ce_exprfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * ce_exprlex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *ce_expralloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *ce_exprrealloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void ce_exprfree (void * ptr )
+{
+	free( (char *) ptr );	/* see ce_exprrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 164 "ce_expr.lex"
+
+
+
+// Three glue routines for string scanning. These are not declared in the
+// header expr.tab.h nor is YY_BUFFER_STATE. Including these here allows them
+// to see the type definitions in lex.expr.c (where YY_BUFFER_STATE is
+// defined) and allows callers to declare them (since callers outside of this
+// file cannot declare the YY_BUFFER_STATE variable). Note that I changed the
+// name of the expr_scan_string function to expr_string because C++ cannot
+// distinguish by return type. 1/12/99 jhrg
+
+void *
+ce_expr_string(const char *str)
+{
+    return (void *)ce_expr_scan_string(str);
+}
+
+void
+ce_expr_switch_to_buffer(void *buf)
+{
+    ce_expr_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+ce_expr_delete_buffer(void *buf)
+{
+    ce_expr_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+static void
+store_id()
+{
+    strncpy(ce_exprlval.id, www2id(string(ce_exprtext)).c_str(), ID_MAX-1);
+    ce_exprlval.id[ID_MAX-1] = '\0';
+}
+
+static void
+store_str()
+{
+    // transform %20 to a space. 7/11/2001 jhrg
+    string *s = new string(www2id(string(ce_exprtext)));  // XXX memory leak?
+
+    if (*s->begin() == '\"' && *(s->end()-1) == '\"') {
+	s->erase(s->begin());
+	s->erase(s->end()-1);
+    }
+
+    ce_exprlval.val.type = dods_str_c;
+    ce_exprlval.val.v.s = s;
+}
+
+static void
+store_op(int op)
+{
+    ce_exprlval.op = op;
+}
+
+
diff --git a/lex.das.cc b/lex.das.cc
new file mode 100644
index 0000000..bd828fa
--- /dev/null
+++ b/lex.das.cc
@@ -0,0 +1,2153 @@
+#line 2 "lex.das.cc"
+
+#line 4 "lex.das.cc"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE dasrestart(dasin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int dasleng;
+
+extern FILE *dasin, *dasout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up dastext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up dastext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via dasrestart()), so that the user can continue scanning by
+	 * just pointing dasin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when dastext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int dasleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow daswrap()'s to do buffer switches
+ * instead of setting up a fresh dasin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void dasrestart (FILE *input_file  );
+void das_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE das_create_buffer (FILE *file,int size  );
+void das_delete_buffer (YY_BUFFER_STATE b  );
+void das_flush_buffer (YY_BUFFER_STATE b  );
+void daspush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void daspop_buffer_state (void );
+
+static void dasensure_buffer_stack (void );
+static void das_load_buffer_state (void );
+static void das_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER das_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE das_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE das_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE das_scan_bytes (yyconst char *bytes,int len  );
+
+void *dasalloc (yy_size_t  );
+void *dasrealloc (void *,yy_size_t  );
+void dasfree (void *  );
+
+#define yy_new_buffer das_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        dasensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            das_create_buffer(dasin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        dasensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            das_create_buffer(dasin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define daswrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *dasin = (FILE *) 0, *dasout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int daslineno;
+
+int daslineno = 1;
+
+extern char *dastext;
+#define yytext_ptr dastext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up dastext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	(yytext_ptr) -= (yy_more_len); \
+	dasleng = (size_t) (yy_cp - (yytext_ptr)); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 31
+#define YY_END_OF_BUFFER 32
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[188] =
+    {   0,
+        0,    0,   25,   25,   21,   21,    0,    0,   32,   30,
+       18,   19,   24,   20,   13,   13,   17,   16,   13,   13,
+       13,   13,   13,   13,   13,   31,   13,   13,   13,   13,
+       13,   13,   13,   14,   15,   25,   26,   31,   29,   31,
+       21,   22,   31,   18,   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,   25,   26,    0,   27,   28,   21,   23,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   11,   13,   13,   13,   13,
+
+       13,   13,   13,   13,   13,   13,   13,   13,   13,    3,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,    2,   13,   13,   13,   13,    4,    6,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   13,   13,   13,   13,   13,   13,   13,   13,
+       13,   13,   10,    5,    7,   13,   13,   13,   13,   13,
+       13,    8,    9,   13,   13,   13,   13,   13,   13,   13,
+       12,   13,   13,   13,   13,    1,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    5,    6,    1,    7,    1,    1,    7,
+        7,    8,    7,    9,    7,    7,    7,    7,   10,   11,
+       12,   13,    7,   14,    7,    7,    7,    7,   15,    1,
+        1,    1,    1,    1,   16,   17,    7,    7,   18,   19,
+       20,   21,   22,    7,    7,   23,   24,   25,   26,    7,
+        7,   27,   28,   29,   30,    7,    7,   31,   32,    7,
+       33,   34,   33,    1,    7,    1,   35,   36,    7,    7,
+
+       37,   38,   39,   40,   41,    7,    7,   42,   43,   44,
+       45,    7,    7,   46,   47,   48,   49,    7,    7,   50,
+       51,    7,   52,    1,   53,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[54] =
+    {   0,
+        1,    1,    2,    3,    4,    5,    5,    5,    1,    5,
+        5,    5,    5,    5,    1,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    5,    1,    6,    5,    5,    5,    5,    5,    5,
+        5,    5,    5,    5,    5,    5,    5,    5,    5,    5,
+        5,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[195] =
+    {   0,
+        0,    0,   51,   54,   57,   59,    0,    0,  271,  272,
+       62,  272,  272,  272,    0,    0,  272,  272,   42,   35,
+       45,   45,   43,   44,   52,  272,   27,  219,  227,  224,
+      219,  218,   35,  272,  272,   74,  272,  262,  272,    0,
+        0,  272,  261,   78,    0,  241,  233,  220,  212,  230,
+      210,  231,  211,  226,  206,  232,  212,  224,  204,   58,
+      226,  204,  205,  205,  197,  196,  198,  194,  201,  194,
+      195,  196,   91,  272,  234,  272,  272,    0,  272,  220,
+      208,  199,  187,  214,  194,  214,  194,   87,   91,  210,
+      190,  204,  184,  195,  175,    0,  174,  186,  174,  182,
+
+      183,   94,  180,  175,  167,  186,  191,  165,  170,    0,
+      181,  161,  194,  196,  192,  194,  177,  157,  177,  157,
+       95,   98,   99,  153,  158,  150,  183,  185,  149,  150,
+      102,    0,  176,  156,  101,  104,    0,    0,  160,  159,
+      169,  149,  173,  175,  171,  173,  169,  171,  145,  105,
+      130,  140,  164,  166,  143,  123,  155,  150,  127,  124,
+      112,   96,    0,    0,    0,   86,  123,  120,   89,  102,
+       82,    0,    0,  106,  105,   85,   78,   83,  106,   86,
+        0,   85,   93,   53,   49,    0,  272,  139,  145,  151,
+      153,  159,  164,  170
+
+    } ;
+
+static yyconst flex_int16_t yy_def[195] =
+    {   0,
+      187,    1,  188,  188,  189,  189,  190,  190,  187,  187,
+      187,  187,  187,  187,  191,  191,  187,  187,  191,  191,
+      191,  191,  191,  191,  191,  187,  191,  191,  191,  191,
+      191,  191,  191,  187,  187,  192,  187,  187,  187,  193,
+      194,  187,  187,  187,  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,  192,  187,  187,  187,  187,  194,  187,  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,  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,  191,  191,  191,  191,  191,
+      191,  191,  191,  191,  191,  191,    0,  187,  187,  187,
+      187,  187,  187,  187
+
+    } ;
+
+static yyconst flex_int16_t yy_nxt[326] =
+    {   0,
+       10,   11,   12,   11,   13,   14,   15,   16,   17,   15,
+       15,   15,   15,   15,   18,   19,   20,   15,   21,   15,
+       15,   22,   15,   15,   15,   23,   15,   24,   15,   25,
+       15,   15,   26,   15,   27,   28,   15,   29,   15,   15,
+       30,   15,   15,   15,   31,   15,   32,   15,   33,   15,
+       15,   34,   35,   37,   38,   39,   37,   38,   39,   42,
+       43,   42,   43,   44,   46,   44,   50,   52,   64,   54,
+       47,   56,   58,   60,   65,   71,   74,   75,   61,   44,
+       72,   44,   94,   48,   40,   51,   53,   40,   55,   49,
+       57,   59,   62,   74,   75,  186,  113,   63,  114,  186,
+
+      115,   95,  116,  127,  143,  128,  144,  145,  147,  146,
+      148,  153,  157,  154,  158,  159,  167,  160,  168,  175,
+      186,  185,  184,  183,  181,  182,  181,  181,  181,  180,
+      179,  178,  173,  172,  177,  174,  173,  172,  176,   36,
+       36,   36,   36,   36,   36,   41,   41,   41,   41,   41,
+       41,   26,   26,   26,   26,   26,   26,   45,   45,   73,
+       73,   73,  173,   73,   77,  172,   77,   77,   77,   77,
+       78,  171,  170,   78,   78,   78,  165,  164,  163,  169,
+      166,  165,  164,  165,  164,  165,  164,  163,  163,  162,
+      161,  156,  155,  152,  151,  138,  137,  150,  149,  132,
+
+      142,  141,  140,  139,  138,  137,  138,  137,  136,  135,
+      134,  132,  133,  132,  131,  130,  129,  126,  110,  125,
+      124,  123,  122,  121,  120,  119,  118,  117,  112,  111,
+      110,  110,  109,  108,  107,  106,   76,   96,  105,  104,
+      103,  102,  101,  100,   99,   98,   96,   97,   96,   93,
+       92,   91,   90,   89,   88,   87,   86,   85,   84,   83,
+       82,   81,   80,   79,   76,   70,   69,   68,   67,   66,
+      187,    9,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187
+    } ;
+
+static yyconst flex_int16_t yy_chk[326] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    3,    3,    3,    4,    4,    4,    5,
+        5,    6,    6,   11,   19,   11,   20,   21,   27,   22,
+       19,   23,   24,   25,   27,   33,   36,   36,   25,   44,
+       33,   44,   60,   19,    3,   20,   21,    4,   22,   19,
+       23,   24,   25,   73,   73,  185,   88,   25,   88,  184,
+
+       89,   60,   89,  102,  121,  102,  121,  122,  123,  122,
+      123,  131,  135,  131,  135,  136,  150,  136,  150,  162,
+      183,  182,  180,  179,  178,  177,  176,  175,  174,  171,
+      170,  169,  168,  167,  166,  161,  160,  159,  162,  188,
+      188,  188,  188,  188,  188,  189,  189,  189,  189,  189,
+      189,  190,  190,  190,  190,  190,  190,  191,  191,  192,
+      192,  192,  158,  192,  193,  157,  193,  193,  193,  193,
+      194,  156,  155,  194,  194,  194,  154,  153,  152,  151,
+      149,  148,  147,  146,  145,  144,  143,  142,  141,  140,
+      139,  134,  133,  130,  129,  128,  127,  126,  125,  124,
+
+      120,  119,  118,  117,  116,  115,  114,  113,  112,  111,
+      109,  108,  107,  106,  105,  104,  103,  101,  100,   99,
+       98,   97,   95,   94,   93,   92,   91,   90,   87,   86,
+       85,   84,   83,   82,   81,   80,   75,   72,   71,   70,
+       69,   68,   67,   66,   65,   64,   63,   62,   61,   59,
+       58,   57,   56,   55,   54,   53,   52,   51,   50,   49,
+       48,   47,   46,   43,   38,   32,   31,   30,   29,   28,
+        9,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187,  187,  187,  187,  187,  187,
+      187,  187,  187,  187,  187
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int das_flex_debug;
+int das_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+static int yy_more_flag = 0;
+static int yy_more_len = 0;
+#define yymore() ((yy_more_flag) = 1)
+#define YY_MORE_ADJ (yy_more_len)
+#define YY_RESTORE_YY_MORE_OFFSET
+char *dastext;
+#line 1 "das.lex"
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-2000
+*/ 
+/*
+   Scanner for the DAS. This file works with gnu's flex scanner generator. It
+   returns either ATTR, ID, VAL, TYPE or one of the single character tokens
+   `{', `}', `;', `,' or `\n' as integers. In the case of an ID or VAL, the
+   scanner stores a pointer to the lexeme in yylval (whose type is char *).
+
+   The scanner discards all comment text.
+
+   The scanner returns quoted strings as VALs. Any characters may appear in a
+   quoted string except backslash (\) and quote("). To include these escape
+   them with a backslash.
+   
+   The scanner is not reentrant, but can share name spaces with other
+   scanners.
+   
+   Note:
+   1) The `defines' file das.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `daslex'.
+   3) When bison builds the das.tab.h file, it uses `das' instead of `yy' for
+   variable name prefixes (e.g., yylval --> daslval).
+   4) The quote stuff is very complicated because we want backslash (\)
+   escapes to work and because we want line counts to work too. In order to
+   properly scan a quoted string two C functions are used: one to remove the
+   escape characters from escape sequences and one to remove the trailing
+   quote on the end of the string. 
+
+   jhrg 7/12/94 
+
+   NB: We don't remove the \'s or ending quotes any more -- that way the
+   printed das can be re-parsed. 9/28/94. 
+*/
+#line 63 "das.lex"
+#include "config_dap.h"
+
+#include <cstdio>
+
+static char rcsid[] not_used ={"$Id: das.lex 21577 2009-10-02 16:12:17Z jimg $"};
+
+#ifndef _MSC_VER
+#include <string.h>
+#else
+#include <string>
+#endif
+
+using namespace std;
+
+#include "debug.h"
+#include "parser.h"
+
+using namespace libdap ;
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+/* These defines must precede the das.tab.h include. */
+#define YYSTYPE char *
+#define YY_DECL int daslex YY_PROTO(( void ))
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning DAS object text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+#include "das.tab.hh"
+
+int das_line_num = 1;
+static int start_line;		/* used in quote and comment error handlers */
+
+
+
+
+/* Comment chars (#) are treated specially. Lets hope nobody wants to start
+   A variable name with one... Note that the DAS allows Identifiers to have 
+   parens and colons while the DDS and expr scanners don't. It's too hard to
+   disambiguate functions when IDs have parens in them and adding colons
+   makes parsing the array projections hard. 10/31/2001 jhrg */
+#line 699 "lex.das.cc"
+
+#define INITIAL 0
+#define quote 1
+#define comment 2
+#define xml 3
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int daswrap (void );
+#else
+extern int daswrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( dastext, dasleng, 1, dasout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( dasin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( dasin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, dasin))==0 && ferror(dasin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(dasin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int daslex (void);
+
+#define YY_DECL int daslex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after dastext and dasleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 133 "das.lex"
+
+
+#line 858 "lex.das.cc"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! dasin )
+			dasin = stdin;
+
+		if ( ! dasout )
+			dasout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			dasensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				das_create_buffer(dasin,YY_BUF_SIZE );
+		}
+
+		das_load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		(yy_more_len) = 0;
+		if ( (yy_more_flag) )
+			{
+			(yy_more_len) = (yy_c_buf_p) - (yytext_ptr);
+			(yy_more_flag) = 0;
+			}
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of dastext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 188 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 272 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 135 "das.lex"
+daslval = dastext; return SCAN_ATTR;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 137 "das.lex"
+daslval = dastext; return SCAN_ALIAS;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 138 "das.lex"
+daslval = dastext; return SCAN_BYTE;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 139 "das.lex"
+daslval = dastext; return SCAN_INT16;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 140 "das.lex"
+daslval = dastext; return SCAN_UINT16;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 141 "das.lex"
+daslval = dastext; return SCAN_INT32;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 142 "das.lex"
+daslval = dastext; return SCAN_UINT32;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 143 "das.lex"
+daslval = dastext; return SCAN_FLOAT32;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 144 "das.lex"
+daslval = dastext; return SCAN_FLOAT64;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 145 "das.lex"
+daslval = dastext; return SCAN_STRING;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 146 "das.lex"
+daslval = dastext; return SCAN_URL;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 147 "das.lex"
+daslval = dastext; return SCAN_XML;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 149 "das.lex"
+{
+			    daslval = dastext; 
+			    DBG(cerr << "WORD: " << dastext << endl); 
+			    return SCAN_WORD;
+			}
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 155 "das.lex"
+return (int)*dastext;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 156 "das.lex"
+return (int)*dastext;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 157 "das.lex"
+return (int)*dastext;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 158 "das.lex"
+return (int)*dastext;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 160 "das.lex"
+
+	YY_BREAK
+case 19:
+/* rule 19 can match eol */
+YY_RULE_SETUP
+#line 161 "das.lex"
+++das_line_num;
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 162 "das.lex"
+yy_init = 1; das_line_num = 1; yyterminate();
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 164 "das.lex"
+BEGIN(comment);
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 165 "das.lex"
+
+	YY_BREAK
+case 22:
+/* rule 22 can match eol */
+YY_RULE_SETUP
+#line 166 "das.lex"
+++das_line_num; BEGIN(INITIAL);
+	YY_BREAK
+case 23:
+/* rule 23 can match eol */
+YY_RULE_SETUP
+#line 167 "das.lex"
+++das_line_num; BEGIN(INITIAL);
+	YY_BREAK
+case YY_STATE_EOF(comment):
+#line 168 "das.lex"
+yy_init = 1; das_line_num = 1; yyterminate();
+	YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 170 "das.lex"
+BEGIN(quote); start_line = das_line_num; yymore();
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 171 "das.lex"
+yymore();
+	YY_BREAK
+case 26:
+/* rule 26 can match eol */
+YY_RULE_SETUP
+#line 172 "das.lex"
+yymore(); ++das_line_num;
+	YY_BREAK
+case 27:
+/* rule 27 can match eol */
+YY_RULE_SETUP
+#line 173 "das.lex"
+yymore(); ++das_line_num;
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 174 "das.lex"
+yymore();
+	YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 175 "das.lex"
+{ 
+                          BEGIN(INITIAL); 
+
+                          daslval = dastext;
+
+                          return SCAN_WORD;
+                        }
+	YY_BREAK
+case YY_STATE_EOF(quote):
+#line 182 "das.lex"
+{
+                          char msg[256];
+                          sprintf(msg,
+                                  "Unterminated quote (starts on line %d)\n",
+                                  start_line);
+                          YY_FATAL_ERROR(msg);
+                        }
+	YY_BREAK
+case 30:
+/* rule 30 can match eol */
+YY_RULE_SETUP
+#line 190 "das.lex"
+{
+                          if (dastext) {
+                            fprintf(stderr, "Character '%c' (%d) is not",
+                            	    *dastext, *dastext);
+                            fprintf(stderr, " allowed.");
+			  }
+			}
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 197 "das.lex"
+ECHO;
+	YY_BREAK
+#line 1142 "lex.das.cc"
+case YY_STATE_EOF(xml):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed dasin at a new source and called
+			 * daslex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = dasin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( daswrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * dastext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of daslex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					dasrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			dasrestart(dasin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 188 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 188 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 187);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up dastext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					dasrestart(dasin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( daswrap( ) )
+						return 0;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve dastext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void dasrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        dasensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            das_create_buffer(dasin,YY_BUF_SIZE );
+	}
+
+	das_init_buffer(YY_CURRENT_BUFFER,input_file );
+	das_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void das_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		daspop_buffer_state();
+	 *		daspush_buffer_state(new_buffer);
+     */
+	dasensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	das_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (daswrap()) processing, but the only time this flag
+	 * is looked at is after daswrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void das_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	dasin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE das_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) dasalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in das_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) dasalloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in das_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	das_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with das_create_buffer()
+ * 
+ */
+    void das_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		dasfree((void *) b->yy_ch_buf  );
+
+	dasfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a dasrestart() or at EOF.
+ */
+    static void das_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	das_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then das_init_buffer was _probably_
+     * called from dasrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void das_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		das_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void daspush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	dasensure_buffer_stack();
+
+	/* This block is copied from das_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from das_switch_to_buffer. */
+	das_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void daspop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	das_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		das_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void dasensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)dasalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)dasrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE das_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) dasalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in das_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	das_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to daslex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       das_scan_bytes() instead.
+ */
+YY_BUFFER_STATE das_scan_string (yyconst char * yystr )
+{
+    
+	return das_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to daslex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE das_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) dasalloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in das_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = das_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in das_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up dastext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		dastext[dasleng] = (yy_hold_char); \
+		(yy_c_buf_p) = dastext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		dasleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int dasget_lineno  (void)
+{
+        
+    return daslineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *dasget_in  (void)
+{
+        return dasin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *dasget_out  (void)
+{
+        return dasout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int dasget_leng  (void)
+{
+        return dasleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *dasget_text  (void)
+{
+        return dastext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void dasset_lineno (int  line_number )
+{
+    
+    daslineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see das_switch_to_buffer
+ */
+void dasset_in (FILE *  in_str )
+{
+        dasin = in_str ;
+}
+
+void dasset_out (FILE *  out_str )
+{
+        dasout = out_str ;
+}
+
+int dasget_debug  (void)
+{
+        return das_flex_debug;
+}
+
+void dasset_debug (int  bdebug )
+{
+        das_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from daslex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    dasin = stdin;
+    dasout = stdout;
+#else
+    dasin = (FILE *) 0;
+    dasout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * daslex_init()
+     */
+    return 0;
+}
+
+/* daslex_destroy is for both reentrant and non-reentrant scanners. */
+int daslex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		das_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		daspop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	dasfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * daslex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *dasalloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *dasrealloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void dasfree (void * ptr )
+{
+	free( (char *) ptr );	/* see dasrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 197 "das.lex"
+
+
+
+// These three glue routines enable DDS to reclaim the memory used to parse a
+// DDS off the wire. They are here because this file can see the YY_*
+// symbols; the file DDS.cc cannot.
+
+void *
+das_buffer(FILE *fp)
+{
+    return (void *)das_create_buffer(fp, YY_BUF_SIZE);
+}
+
+void
+das_switch_to_buffer(void *buf)
+{
+    das_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+das_delete_buffer(void *buf)
+{
+    das_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+
diff --git a/lex.dds.cc b/lex.dds.cc
new file mode 100644
index 0000000..b123100
--- /dev/null
+++ b/lex.dds.cc
@@ -0,0 +1,2103 @@
+#line 2 "lex.dds.cc"
+
+#line 4 "lex.dds.cc"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE ddsrestart(ddsin  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int ddsleng;
+
+extern FILE *ddsin, *ddsout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up ddstext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up ddstext again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via ddsrestart()), so that the user can continue scanning by
+	 * just pointing ddsin at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when ddstext is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int ddsleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow ddswrap()'s to do buffer switches
+ * instead of setting up a fresh ddsin.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void ddsrestart (FILE *input_file  );
+void dds_switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE dds_create_buffer (FILE *file,int size  );
+void dds_delete_buffer (YY_BUFFER_STATE b  );
+void dds_flush_buffer (YY_BUFFER_STATE b  );
+void ddspush_buffer_state (YY_BUFFER_STATE new_buffer  );
+void ddspop_buffer_state (void );
+
+static void ddsensure_buffer_stack (void );
+static void dds_load_buffer_state (void );
+static void dds_init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER dds_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE dds_scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE dds_scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE dds_scan_bytes (yyconst char *bytes,int len  );
+
+void *ddsalloc (yy_size_t  );
+void *ddsrealloc (void *,yy_size_t  );
+void ddsfree (void *  );
+
+#define yy_new_buffer dds_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        ddsensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            dds_create_buffer(ddsin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        ddsensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            dds_create_buffer(ddsin,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define ddswrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *ddsin = (FILE *) 0, *ddsout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int ddslineno;
+
+int ddslineno = 1;
+
+extern char *ddstext;
+#define yytext_ptr ddstext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up ddstext.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	ddsleng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 31
+#define YY_END_OF_BUFFER 32
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[185] =
+    {   0,
+        0,    0,   26,   26,   32,   30,   23,   24,   25,   22,
+       31,   22,    5,    6,    7,   22,   22,   22,   22,   22,
+       22,   22,   22,    3,    4,   22,   22,   22,   22,   22,
+       22,   22,   22,    1,    2,   26,   27,   23,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   26,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   21,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   13,   22,   22,
+
+       22,   22,   12,   22,   22,   22,   22,    9,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,    0,   22,   22,   22,   14,
+       16,   22,   22,   22,   22,   22,   22,   22,   22,   22,
+       22,   22,   22,   22,   22,   22,   22,   22,   22,   28,
+        0,   22,   22,   22,   22,   22,   22,   20,   22,   22,
+       22,   15,   17,   22,   22,   22,   22,   22,    8,   29,
+       18,   19,   22,   22,   22,   22,   22,   22,   10,   22,
+       22,   22,   11,    0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
+        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    2,    1,    1,    5,    1,    6,    1,    1,    7,
+        7,    8,    6,    7,    6,    6,    6,    6,    9,   10,
+       11,   12,    6,   13,    6,    6,    6,   14,   15,    1,
+       16,    1,    1,    1,   17,   18,   19,   20,   21,   22,
+       23,    6,   24,    6,    6,   25,    6,   26,   27,    6,
+       28,   29,   30,   31,   32,    6,    6,    6,   33,    6,
+       34,    6,   35,    1,    6,    1,   36,   37,   38,   39,
+
+       40,   41,   42,    6,   43,    6,    6,   44,    6,   45,
+       46,    6,   47,   48,   49,   50,   51,    6,    6,    6,
+       52,    6,   53,    1,   54,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[55] =
+    {   0,
+        1,    1,    2,    1,    3,    3,    1,    3,    3,    3,
+        3,    3,    3,    1,    1,    1,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    3,    1,    1,    3,    3,    3,    3,    3,
+        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,
+        3,    3,    1,    1
+    } ;
+
+static yyconst flex_int16_t yy_base[188] =
+    {   0,
+        0,    0,  235,  234,  236,  239,   53,  239,  239,    0,
+      239,    0,  239,  239,  239,   23,   41,   34,   31,   35,
+       38,   42,   40,  239,  239,  183,  198,  189,  184,  186,
+      187,   26,   22,  239,  239,    0,  239,   70,    0,  198,
+      178,  196,  176,  198,  178,  199,  179,  190,  170,  189,
+      169,  189,  187,  168,  166,   41,  188,  168,  161,  160,
+      163,  165,  157,  157,  158,  156,  158,  158,    0,  180,
+      160,  182,  162,  180,  160,  175,  155,   74,   78,  162,
+      142,  159,   66,  139,   48,  158,  138,    0,  147,  150,
+      149,  145,   84,  133,  131,   51,  131,    0,  150,   54,
+
+      148,  128,    0,  164,  166,  162,  164,    0,  152,  146,
+      152,  130,  124,  130,   95,   96,  118,  116,  152,  154,
+      123,  117,  123,   99,  139,   93,  119,   98,  101,    0,
+        0,  132,  134,  125,  110,  112,  103,  139,  141,  137,
+      139,  108,  102,  102,  104,   95,  131,  133,  111,  239,
+      138,   90,  129,  126,  127,  124,  116,    0,  102,   95,
+       81,    0,    0,   81,  120,  117,   90,   76,    0,  239,
+        0,    0,  105,   96,   84,   75,   82,   72,    0,   80,
+       60,   44,    0,  239,  115,   68,  118
+    } ;
+
+static yyconst flex_int16_t yy_def[188] =
+    {   0,
+      184,    1,  185,  185,  184,  184,  184,  184,  184,  186,
+      184,  186,  184,  184,  184,  186,  186,  186,  186,  186,
+      186,  186,  186,  184,  184,  186,  186,  186,  186,  186,
+      186,  186,  186,  184,  184,  187,  184,  184,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  187,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  184,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  184,
+      184,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  184,
+      186,  186,  186,  186,  186,  186,  186,  186,  186,  186,
+      186,  186,  186,    0,  184,  184,  184
+    } ;
+
+static yyconst flex_int16_t yy_nxt[294] =
+    {   0,
+        6,    7,    8,    7,    9,   10,   11,   12,   10,   10,
+       10,   10,   10,   13,   14,   15,   10,   16,   10,   17,
+       10,   18,   19,   20,   21,   10,   10,   10,   10,   22,
+       10,   23,   10,   24,   25,   10,   26,   10,   27,   10,
+       28,   29,   30,   31,   10,   10,   10,   10,   32,   10,
+       33,   10,   34,   35,   38,   40,   38,   42,   44,   46,
+       48,   50,   52,   56,   67,   65,   86,  126,   57,   68,
+       39,   38,   53,   38,   41,   66,   43,   45,   47,   49,
+       51,   54,  104,  183,  105,   87,  106,   58,  107,  110,
+      113,   55,  119,  122,  120,  150,  151,  111,  114,  183,
+
+      183,  123,  127,  138,  140,  139,  141,  147,  153,  148,
+      154,  155,  165,  156,  166,   36,   36,   36,   69,  182,
+       69,  179,  181,  179,  180,  179,  178,  177,  172,  171,
+      169,  176,  175,  174,  173,  172,  171,  172,  171,  169,
+      170,  169,  163,  162,  168,  158,  167,  164,  163,  162,
+      163,  162,  161,  158,  160,  159,  158,  157,  152,  149,
+      146,  145,  144,  131,  130,  143,  142,  137,  136,  135,
+      134,  133,  132,  131,  130,  131,  130,  129,  128,  125,
+      124,  121,  108,  103,  118,  117,   98,  116,  115,  112,
+      109,  108,  108,  103,  103,  102,  101,  100,   99,   98,
+
+       98,   88,   97,   96,   95,   94,   93,   92,   91,   90,
+       89,   88,   88,   85,   84,   83,   82,   81,   80,   79,
+       78,   77,   76,   75,   74,   73,   72,   71,   70,   64,
+       63,   62,   61,   60,   59,  184,   37,   37,    5,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184
+
+    } ;
+
+static yyconst flex_int16_t yy_chk[294] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    7,   16,    7,   17,   18,   19,
+       20,   21,   22,   23,   33,   32,   56,  100,   23,   33,
+      186,   38,   22,   38,   16,   32,   17,   18,   19,   20,
+       21,   22,   78,  182,   78,   56,   79,   23,   79,   83,
+       85,   22,   93,   96,   93,  126,  126,   83,   85,  181,
+
+      180,   96,  100,  115,  116,  115,  116,  124,  128,  124,
+      128,  129,  143,  129,  143,  185,  185,  185,  187,  178,
+      187,  177,  176,  175,  174,  173,  168,  167,  166,  165,
+      164,  161,  160,  159,  157,  156,  155,  154,  153,  152,
+      151,  149,  148,  147,  146,  145,  144,  142,  141,  140,
+      139,  138,  137,  136,  135,  134,  133,  132,  127,  125,
+      123,  122,  121,  120,  119,  118,  117,  114,  113,  112,
+      111,  110,  109,  107,  106,  105,  104,  102,  101,   99,
+       97,   95,   94,   92,   91,   90,   89,   87,   86,   84,
+       82,   81,   80,   77,   76,   75,   74,   73,   72,   71,
+
+       70,   68,   67,   66,   65,   64,   63,   62,   61,   60,
+       59,   58,   57,   55,   54,   53,   52,   51,   50,   49,
+       48,   47,   46,   45,   44,   43,   42,   41,   40,   31,
+       30,   29,   28,   27,   26,    5,    4,    3,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184,  184,  184,  184,  184,  184,  184,  184,
+      184,  184,  184
+
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int dds_flex_debug;
+int dds_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *ddstext;
+#line 1 "dds.lex"
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1994-1999
+
+*/
+/*
+   Scanner for the DDS. This file works with gnu's flex scanner generator. It
+   returns either DATASET, INDEPENDENT, DEPENDENT, ARRAY, MAPS, LIST,
+   SEQUENCE, STRUCTURE, FUNCTION, GRID, BYTE, INT32, FLOAT64, STRING, URL, ID
+   or one of the single character tokens `{', `}', `;', `=' or `\n' as
+   integers. In the case of an ID, the scanner stores a pointer to the lexeme
+   in yylval (whose type is char *).
+
+   The scanner discards all comment text.
+
+   The scanner is not reentrant, but can share name spaces with other
+   scanners.
+
+   Note:
+   1) The `defines' file dds.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `ddslex'.
+   3) When bison builds the dds.tab.h file, it uses `dds' instead of `yy' for
+   variable name prefixes (e.g., yylval --> ddslval).
+
+   jhrg 8/29/94
+*/
+#line 53 "dds.lex"
+
+#include "config_dap.h"
+
+#include <cstdio>
+#include <cstring>
+
+static char rcsid[] not_used = {"$Id: dds.lex 20716 2009-04-08 19:50:54Z jimg $"};
+
+#include "parser.h"
+#include "dds.tab.hh"
+#include "escaping.h"
+
+using namespace libdap ;
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_DECL int ddslex YY_PROTO(( void ))
+
+#define YY_INPUT(buf,result,max_size) { \
+    if (fgets((buf), (max_size), (ddsin)) == NULL) { \
+      *buf = '\0'; \
+    } \
+    result = (feof(ddsin) || *buf == '\0' || strncmp(buf, "Data:\n", 6) == 0) \
+             ? YY_NULL : strlen(buf); \
+}
+
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning DDS object text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+int dds_line_num = 1;
+
+static void store_word();
+
+
+/* See das.lex for comments about the characters allowed in a WORD.
+   10/31/2001 jhrg */
+#line 673 "lex.dds.cc"
+
+#define INITIAL 0
+#define comment 1
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int ddswrap (void );
+#else
+extern int ddswrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( ddstext, ddsleng, 1, ddsout )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( ddsin )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( ddsin ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, ddsin))==0 && ferror(ddsin)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(ddsin); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int ddslex (void);
+
+#define YY_DECL int ddslex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after ddstext and ddsleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 119 "dds.lex"
+
+
+#line 830 "lex.dds.cc"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! ddsin )
+			ddsin = stdin;
+
+		if ( ! ddsout )
+			ddsout = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			ddsensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				dds_create_buffer(ddsin,YY_BUF_SIZE );
+		}
+
+		dds_load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of ddstext. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 185 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 239 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 121 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 122 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 123 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 124 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 125 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 126 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 127 "dds.lex"
+return (int)*ddstext;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 129 "dds.lex"
+store_word(); return SCAN_DATASET;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 130 "dds.lex"
+store_word(); return SCAN_LIST;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 131 "dds.lex"
+store_word(); return SCAN_SEQUENCE;
+	YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 132 "dds.lex"
+store_word(); return SCAN_STRUCTURE;
+	YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 133 "dds.lex"
+store_word(); return SCAN_GRID;
+	YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 134 "dds.lex"
+store_word(); return SCAN_BYTE;
+	YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 135 "dds.lex"
+store_word(); return SCAN_INT16;
+	YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 136 "dds.lex"
+store_word(); return SCAN_UINT16;
+	YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 137 "dds.lex"
+store_word(); return SCAN_INT32;
+	YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 138 "dds.lex"
+store_word(); return SCAN_UINT32;
+	YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 139 "dds.lex"
+store_word(); return SCAN_FLOAT32;
+	YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 140 "dds.lex"
+store_word(); return SCAN_FLOAT64;
+	YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 141 "dds.lex"
+store_word(); return SCAN_STRING;
+	YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 142 "dds.lex"
+store_word(); return SCAN_URL;
+	YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 144 "dds.lex"
+store_word(); return SCAN_WORD;
+	YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 146 "dds.lex"
+
+	YY_BREAK
+case 24:
+/* rule 24 can match eol */
+YY_RULE_SETUP
+#line 147 "dds.lex"
+++dds_line_num;
+	YY_BREAK
+case YY_STATE_EOF(INITIAL):
+#line 148 "dds.lex"
+yy_init = 1; dds_line_num = 1; yyterminate();
+	YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 150 "dds.lex"
+BEGIN(comment);
+	YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 151 "dds.lex"
+
+	YY_BREAK
+case 27:
+/* rule 27 can match eol */
+YY_RULE_SETUP
+#line 152 "dds.lex"
+++dds_line_num; BEGIN(INITIAL);
+	YY_BREAK
+case YY_STATE_EOF(comment):
+#line 153 "dds.lex"
+yy_init = 1; dds_line_num = 1; yyterminate();
+	YY_BREAK
+case 28:
+/* rule 28 can match eol */
+YY_RULE_SETUP
+#line 155 "dds.lex"
+yyterminate();
+	YY_BREAK
+case 29:
+/* rule 29 can match eol */
+YY_RULE_SETUP
+#line 156 "dds.lex"
+yyterminate();
+	YY_BREAK
+case 30:
+/* rule 30 can match eol */
+YY_RULE_SETUP
+#line 158 "dds.lex"
+{
+            if (ddstext) {	/* suppress msgs about `' chars */
+                fprintf(stderr, "Character `%c' is not", *ddstext);
+                fprintf(stderr, " allowed and has been ignored\n");
+	    }
+	}
+	YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 164 "dds.lex"
+ECHO;
+	YY_BREAK
+#line 1086 "lex.dds.cc"
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed ddsin at a new source and called
+			 * ddslex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = ddsin;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( ddswrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * ddstext, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of ddslex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					ddsrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			ddsrestart(ddsin  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 185 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 185 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 184);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up ddstext */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					ddsrestart(ddsin );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( ddswrap( ) )
+						return 0;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve ddstext */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void ddsrestart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        ddsensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            dds_create_buffer(ddsin,YY_BUF_SIZE );
+	}
+
+	dds_init_buffer(YY_CURRENT_BUFFER,input_file );
+	dds_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void dds_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		ddspop_buffer_state();
+	 *		ddspush_buffer_state(new_buffer);
+     */
+	ddsensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	dds_load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (ddswrap()) processing, but the only time this flag
+	 * is looked at is after ddswrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void dds_load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	ddsin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE dds_create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) ddsalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in dds_create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) ddsalloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in dds_create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	dds_init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with dds_create_buffer()
+ * 
+ */
+    void dds_delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		ddsfree((void *) b->yy_ch_buf  );
+
+	ddsfree((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a ddsrestart() or at EOF.
+ */
+    static void dds_init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	dds_flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then dds_init_buffer was _probably_
+     * called from ddsrestart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void dds_flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		dds_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void ddspush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	ddsensure_buffer_stack();
+
+	/* This block is copied from dds_switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from dds_switch_to_buffer. */
+	dds_load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void ddspop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	dds_delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		dds_load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void ddsensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)ddsalloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)ddsrealloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE dds_scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) ddsalloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in dds_scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	dds_switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to ddslex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       dds_scan_bytes() instead.
+ */
+YY_BUFFER_STATE dds_scan_string (yyconst char * yystr )
+{
+    
+	return dds_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to ddslex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE dds_scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) ddsalloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in dds_scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = dds_scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in dds_scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up ddstext. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		ddstext[ddsleng] = (yy_hold_char); \
+		(yy_c_buf_p) = ddstext + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		ddsleng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int ddsget_lineno  (void)
+{
+        
+    return ddslineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *ddsget_in  (void)
+{
+        return ddsin;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *ddsget_out  (void)
+{
+        return ddsout;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int ddsget_leng  (void)
+{
+        return ddsleng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *ddsget_text  (void)
+{
+        return ddstext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void ddsset_lineno (int  line_number )
+{
+    
+    ddslineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see dds_switch_to_buffer
+ */
+void ddsset_in (FILE *  in_str )
+{
+        ddsin = in_str ;
+}
+
+void ddsset_out (FILE *  out_str )
+{
+        ddsout = out_str ;
+}
+
+int ddsget_debug  (void)
+{
+        return dds_flex_debug;
+}
+
+void ddsset_debug (int  bdebug )
+{
+        dds_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from ddslex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    ddsin = stdin;
+    ddsout = stdout;
+#else
+    ddsin = (FILE *) 0;
+    ddsout = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * ddslex_init()
+     */
+    return 0;
+}
+
+/* ddslex_destroy is for both reentrant and non-reentrant scanners. */
+int ddslex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		dds_delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		ddspop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	ddsfree((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * ddslex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *ddsalloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *ddsrealloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void ddsfree (void * ptr )
+{
+	free( (char *) ptr );	/* see ddsrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 164 "dds.lex"
+
+
+
+// These three glue routines enable DDS to reclaim the memory used to parse a
+// DDS off the wire. They are here because this file can see the YY_*
+// symbols; the file DDS.cc cannot.
+
+void *
+dds_buffer(FILE *fp)
+{
+    return (void *)dds_create_buffer(fp, YY_BUF_SIZE);
+}
+
+void
+dds_switch_to_buffer(void *buf)
+{
+    dds_switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+dds_delete_buffer(void *buf)
+{
+    dds_delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+static void
+store_word()
+{
+    // dods2id(string(ddstext)).c_str()
+    strncpy(ddslval.word, ddstext, ID_MAX-1);
+    ddslval.word[ID_MAX-1] = '\0'; // for the paranoid...
+}
+
+
diff --git a/lex.gse_.cc b/lex.gse_.cc
new file mode 100644
index 0000000..63f4834
--- /dev/null
+++ b/lex.gse_.cc
@@ -0,0 +1,1882 @@
+#line 2 "lex.gse_.cc"
+
+#line 4 "lex.gse_.cc"
+
+#define  YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with  platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types. 
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t; 
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN               (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN              (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN              (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX               (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX              (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX              (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX              (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX             (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX             (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else	/* ! __cplusplus */
+
+#if __STDC__
+
+#define YY_USE_CONST
+
+#endif	/* __STDC__ */
+#endif	/* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index.  If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition.  This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state.  The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE gse_restart(gse_in  )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int gse_leng;
+
+extern FILE *gse_in, *gse_out;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+    #define YY_LESS_LINENO(n)
+    
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up gse_text. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		*yy_cp = (yy_hold_char); \
+		YY_RESTORE_YY_MORE_OFFSET \
+		(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+		YY_DO_BEFORE_ACTION; /* set up gse_text again */ \
+		} \
+	while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr)  )
+
+/* The following is because we cannot portably get our hands on size_t
+ * (without autoconf's help, which isn't available because we want
+ * flex-generated scanners to compile on their own).
+ */
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+	{
+	FILE *yy_input_file;
+
+	char *yy_ch_buf;		/* input buffer */
+	char *yy_buf_pos;		/* current position in input buffer */
+
+	/* Size of input buffer in bytes, not including room for EOB
+	 * characters.
+	 */
+	yy_size_t yy_buf_size;
+
+	/* Number of characters read into yy_ch_buf, not including EOB
+	 * characters.
+	 */
+	int yy_n_chars;
+
+	/* Whether we "own" the buffer - i.e., we know we created it,
+	 * and can realloc() it to grow it, and should free() it to
+	 * delete it.
+	 */
+	int yy_is_our_buffer;
+
+	/* Whether this is an "interactive" input source; if so, and
+	 * if we're using stdio for input, then we want to use getc()
+	 * instead of fread(), to make sure we stop fetching input after
+	 * each newline.
+	 */
+	int yy_is_interactive;
+
+	/* Whether we're considered to be at the beginning of a line.
+	 * If so, '^' rules will be active on the next match, otherwise
+	 * not.
+	 */
+	int yy_at_bol;
+
+    int yy_bs_lineno; /**< The line count. */
+    int yy_bs_column; /**< The column count. */
+    
+	/* Whether to try to fill the input buffer when we reach the
+	 * end of it.
+	 */
+	int yy_fill_buffer;
+
+	int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+	/* When an EOF's been seen but there's still some text to process
+	 * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+	 * shouldn't try reading from the input source any more.  We might
+	 * still have a bunch of tokens to match, though, because of
+	 * possible backing-up.
+	 *
+	 * When we actually see the EOF, we change the status to "new"
+	 * (via gse_restart()), so that the user can continue scanning by
+	 * just pointing gse_in at a new input file.
+	 */
+#define YY_BUFFER_EOF_PENDING 2
+
+	};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+                          : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when gse_text is formed. */
+static char yy_hold_char;
+static int yy_n_chars;		/* number of characters read into yy_ch_buf */
+int gse_leng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0;		/* whether we need to initialize */
+static int yy_start = 0;	/* start state number */
+
+/* Flag which is used to allow gse_wrap()'s to do buffer switches
+ * instead of setting up a fresh gse_in.  A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void gse_restart (FILE *input_file  );
+void gse__switch_to_buffer (YY_BUFFER_STATE new_buffer  );
+YY_BUFFER_STATE gse__create_buffer (FILE *file,int size  );
+void gse__delete_buffer (YY_BUFFER_STATE b  );
+void gse__flush_buffer (YY_BUFFER_STATE b  );
+void gse_push_buffer_state (YY_BUFFER_STATE new_buffer  );
+void gse_pop_buffer_state (void );
+
+static void gse_ensure_buffer_stack (void );
+static void gse__load_buffer_state (void );
+static void gse__init_buffer (YY_BUFFER_STATE b,FILE *file  );
+
+#define YY_FLUSH_BUFFER gse__flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE gse__scan_buffer (char *base,yy_size_t size  );
+YY_BUFFER_STATE gse__scan_string (yyconst char *yy_str  );
+YY_BUFFER_STATE gse__scan_bytes (yyconst char *bytes,int len  );
+
+void *gse_alloc (yy_size_t  );
+void *gse_realloc (void *,yy_size_t  );
+void gse_free (void *  );
+
+#define yy_new_buffer gse__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){ \
+        gse_ensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            gse__create_buffer(gse_in,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+	}
+
+#define yy_set_bol(at_bol) \
+	{ \
+	if ( ! YY_CURRENT_BUFFER ){\
+        gse_ensure_buffer_stack (); \
+		YY_CURRENT_BUFFER_LVALUE =    \
+            gse__create_buffer(gse_in,YY_BUF_SIZE ); \
+	} \
+	YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+	}
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define gse_wrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *gse_in = (FILE *) 0, *gse_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int gse_lineno;
+
+int gse_lineno = 1;
+
+extern char *gse_text;
+#define yytext_ptr gse_text
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state  );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[]  );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up gse_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+	(yytext_ptr) = yy_bp; \
+	gse_leng = (size_t) (yy_cp - yy_bp); \
+	(yy_hold_char) = *yy_cp; \
+	*yy_cp = '\0'; \
+	(yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 10
+#define YY_END_OF_BUFFER 11
+/* This struct is not used in this scanner,
+   but its presence is necessary. */
+struct yy_trans_info
+	{
+	flex_int32_t yy_verify;
+	flex_int32_t yy_nxt;
+	};
+static yyconst flex_int16_t yy_accept[32] =
+    {   0,
+        0,    0,   11,   10,   10,    3,    3,    3,    1,    8,
+        4,    6,    3,    3,    5,    3,    3,    1,    2,    2,
+        1,    3,    9,    7,    3,    3,    2,    3,    2,    2,
+        0
+    } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    2,    1,    3,    1,    4,    1,    1,    1,
+        1,    1,    5,    1,    5,    6,    4,    7,    7,    7,
+        7,    7,    7,    7,    7,    7,    7,    1,    1,    8,
+        9,   10,    1,    1,   11,    4,    4,    4,   12,   13,
+        4,    4,   14,    4,    4,    4,    4,   15,    4,    4,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        1,    4,    1,    1,    4,    1,   11,    4,    4,    4,
+
+       16,   13,    4,    4,   14,    4,    4,    4,    4,   15,
+        4,    4,    4,    4,    4,    4,    4,    4,    4,    4,
+        4,    4,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1
+    } ;
+
+static yyconst flex_int32_t yy_meta[17] =
+    {   0,
+        1,    1,    2,    2,    2,    2,    2,    1,    1,    1,
+        2,    2,    2,    2,    2,    2
+    } ;
+
+static yyconst flex_int16_t yy_base[33] =
+    {   0,
+        0,    0,   43,   44,   33,    0,   11,   34,   13,   31,
+       44,   30,   23,   26,   44,    0,   29,    0,   15,   17,
+        0,   21,   44,   44,   22,   19,   24,   26,   25,    0,
+       44,   25
+    } ;
+
+static yyconst flex_int16_t yy_def[33] =
+    {   0,
+       31,    1,   31,   31,   31,   32,   32,   32,   32,   31,
+       31,   31,   32,   32,   31,   32,   32,    9,    9,    9,
+        9,   32,   31,   31,   32,   32,    9,   32,   32,   32,
+        0,   31
+    } ;
+
+static yyconst flex_int16_t yy_nxt[61] =
+    {   0,
+        4,    5,    4,    6,    7,    8,    9,   10,   11,   12,
+        6,    6,    6,   13,   14,    6,   17,   18,   20,   21,
+       16,   19,   16,   27,   22,   28,   16,   29,   22,   16,
+       27,   29,   29,   30,   30,   19,   26,   25,   24,   23,
+       19,   15,   31,    3,   31,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31
+    } ;
+
+static yyconst flex_int16_t yy_chk[61] =
+    {   0,
+        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+        1,    1,    1,    1,    1,    1,    7,    7,    9,    9,
+       19,   19,   20,   20,    9,   22,   32,   22,    9,   27,
+       27,   29,   28,   26,   25,   17,   14,   13,   12,   10,
+        8,    5,    3,   31,   31,   31,   31,   31,   31,   31,
+       31,   31,   31,   31,   31,   31,   31,   31,   31,   31
+    } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int gse__flex_debug;
+int gse__flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *gse_text;
+#line 1 "gse.lex"
+/*
+ -*- mode: c++; c-basic-offset:4 -*-
+
+ This file is part of libdap, A C++ implementation of the OPeNDAP Data
+ Access Protocol.
+
+ Copyright (c) 2002,2003 OPeNDAP, Inc.
+ Author: James Gallagher <jgallagher at opendap.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+ 
+ You should have received a copy of the GNU Lesser 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
+
+ You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+ (c) COPYRIGHT URI/MIT 1999
+*/ 
+/*
+  Scanner for grid selection sub-expressions. The scanner is not reentrant,
+  but can share a name space with other scanners.
+
+   Note:
+   1) The `defines' file gse.tab.h is built using `bison -d'.
+   2) Define YY_DECL such that the scanner is called `gse_lex'.
+   3) When bison builds the gse.tab.h file, it uses `gse_' instead
+   of `yy' for variable name prefixes (e.g., yylval --> gse_lval).
+
+   1/13/99 jhrg
+*/
+#line 44 "gse.lex"
+
+#include "config_dap.h"
+
+static char rcsid[] not_used = {"$Id: gse.lex 18500 2008-03-19 19:39:45Z jimg $"};
+
+#include <string>
+#include <cstring>
+
+#include "Error.h"
+
+#ifndef YY_PROTO
+#define YY_PROTO(proto) proto
+#endif
+
+#define YY_DECL int gse_lex YY_PROTO(( void ))
+#define ID_MAX 256
+#define YY_NO_UNPUT 1
+#define YY_NO_INPUT 1
+#define YY_FATAL_ERROR(msg) {\
+    throw(Error(string("Error scanning grid constraint expression text: ") + string(msg))); \
+    yy_fatal_error(msg); /* 'Used' here to suppress warning */ \
+}
+
+#include "gse.tab.hh"
+
+using namespace std;
+using namespace libdap;
+
+static void store_int32();
+static void store_float64();
+static void store_id();
+static void store_op(int op);
+
+/* See das.lex for comments about the characters allowed in a WORD.
+   10/31/2001 jhrg */
+#line 552 "lex.gse_.cc"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int gse_wrap (void );
+#else
+extern int gse_wrap (void );
+#endif
+#endif
+
+    static void yyunput (int c,char *buf_ptr  );
+    
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO (void) fwrite( gse_text, gse_leng, 1, gse_out )
+#endif
+
+/* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+		{ \
+		int c = '*'; \
+		size_t n; \
+		for ( n = 0; n < max_size && \
+			     (c = getc( gse_in )) != EOF && c != '\n'; ++n ) \
+			buf[n] = (char) c; \
+		if ( c == '\n' ) \
+			buf[n++] = (char) c; \
+		if ( c == EOF && ferror( gse_in ) ) \
+			YY_FATAL_ERROR( "input in flex scanner failed" ); \
+		result = n; \
+		} \
+	else \
+		{ \
+		errno=0; \
+		while ( (result = fread(buf, 1, max_size, gse_in))==0 && ferror(gse_in)) \
+			{ \
+			if( errno != EINTR) \
+				{ \
+				YY_FATAL_ERROR( "input in flex scanner failed" ); \
+				break; \
+				} \
+			errno=0; \
+			clearerr(gse_in); \
+			} \
+		}\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int gse_lex (void);
+
+#define YY_DECL int gse_lex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after gse_text and gse_leng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+	YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp, *yy_bp;
+	register int yy_act;
+    
+#line 107 "gse.lex"
+
+
+#line 708 "lex.gse_.cc"
+
+	if ( !(yy_init) )
+		{
+		(yy_init) = 1;
+
+#ifdef YY_USER_INIT
+		YY_USER_INIT;
+#endif
+
+		if ( ! (yy_start) )
+			(yy_start) = 1;	/* first start state */
+
+		if ( ! gse_in )
+			gse_in = stdin;
+
+		if ( ! gse_out )
+			gse_out = stdout;
+
+		if ( ! YY_CURRENT_BUFFER ) {
+			gse_ensure_buffer_stack ();
+			YY_CURRENT_BUFFER_LVALUE =
+				gse__create_buffer(gse_in,YY_BUF_SIZE );
+		}
+
+		gse__load_buffer_state( );
+		}
+
+	while ( 1 )		/* loops until end-of-file is reached */
+		{
+		yy_cp = (yy_c_buf_p);
+
+		/* Support of gse_text. */
+		*yy_cp = (yy_hold_char);
+
+		/* yy_bp points to the position in yy_ch_buf of the start of
+		 * the current run.
+		 */
+		yy_bp = yy_cp;
+
+		yy_current_state = (yy_start);
+yy_match:
+		do
+			{
+			register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+			if ( yy_accept[yy_current_state] )
+				{
+				(yy_last_accepting_state) = yy_current_state;
+				(yy_last_accepting_cpos) = yy_cp;
+				}
+			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+				{
+				yy_current_state = (int) yy_def[yy_current_state];
+				if ( yy_current_state >= 32 )
+					yy_c = yy_meta[(unsigned int) yy_c];
+				}
+			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+			++yy_cp;
+			}
+		while ( yy_base[yy_current_state] != 44 );
+
+yy_find_action:
+		yy_act = yy_accept[yy_current_state];
+		if ( yy_act == 0 )
+			{ /* have to back up */
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			yy_act = yy_accept[yy_current_state];
+			}
+
+		YY_DO_BEFORE_ACTION;
+
+do_action:	/* This label is used only to access EOF actions. */
+
+		switch ( yy_act )
+	{ /* beginning of action switch */
+			case 0: /* must back up */
+			/* undo the effects of YY_DO_BEFORE_ACTION */
+			*yy_cp = (yy_hold_char);
+			yy_cp = (yy_last_accepting_cpos);
+			yy_current_state = (yy_last_accepting_state);
+			goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 109 "gse.lex"
+store_int32(); return SCAN_INT;
+	YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 110 "gse.lex"
+store_float64(); return SCAN_FLOAT;
+	YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 112 "gse.lex"
+store_id(); return SCAN_WORD;
+	YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 114 "gse.lex"
+store_op(SCAN_EQUAL); return SCAN_EQUAL;
+	YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 115 "gse.lex"
+store_op(SCAN_NOT_EQUAL); return SCAN_NOT_EQUAL;
+	YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 116 "gse.lex"
+store_op(SCAN_GREATER); return SCAN_GREATER;
+	YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 117 "gse.lex"
+store_op(SCAN_GREATER_EQL); return SCAN_GREATER_EQL;
+	YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 118 "gse.lex"
+store_op(SCAN_LESS); return SCAN_LESS;
+	YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 119 "gse.lex"
+store_op(SCAN_LESS_EQL); return SCAN_LESS_EQL;
+	YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 121 "gse.lex"
+ECHO;
+	YY_BREAK
+#line 841 "lex.gse_.cc"
+case YY_STATE_EOF(INITIAL):
+	yyterminate();
+
+	case YY_END_OF_BUFFER:
+		{
+		/* Amount of text matched not including the EOB char. */
+		int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+		/* Undo the effects of YY_DO_BEFORE_ACTION. */
+		*yy_cp = (yy_hold_char);
+		YY_RESTORE_YY_MORE_OFFSET
+
+		if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+			{
+			/* We're scanning a new file or input source.  It's
+			 * possible that this happened because the user
+			 * just pointed gse_in at a new source and called
+			 * gse_lex().  If so, then we have to assure
+			 * consistency between YY_CURRENT_BUFFER and our
+			 * globals.  Here is the right place to do so, because
+			 * this is the first action (other than possibly a
+			 * back-up) that will match for the new input source.
+			 */
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+			YY_CURRENT_BUFFER_LVALUE->yy_input_file = gse_in;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+			}
+
+		/* Note that here we test for yy_c_buf_p "<=" to the position
+		 * of the first EOB in the buffer, since yy_c_buf_p will
+		 * already have been incremented past the NUL character
+		 * (since all states make transitions on EOB to the
+		 * end-of-buffer state).  Contrast this with the test
+		 * in input().
+		 */
+		if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			{ /* This was really a NUL. */
+			yy_state_type yy_next_state;
+
+			(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+			yy_current_state = yy_get_previous_state(  );
+
+			/* Okay, we're now positioned to make the NUL
+			 * transition.  We couldn't have
+			 * yy_get_previous_state() go ahead and do it
+			 * for us because it doesn't know how to deal
+			 * with the possibility of jamming (and we don't
+			 * want to build jamming into it because then it
+			 * will run more slowly).
+			 */
+
+			yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+			yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+			if ( yy_next_state )
+				{
+				/* Consume the NUL. */
+				yy_cp = ++(yy_c_buf_p);
+				yy_current_state = yy_next_state;
+				goto yy_match;
+				}
+
+			else
+				{
+				yy_cp = (yy_c_buf_p);
+				goto yy_find_action;
+				}
+			}
+
+		else switch ( yy_get_next_buffer(  ) )
+			{
+			case EOB_ACT_END_OF_FILE:
+				{
+				(yy_did_buffer_switch_on_eof) = 0;
+
+				if ( gse_wrap( ) )
+					{
+					/* Note: because we've taken care in
+					 * yy_get_next_buffer() to have set up
+					 * gse_text, we can now set up
+					 * yy_c_buf_p so that if some total
+					 * hoser (like flex itself) wants to
+					 * call the scanner after we return the
+					 * YY_NULL, it'll still work - another
+					 * YY_NULL will get returned.
+					 */
+					(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+					yy_act = YY_STATE_EOF(YY_START);
+					goto do_action;
+					}
+
+				else
+					{
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+					}
+				break;
+				}
+
+			case EOB_ACT_CONTINUE_SCAN:
+				(yy_c_buf_p) =
+					(yytext_ptr) + yy_amount_of_matched_text;
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_match;
+
+			case EOB_ACT_LAST_MATCH:
+				(yy_c_buf_p) =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+				yy_current_state = yy_get_previous_state(  );
+
+				yy_cp = (yy_c_buf_p);
+				yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+				goto yy_find_action;
+			}
+		break;
+		}
+
+	default:
+		YY_FATAL_ERROR(
+			"fatal flex scanner internal error--no action found" );
+	} /* end of action switch */
+		} /* end of scanning one token */
+} /* end of gse_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ *	EOB_ACT_LAST_MATCH -
+ *	EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ *	EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+    	register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+	register char *source = (yytext_ptr);
+	register int number_to_move, i;
+	int ret_val;
+
+	if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+		YY_FATAL_ERROR(
+		"fatal flex scanner internal error--end of buffer missed" );
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+		{ /* Don't try to fill the buffer, so this is an EOF. */
+		if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+			{
+			/* We matched a single character, the EOB, so
+			 * treat this as a final EOF.
+			 */
+			return EOB_ACT_END_OF_FILE;
+			}
+
+		else
+			{
+			/* We matched some text prior to the EOB, first
+			 * process it.
+			 */
+			return EOB_ACT_LAST_MATCH;
+			}
+		}
+
+	/* Try to read more data. */
+
+	/* First move last chars to start of buffer. */
+	number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+	for ( i = 0; i < number_to_move; ++i )
+		*(dest++) = *(source++);
+
+	if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+		/* don't do the read, it's not guaranteed to return an EOF,
+		 * just force an EOF
+		 */
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+	else
+		{
+			int num_to_read =
+			YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+		while ( num_to_read <= 0 )
+			{ /* Not enough room in the buffer - grow it. */
+
+			/* just a shorter name for the current buffer */
+			YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+			int yy_c_buf_p_offset =
+				(int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+			if ( b->yy_is_our_buffer )
+				{
+				int new_size = b->yy_buf_size * 2;
+
+				if ( new_size <= 0 )
+					b->yy_buf_size += b->yy_buf_size / 8;
+				else
+					b->yy_buf_size *= 2;
+
+				b->yy_ch_buf = (char *)
+					/* Include room in for 2 EOB chars. */
+					gse_realloc((void *) b->yy_ch_buf,b->yy_buf_size + 2  );
+				}
+			else
+				/* Can't grow it, we don't own it. */
+				b->yy_ch_buf = 0;
+
+			if ( ! b->yy_ch_buf )
+				YY_FATAL_ERROR(
+				"fatal error - scanner input buffer overflow" );
+
+			(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+			num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+						number_to_move - 1;
+
+			}
+
+		if ( num_to_read > YY_READ_BUF_SIZE )
+			num_to_read = YY_READ_BUF_SIZE;
+
+		/* Read in more data. */
+		YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+			(yy_n_chars), num_to_read );
+
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	if ( (yy_n_chars) == 0 )
+		{
+		if ( number_to_move == YY_MORE_ADJ )
+			{
+			ret_val = EOB_ACT_END_OF_FILE;
+			gse_restart(gse_in  );
+			}
+
+		else
+			{
+			ret_val = EOB_ACT_LAST_MATCH;
+			YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+				YY_BUFFER_EOF_PENDING;
+			}
+		}
+
+	else
+		ret_val = EOB_ACT_CONTINUE_SCAN;
+
+	(yy_n_chars) += number_to_move;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+	YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+	(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+	return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+    static yy_state_type yy_get_previous_state (void)
+{
+	register yy_state_type yy_current_state;
+	register char *yy_cp;
+    
+	yy_current_state = (yy_start);
+
+	for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+		{
+		register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+		if ( yy_accept[yy_current_state] )
+			{
+			(yy_last_accepting_state) = yy_current_state;
+			(yy_last_accepting_cpos) = yy_cp;
+			}
+		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+			{
+			yy_current_state = (int) yy_def[yy_current_state];
+			if ( yy_current_state >= 32 )
+				yy_c = yy_meta[(unsigned int) yy_c];
+			}
+		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+		}
+
+	return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ *	next_state = yy_try_NUL_trans( current_state );
+ */
+    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )
+{
+	register int yy_is_jam;
+    	register char *yy_cp = (yy_c_buf_p);
+
+	register YY_CHAR yy_c = 1;
+	if ( yy_accept[yy_current_state] )
+		{
+		(yy_last_accepting_state) = yy_current_state;
+		(yy_last_accepting_cpos) = yy_cp;
+		}
+	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+		{
+		yy_current_state = (int) yy_def[yy_current_state];
+		if ( yy_current_state >= 32 )
+			yy_c = yy_meta[(unsigned int) yy_c];
+		}
+	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+	yy_is_jam = (yy_current_state == 31);
+
+	return yy_is_jam ? 0 : yy_current_state;
+}
+
+    static void yyunput (int c, register char * yy_bp )
+{
+	register char *yy_cp;
+    
+    yy_cp = (yy_c_buf_p);
+
+	/* undo effects of setting up gse_text */
+	*yy_cp = (yy_hold_char);
+
+	if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+		{ /* need to shift things up to make room */
+		/* +2 for EOB chars. */
+		register int number_to_move = (yy_n_chars) + 2;
+		register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+					YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+		register char *source =
+				&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+		while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+			*--dest = *--source;
+
+		yy_cp += (int) (dest - source);
+		yy_bp += (int) (dest - source);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+			(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+		if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+			YY_FATAL_ERROR( "flex scanner push-back overflow" );
+		}
+
+	*--yy_cp = (char) c;
+
+	(yytext_ptr) = yy_bp;
+	(yy_hold_char) = *yy_cp;
+	(yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+    static int yyinput (void)
+#else
+    static int input  (void)
+#endif
+
+{
+	int c;
+    
+	*(yy_c_buf_p) = (yy_hold_char);
+
+	if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+		{
+		/* yy_c_buf_p now points to the character we want to return.
+		 * If this occurs *before* the EOB characters, then it's a
+		 * valid NUL; if not, then we've hit the end of the buffer.
+		 */
+		if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+			/* This was really a NUL. */
+			*(yy_c_buf_p) = '\0';
+
+		else
+			{ /* need more input */
+			int offset = (yy_c_buf_p) - (yytext_ptr);
+			++(yy_c_buf_p);
+
+			switch ( yy_get_next_buffer(  ) )
+				{
+				case EOB_ACT_LAST_MATCH:
+					/* This happens because yy_g_n_b()
+					 * sees that we've accumulated a
+					 * token and flags that we need to
+					 * try matching the token before
+					 * proceeding.  But for input(),
+					 * there's no matching to consider.
+					 * So convert the EOB_ACT_LAST_MATCH
+					 * to EOB_ACT_END_OF_FILE.
+					 */
+
+					/* Reset buffer status. */
+					gse_restart(gse_in );
+
+					/*FALLTHROUGH*/
+
+				case EOB_ACT_END_OF_FILE:
+					{
+					if ( gse_wrap( ) )
+						return 0;
+
+					if ( ! (yy_did_buffer_switch_on_eof) )
+						YY_NEW_FILE;
+#ifdef __cplusplus
+					return yyinput();
+#else
+					return input();
+#endif
+					}
+
+				case EOB_ACT_CONTINUE_SCAN:
+					(yy_c_buf_p) = (yytext_ptr) + offset;
+					break;
+				}
+			}
+		}
+
+	c = *(unsigned char *) (yy_c_buf_p);	/* cast for 8-bit char's */
+	*(yy_c_buf_p) = '\0';	/* preserve gse_text */
+	(yy_hold_char) = *++(yy_c_buf_p);
+
+	return c;
+}
+#endif	/* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * 
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+    void gse_restart  (FILE * input_file )
+{
+    
+	if ( ! YY_CURRENT_BUFFER ){
+        gse_ensure_buffer_stack ();
+		YY_CURRENT_BUFFER_LVALUE =
+            gse__create_buffer(gse_in,YY_BUF_SIZE );
+	}
+
+	gse__init_buffer(YY_CURRENT_BUFFER,input_file );
+	gse__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * 
+ */
+    void gse__switch_to_buffer  (YY_BUFFER_STATE  new_buffer )
+{
+    
+	/* TODO. We should be able to replace this entire function body
+	 * with
+	 *		gse_pop_buffer_state();
+	 *		gse_push_buffer_state(new_buffer);
+     */
+	gse_ensure_buffer_stack ();
+	if ( YY_CURRENT_BUFFER == new_buffer )
+		return;
+
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+	gse__load_buffer_state( );
+
+	/* We don't actually know whether we did this switch during
+	 * EOF (gse_wrap()) processing, but the only time this flag
+	 * is looked at is after gse_wrap() is called, so it's safe
+	 * to go ahead and always set it.
+	 */
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void gse__load_buffer_state  (void)
+{
+    	(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+	(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+	gse_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+	(yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * 
+ * @return the allocated buffer state.
+ */
+    YY_BUFFER_STATE gse__create_buffer  (FILE * file, int  size )
+{
+	YY_BUFFER_STATE b;
+    
+	b = (YY_BUFFER_STATE) gse_alloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in gse__create_buffer()" );
+
+	b->yy_buf_size = size;
+
+	/* yy_ch_buf has to be 2 characters longer than the size given because
+	 * we need to put in 2 end-of-buffer characters.
+	 */
+	b->yy_ch_buf = (char *) gse_alloc(b->yy_buf_size + 2  );
+	if ( ! b->yy_ch_buf )
+		YY_FATAL_ERROR( "out of dynamic memory in gse__create_buffer()" );
+
+	b->yy_is_our_buffer = 1;
+
+	gse__init_buffer(b,file );
+
+	return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with gse__create_buffer()
+ * 
+ */
+    void gse__delete_buffer (YY_BUFFER_STATE  b )
+{
+    
+	if ( ! b )
+		return;
+
+	if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+		YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+	if ( b->yy_is_our_buffer )
+		gse_free((void *) b->yy_ch_buf  );
+
+	gse_free((void *) b  );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+    
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a gse_restart() or at EOF.
+ */
+    static void gse__init_buffer  (YY_BUFFER_STATE  b, FILE * file )
+
+{
+	int oerrno = errno;
+    
+	gse__flush_buffer(b );
+
+	b->yy_input_file = file;
+	b->yy_fill_buffer = 1;
+
+    /* If b is the current buffer, then gse__init_buffer was _probably_
+     * called from gse_restart() or through yy_get_next_buffer.
+     * In that case, we don't want to reset the lineno or column.
+     */
+    if (b != YY_CURRENT_BUFFER){
+        b->yy_bs_lineno = 1;
+        b->yy_bs_column = 0;
+    }
+
+        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+    
+	errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * 
+ */
+    void gse__flush_buffer (YY_BUFFER_STATE  b )
+{
+    	if ( ! b )
+		return;
+
+	b->yy_n_chars = 0;
+
+	/* We always need two end-of-buffer characters.  The first causes
+	 * a transition to the end-of-buffer state.  The second causes
+	 * a jam in that state.
+	 */
+	b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+	b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+	b->yy_buf_pos = &b->yy_ch_buf[0];
+
+	b->yy_at_bol = 1;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	if ( b == YY_CURRENT_BUFFER )
+		gse__load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ *  the current state. This function will allocate the stack
+ *  if necessary.
+ *  @param new_buffer The new state.
+ *  
+ */
+void gse_push_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+    	if (new_buffer == NULL)
+		return;
+
+	gse_ensure_buffer_stack();
+
+	/* This block is copied from gse__switch_to_buffer. */
+	if ( YY_CURRENT_BUFFER )
+		{
+		/* Flush out information for old buffer. */
+		*(yy_c_buf_p) = (yy_hold_char);
+		YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+		YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+		}
+
+	/* Only push if top exists. Otherwise, replace top. */
+	if (YY_CURRENT_BUFFER)
+		(yy_buffer_stack_top)++;
+	YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+	/* copied from gse__switch_to_buffer. */
+	gse__load_buffer_state( );
+	(yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ *  The next element becomes the new top.
+ *  
+ */
+void gse_pop_buffer_state (void)
+{
+    	if (!YY_CURRENT_BUFFER)
+		return;
+
+	gse__delete_buffer(YY_CURRENT_BUFFER );
+	YY_CURRENT_BUFFER_LVALUE = NULL;
+	if ((yy_buffer_stack_top) > 0)
+		--(yy_buffer_stack_top);
+
+	if (YY_CURRENT_BUFFER) {
+		gse__load_buffer_state( );
+		(yy_did_buffer_switch_on_eof) = 1;
+	}
+}
+
+/* Allocates the stack if it does not exist.
+ *  Guarantees space for at least one push.
+ */
+static void gse_ensure_buffer_stack (void)
+{
+	int num_to_alloc;
+    
+	if (!(yy_buffer_stack)) {
+
+		/* First allocation is just for 2 elements, since we don't know if this
+		 * scanner will even need a stack. We use 2 instead of 1 to avoid an
+		 * immediate realloc on the next call.
+         */
+		num_to_alloc = 1;
+		(yy_buffer_stack) = (struct yy_buffer_state**)gse_alloc
+								(num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+		
+		memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+				
+		(yy_buffer_stack_max) = num_to_alloc;
+		(yy_buffer_stack_top) = 0;
+		return;
+	}
+
+	if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+		/* Increase the buffer to prepare for a possible push. */
+		int grow_size = 8 /* arbitrary grow size */;
+
+		num_to_alloc = (yy_buffer_stack_max) + grow_size;
+		(yy_buffer_stack) = (struct yy_buffer_state**)gse_realloc
+								((yy_buffer_stack),
+								num_to_alloc * sizeof(struct yy_buffer_state*)
+								);
+
+		/* zero only the new slots.*/
+		memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+		(yy_buffer_stack_max) = num_to_alloc;
+	}
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * 
+ * @return the newly allocated buffer state object. 
+ */
+YY_BUFFER_STATE gse__scan_buffer  (char * base, yy_size_t  size )
+{
+	YY_BUFFER_STATE b;
+    
+	if ( size < 2 ||
+	     base[size-2] != YY_END_OF_BUFFER_CHAR ||
+	     base[size-1] != YY_END_OF_BUFFER_CHAR )
+		/* They forgot to leave room for the EOB's. */
+		return 0;
+
+	b = (YY_BUFFER_STATE) gse_alloc(sizeof( struct yy_buffer_state )  );
+	if ( ! b )
+		YY_FATAL_ERROR( "out of dynamic memory in gse__scan_buffer()" );
+
+	b->yy_buf_size = size - 2;	/* "- 2" to take care of EOB's */
+	b->yy_buf_pos = b->yy_ch_buf = base;
+	b->yy_is_our_buffer = 0;
+	b->yy_input_file = 0;
+	b->yy_n_chars = b->yy_buf_size;
+	b->yy_is_interactive = 0;
+	b->yy_at_bol = 1;
+	b->yy_fill_buffer = 0;
+	b->yy_buffer_status = YY_BUFFER_NEW;
+
+	gse__switch_to_buffer(b  );
+
+	return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to gse_lex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ * 
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ *       gse__scan_bytes() instead.
+ */
+YY_BUFFER_STATE gse__scan_string (yyconst char * yystr )
+{
+    
+	return gse__scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to gse_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * 
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE gse__scan_bytes  (yyconst char * yybytes, int  _yybytes_len )
+{
+	YY_BUFFER_STATE b;
+	char *buf;
+	yy_size_t n;
+	int i;
+    
+	/* Get memory for full buffer, including space for trailing EOB's. */
+	n = _yybytes_len + 2;
+	buf = (char *) gse_alloc(n  );
+	if ( ! buf )
+		YY_FATAL_ERROR( "out of dynamic memory in gse__scan_bytes()" );
+
+	for ( i = 0; i < _yybytes_len; ++i )
+		buf[i] = yybytes[i];
+
+	buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+	b = gse__scan_buffer(buf,n );
+	if ( ! b )
+		YY_FATAL_ERROR( "bad buffer in gse__scan_bytes()" );
+
+	/* It's okay to grow etc. this buffer, and we should throw it
+	 * away when we're done.
+	 */
+	b->yy_is_our_buffer = 1;
+
+	return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+    	(void) fprintf( stderr, "%s\n", msg );
+	exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+	do \
+		{ \
+		/* Undo effects of setting up gse_text. */ \
+        int yyless_macro_arg = (n); \
+        YY_LESS_LINENO(yyless_macro_arg);\
+		gse_text[gse_leng] = (yy_hold_char); \
+		(yy_c_buf_p) = gse_text + yyless_macro_arg; \
+		(yy_hold_char) = *(yy_c_buf_p); \
+		*(yy_c_buf_p) = '\0'; \
+		gse_leng = yyless_macro_arg; \
+		} \
+	while ( 0 )
+
+/* Accessor  methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ * 
+ */
+int gse_get_lineno  (void)
+{
+        
+    return gse_lineno;
+}
+
+/** Get the input stream.
+ * 
+ */
+FILE *gse_get_in  (void)
+{
+        return gse_in;
+}
+
+/** Get the output stream.
+ * 
+ */
+FILE *gse_get_out  (void)
+{
+        return gse_out;
+}
+
+/** Get the length of the current token.
+ * 
+ */
+int gse_get_leng  (void)
+{
+        return gse_leng;
+}
+
+/** Get the current token.
+ * 
+ */
+
+char *gse_get_text  (void)
+{
+        return gse_text;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * 
+ */
+void gse_set_lineno (int  line_number )
+{
+    
+    gse_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * 
+ * @see gse__switch_to_buffer
+ */
+void gse_set_in (FILE *  in_str )
+{
+        gse_in = in_str ;
+}
+
+void gse_set_out (FILE *  out_str )
+{
+        gse_out = out_str ;
+}
+
+int gse_get_debug  (void)
+{
+        return gse__flex_debug;
+}
+
+void gse_set_debug (int  bdebug )
+{
+        gse__flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+        /* Initialization is the same as for the non-reentrant scanner.
+     * This function is called from gse_lex_destroy(), so don't allocate here.
+     */
+
+    (yy_buffer_stack) = 0;
+    (yy_buffer_stack_top) = 0;
+    (yy_buffer_stack_max) = 0;
+    (yy_c_buf_p) = (char *) 0;
+    (yy_init) = 0;
+    (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+    gse_in = stdin;
+    gse_out = stdout;
+#else
+    gse_in = (FILE *) 0;
+    gse_out = (FILE *) 0;
+#endif
+
+    /* For future reference: Set errno on error, since we are called by
+     * gse_lex_init()
+     */
+    return 0;
+}
+
+/* gse_lex_destroy is for both reentrant and non-reentrant scanners. */
+int gse_lex_destroy  (void)
+{
+    
+    /* Pop the buffer stack, destroying each element. */
+	while(YY_CURRENT_BUFFER){
+		gse__delete_buffer(YY_CURRENT_BUFFER  );
+		YY_CURRENT_BUFFER_LVALUE = NULL;
+		gse_pop_buffer_state();
+	}
+
+	/* Destroy the stack itself. */
+	gse_free((yy_buffer_stack) );
+	(yy_buffer_stack) = NULL;
+
+    /* Reset the globals. This is important in a non-reentrant scanner so the next time
+     * gse_lex() is called, initialization will occur. */
+    yy_init_globals( );
+
+    return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+	register int i;
+	for ( i = 0; i < n; ++i )
+		s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+	register int n;
+	for ( n = 0; s[n]; ++n )
+		;
+
+	return n;
+}
+#endif
+
+void *gse_alloc (yy_size_t  size )
+{
+	return (void *) malloc( size );
+}
+
+void *gse_realloc  (void * ptr, yy_size_t  size )
+{
+	/* The cast to (char *) in the following accommodates both
+	 * implementations that use char* generic pointers, and those
+	 * that use void* generic pointers.  It works with the latter
+	 * because both ANSI C and C++ allow castless assignment from
+	 * any pointer type to void*, and deal with argument conversions
+	 * as though doing an assignment.
+	 */
+	return (void *) realloc( (char *) ptr, size );
+}
+
+void gse_free (void * ptr )
+{
+	free( (char *) ptr );	/* see gse_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 121 "gse.lex"
+
+
+
+// Three glue routines for string scanning. These are not declared in the
+// header gse.tab.h nor is YY_BUFFER_STATE. Including these here allows them
+// to see the type definitions in lex.gse.c (where YY_BUFFER_STATE is
+// defined) and allows callers to declare them (since callers outside of this
+// file cannot declare YY_BUFFER_STATE variable).
+
+void *
+gse_string(const char *str)
+{
+    return (void *)gse__scan_string(str);
+}
+
+void
+gse_switch_to_buffer(void *buf)
+{
+    gse__switch_to_buffer((YY_BUFFER_STATE)buf);
+}
+
+void
+gse_delete_buffer(void *buf)
+{
+    gse__delete_buffer((YY_BUFFER_STATE)buf);
+}
+
+// Note that the grid() CE function only deals with numeric maps (8/28/2001
+// jhrg) and that all comparisons are done using doubles. 
+
+static void
+store_int32()
+{
+    gse_lval.val = atof(gse_text);
+}
+
+static void
+store_float64()
+{
+    gse_lval.val = atof(gse_text);
+}
+
+static void
+store_id()
+{
+    strncpy(gse_lval.id, gse_text, ID_MAX-1);
+    gse_lval.id[ID_MAX-1] = '\0';
+}
+
+static void
+store_op(int op)
+{
+    gse_lval.op = op;
+}
+
+
diff --git a/libdap.pc.in b/libdap.pc.in
new file mode 100644
index 0000000..7d7b655
--- /dev/null
+++ b/libdap.pc.in
@@ -0,0 +1,15 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+ccompiler=@CC@
+cppcompiler=@CXX@
+
+Name: @PACKAGE@
+Description: Common items for the OPeNDAP C++ implementation of the Data Access Protocol
+Version: @VERSION@
+Libs: -L${libdir} -ldap
+Libs.private:  @xmlprivatelibs@ @PTHREAD_LIBS@
+Requires.private: @xmlprivatereq@
+Cflags: -I${includedir}/libdap
+
diff --git a/libdap.spec b/libdap.spec
new file mode 100644
index 0000000..f10656c
--- /dev/null
+++ b/libdap.spec
@@ -0,0 +1,171 @@
+Name: libdap
+Summary: The C++ DAP2 library from OPeNDAP
+Version: 3.11.1
+Release: 1
+
+License: LGPLv2+
+Group: Development/Libraries
+URL: http://www.opendap.org/
+Source0: http://www.opendap.org/pub/source/libdap-%{version}.tar.gz
+Requires: curl >= 7.10.6 libxml2 >= 2.6.16
+
+BuildRoot:  %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+
+BuildRequires: curl-devel >= 7.10.6 libxml2-devel >= 2.6.16
+# BuildRequires: doxygen graphviz
+BuildRequires: pkgconfig
+
+# This package could be relocatable. In that case uncomment the following
+# line
+Prefix: %{_prefix}
+
+%description
+The libdap++ library contains an implementation of DAP2. This package
+contains the library, dap-config, getdap. The script dap-config
+simplifies using the library in other projects. The getdap utility is
+a simple command-line tool to read from DAP2 servers. It is built
+using the library and demonstrates simple uses of it. Note that libdap
+used to include a copy of 'deflate' which was used to compress
+responses. This has been removed since it is no longer used and the
+CGI-based code is no longer supported.
+
+%package devel
+Summary: Development and header files from libdap
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires: curl-devel >= 7.10.6 libxml2-devel >= 2.6.16
+Requires: pkgconfig
+# for the /usr/share/aclocal directory ownership
+Requires: automake
+
+%description devel
+This package contains all the files needed to develop applications that
+will use libdap.
+
+# %package doc
+# Summary: Documentation of the libdap library
+# Group: Documentation
+
+# %description doc
+# Documentation of the libdap library.
+
+%prep
+%setup -q
+
+%build
+%configure --disable-static --disable-dependency-tracking
+make %{?_smp_mflags}
+
+# make docs
+
+%install
+rm -rf $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT INSTALL="%{__install} -p"
+rm $RPM_BUILD_ROOT%{_libdir}/*.la
+mv $RPM_BUILD_ROOT%{_bindir}/dap-config-pkgconfig $RPM_BUILD_ROOT%{_bindir}/dap-config
+
+# rm -rf __dist_docs
+# cp -pr docs __dist_docs
+# # those .map and .md5 are of dubious use, remove them
+# rm -f __dist_docs/html/*.map __dist_docs/html/*.md5
+# # use the ChangeLog timestamp to have the same timestamps for the doc files 
+# # for all arches
+# touch -r ChangeLog __dist_docs/html/*
+
+%clean
+rm -rf $RPM_BUILD_ROOT
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%{_bindir}/getdap
+%{_libdir}/libdap.so.*
+%{_libdir}/libdapclient.so.*
+%{_libdir}/libdapserver.so.*
+%doc README NEWS COPYING COPYRIGHT_URI README.dodsrc
+
+%files devel
+%defattr(-,root,root,-)
+%{_libdir}/libdap.so
+%{_libdir}/libdapclient.so
+%{_libdir}/libdapserver.so
+%{_libdir}/pkgconfig/libdap*.pc
+%{_bindir}/dap-config
+%{_includedir}/libdap/
+%{_datadir}/aclocal/*
+
+# %files doc
+# %defattr(-,root,root,-)
+# %doc __dist_docs/html/
+
+%changelog
+* Tue May  4 2010 James Gallagher <jgallagher at opendap.org> - 3.10.2
+
+* Mon Sep 13 2010 James Gallagehr <jgallagher at opendap.org> - 3.11.0
+- 3.11.0 rc 1
+ 
+- 3.10.2 release candidate 1
+ 
+* Mon Feb  1 2010 James Gallagher <jgallagher at opendap.org> - 3.10.0
+- Removed deflate; general update for 3.10.0 release
+
+* Tue Jun 10 2008 James Gallagher <jgallagher at opendap.org> - 3.8.1-1
+- Update for 3.8.1 This is code actually checked in on 4/25/08
+
+* Fri Feb 29 2008 Patrick West <pwest at ucar.edu> - 3.8.0-1
+- Update for 3.8.0
+
+* Wed Nov 28 2007 James Gallagher <jgallagher at opendap.org> - 3.7.10-1
+- Update for 3.7.10
+
+* Tue Jun 26 2007 James Gallagher <jgallagher at opendap.org> - 3.7.8-1
+- Update for 3.7.8
+
+* Thu Feb  8 2007 James Gallagher <jgallagher at opendap.org> - 3.7.7-1
+- Update for 3.7.7
+
+* Thu Feb  8 2007 James Gallagher <jgallagher at opendap.org> - 3.7.5-1
+- Update for 3.7.5
+
+* Tue Jan 02 2007 Patrick West <pwest at ucar.edu> - 3.7.4-1
+- Update for 3.7.4
+
+* Fri Nov 24 2006 James Gallagher <jgallagher at opendap.org> - 3.7.3-1
+- Update for 3.7.3-1
+
+* Mon Sep 15 2006 James Gallagher <jgallagher at opendap.org> - 3.7.2-1
+- Update to 3.7.2
+
+* Mon Aug 21 2006 James Gallagher <jgallagher at opendap.org> - 3.7.1
+- Update to 3.7.1
+
+* Mon Feb 27 2006 James Gallagher <jgallagher at opendap.org> - 3.6.0-1
+- Update to 3.6.0
+
+* Mon Nov 21 2005 Patrice Dumas <pertusus at free.fr> - 3.5.3-2
+- fix Source0
+
+* Tue Aug 30 2005 Patrice Dumas <pertusus at free.fr> - 3.5.2-3
+- Add missing Requires
+
+* Sat Jul  2 2005 Patrice Dumas <pertusus at free.fr> - 3.5.1-2
+- Support for shared libraries
+- Add COPYING
+- Update with fedora template
+
+* Thu May 12 2005 James Gallagher <jimg at comet.opendap.org> - 3.5.0-1
+- Changed: Requires xml2 to libxml2
+
+* Wed May 11 2005 James Gallagher <jimg at zoey.opendap.org> 3.5.0-1
+- Removed version numbers from .a and includes directory.
+
+* Tue May 10 2005 James Gallagher <jimg at zoey.opendap.org> 
+- Mostly works. Problems: Not sure if the %%post script stuff works.
+- Must also address the RHEL3 package deps issue (curl 7.12.0 isn't available;
+  not sure about xml2 2.5.7). At least the deps fail when they are not present!
+
+* Fri May  6 2005 James Gallagher <jimg at zoey.opendap.org> 
+- Initial build.
diff --git a/libdapclient.pc.in b/libdapclient.pc.in
new file mode 100644
index 0000000..8bea689
--- /dev/null
+++ b/libdapclient.pc.in
@@ -0,0 +1,16 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+ccompiler=@CC@
+cppcompiler=@CXX@
+
+Name: libdapclient
+Description: Client side of the OPeNDAP C++ implementation of the Data Access Protocol
+Version: @VERSION@
+Requires: libdap
+Libs: -L${libdir} -ldapclient
+Libs.private: @curlprivatelibs@
+Requires.private: @curlprivatereq@
+Cflags: -I${includedir}/libdap
+
diff --git a/libdapserver.pc.in b/libdapserver.pc.in
new file mode 100644
index 0000000..3430038
--- /dev/null
+++ b/libdapserver.pc.in
@@ -0,0 +1,14 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+ccompiler=@CC@
+cppcompiler=@CXX@
+
+Name: libdapserver
+Description: Server side of the OPeNDAP C++ implementation of the Data Access Protocol
+Version: @VERSION@
+Requires: libdap
+Libs: -L${libdir} -ldapserver
+Cflags: -I${includedir}/libdap
+
diff --git a/mime_util.cc b/mime_util.cc
new file mode 100644
index 0000000..21ec822
--- /dev/null
+++ b/mime_util.cc
@@ -0,0 +1,1044 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//         Reza Nekovei <rnekovei at intcomm.net>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-2001
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+//      reza            Reza Nekovei <rnekovei at intcomm.net>
+
+// A few useful routines which are used in CGI programs.
+//
+// ReZa 9/30/94
+
+#include "config.h"
+#undef FILE_METHODS
+
+static char rcsid[] not_used =
+    {"$Id: mime_util.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include <cstring>
+#include <cstdio>
+#include <ctype.h>
+
+#ifndef TM_IN_SYS_TIME
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifndef WIN32
+#include <unistd.h>    // for access
+#include <sys/wait.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+// Win32 does not define this. 08/21/02 jhrg
+#define F_OK 0
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <string>
+
+#include "mime_util.h"
+#include "Ancillary.h"
+#include "util.h"  // This supplies flush_stream for WIN32.
+#include "debug.h"
+
+#ifdef WIN32
+#define FILE_DELIMITER '\\'
+#else  //  default to unix
+#define FILE_DELIMITER '/'
+#endif
+
+// ...not using a const string here to avoid global objects. jhrg 12/23/05
+#define CRLF "\r\n"             // Change here, expr-test.cc, in DODSFilter and ResponseBuilder
+
+using namespace std;
+
+namespace libdap {
+
+/** Get the last modified time. Assume <tt>name</tt> is a file and
+    find its last modified time. If <tt>name</tt> is not a file, then
+    return now as the last modified time.
+    @param name The name of a file.
+    @return The last modified time or the current time. */
+time_t
+last_modified_time(const string &name)
+{
+    struct stat m;
+
+    if (stat(name.c_str(), &m) == 0 && (S_IFREG & m.st_mode))
+        return m.st_mtime;
+    else
+        return time(0);
+}
+// Return a MIME rfc-822 date. The grammar for this is:
+//       date-time   =  [ day "," ] date time        ; dd mm yy
+//                                                   ;  hh:mm:ss zzz
+//
+//       day         =  "Mon"  / "Tue" /  "Wed"  / "Thu"
+//                   /  "Fri"  / "Sat" /  "Sun"
+//
+//       date        =  1*2DIGIT month 2DIGIT        ; day month year
+//                                                   ;  e.g. 20 Jun 82
+//                   NB: year is 4 digit; see RFC 1123. 11/30/99 jhrg
+//
+//       month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr"
+//                   /  "May"  /  "Jun" /  "Jul"  /  "Aug"
+//                   /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
+//
+//       time        =  hour zone                    ; ANSI and Military
+//
+//       hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT]
+//                                                   ; 00:00:00 - 23:59:59
+//
+//       zone        =  "UT"  / "GMT"                ; Universal Time
+//                                                   ; North American : UT
+//                   /  "EST" / "EDT"                ;  Eastern:  - 5/ - 4
+//                   /  "CST" / "CDT"                ;  Central:  - 6/ - 5
+//                   /  "MST" / "MDT"                ;  Mountain: - 7/ - 6
+//                   /  "PST" / "PDT"                ;  Pacific:  - 8/ - 7
+//                   /  1ALPHA                       ; Military: Z = UT;
+//                                                   ;  A:-1; (J not used)
+//                                                   ;  M:-12; N:+1; Y:+12
+//                   / ( ("+" / "-") 4DIGIT )        ; Local differential
+//                                                   ;  hours+min. (HHMM)
+
+static const char *days[] =
+    {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+    };
+static const char *months[] =
+    {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+     "Aug", "Sep", "Oct", "Nov", "Dec"
+    };
+
+#ifdef _MSC_VER
+#define snprintf sprintf_s
+#endif
+/** Given a constant pointer to a <tt>time_t</tt>, return a RFC
+    822/1123 style date.
+
+    This function returns the RFC 822 date with the exception that the RFC
+    1123 modification for four-digit years is implemented.
+
+    @return The RFC 822/1123 style date in a C++ string.
+    @param t A const <tt>time_t</tt> pointer. */
+string
+rfc822_date(const time_t t)
+{
+    struct tm *stm = gmtime(&t);
+    char d[256];
+
+    snprintf(d, 255, "%s, %02d %s %4d %02d:%02d:%02d GMT", days[stm->tm_wday],
+            stm->tm_mday, months[stm->tm_mon],
+            1900 + stm->tm_year,
+            stm->tm_hour, stm->tm_min, stm->tm_sec);
+    d[255] = '\0';
+    return string(d);
+}
+
+static const int TimLen = 26; // length of string from asctime()
+static const int CLUMP_SIZE = 1024; // size of clumps to new in fmakeword()
+
+/** This sends a formatted block of text to the client, containing
+    version information about various aspects of the server.  The
+    arguments allow you to enclose version information about the
+    filter program and the dataset in the message.  Either argument
+    (or both) may be omitted, in which case no script or dataset
+    version information will be printed.
+
+    @brief Send a version number.
+    @param script_ver The version of the filter script executing this
+    function.
+    @param dataset_ver The version of the dataset.
+    @return TRUE for success. Always returns true.
+*/
+bool
+do_version(const string &script_ver, const string &dataset_ver)
+{
+    fprintf(stdout, "HTTP/1.0 200 OK%s", CRLF) ;
+    fprintf(stdout, "XDODS-Server: %s%s", DVR, CRLF) ;
+    fprintf(stdout, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
+    fprintf(stdout, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
+    fprintf(stdout, "Content-Type: text/plain%s", CRLF) ;
+    fprintf(stdout, CRLF) ;
+
+    fprintf(stdout, "Core software version: %s%s", DVR, CRLF) ;
+
+    if (script_ver != "")
+        fprintf(stdout, "Server Script Revision: %s%s", script_ver.c_str(), CRLF) ;
+
+    if (dataset_ver != "")
+        fprintf(stdout,  "Dataset version: %s%s", dataset_ver.c_str(), CRLF) ;
+
+    fflush(stdout) ;            // Not sure this is needed. jhrg 12/23/05
+
+    return true;
+}
+
+/** Prints an error message in the <tt>httpd</tt> system log file, along with
+    a time stamp and the client host name (or address).
+
+    Use this instead of the functions in liberrmsg.a in the programs run by
+    the CGIs to report errors so those errors show up in HTTPD's log files.
+
+    @deprecated
+    @brief Logs an error message.
+    @return void
+*/
+void
+ErrMsgT(const string &Msgt)
+{
+    time_t TimBin;
+    char TimStr[TimLen];
+
+    if (time(&TimBin) == (time_t) - 1)
+        strncpy(TimStr, "time() error           ", TimLen-1);
+    else {
+        strncpy(TimStr, ctime(&TimBin), TimLen-1);
+        TimStr[TimLen - 2] = '\0'; // overwrite the \n
+    }
+
+    cerr << "[" << TimStr << "] DAP server error: " << Msgt << endl;
+}
+
+// Given a pathname, return just the filename component with any extension
+// removed. The new string resides in newly allocated memory; the caller must
+// delete it when done using the filename.
+// Originally from the netcdf distribution (ver 2.3.2).
+//
+// *** Change to string class argument and return type. jhrg
+// *** Changed so it also removes the#path#of#the#file# from decompressed
+//     files.  rph.
+// Returns: A filename, with path and extension information removed. If
+// memory for the new name cannot be allocated, does not return!
+
+/** Given a pathname, this function returns just the file name
+    component of the path.  That is, given <tt>/a/b/c/ralph.nc.das</tt>, it
+    returns <tt>ralph.nc</tt>.
+
+    @brief Returns the filename portion of a pathname.
+    @param path A C-style simple string containing a pathname to be
+    parsed.
+    @return A C-style simple string containing the filename component
+    of the given pathname.
+*/
+string
+name_path(const string &path)
+{
+    if (path == "")
+        return string("");
+
+    string::size_type delim = path.find_last_of(FILE_DELIMITER);
+    string::size_type pound = path.find_last_of("#");
+    string new_path;
+
+    if (pound != string::npos)
+        new_path = path.substr(pound + 1);
+    else
+        new_path = path.substr(delim + 1);
+
+    return new_path;
+}
+
+// Send string to set the transfer (mime) type and server version
+// Note that the content description filed is used to indicate whether valid
+// information of an error message is contained in the document and the
+// content-encoding field is used to indicate whether the data is compressed.
+// If the data stream is to be compressed, arrange for a compression output
+// filter so that all information sent after the header will be compressed.
+//
+// Returns: false if the compression output filter was to be used but could
+// not be started, true otherwise.
+
+static const char *descrip[] =
+    {"unknown", "dods_das", "dods_dds", "dods_data",
+     "dods_error", "web_error", "dap4-ddx", "dap4-data", "dap4-error",
+     "dap4-data-ddx", "dods_ddx"
+    };
+static const char *encoding[] =
+    {"unknown", "deflate", "x-plain", "gzip", "binary"
+    };
+
+/** This function returns the ObjectType value that matches the given string.
+    Modified to include tests for the descriptions that use hyphens in addition
+    to underscores. 8/1/08 jhrg
+
+    @deprecated  */
+ObjectType
+get_type(const string &value)
+{
+    if ((value == "dods_das") | (value == "dods-das"))
+        return dods_das;
+    else if ((value == "dods_dds") | (value == "dods-dds"))
+        return dods_dds;
+    else if ((value == "dods_data") | (value == "dods-data"))
+        return dods_data;
+    else if ((value == "dods_error") | (value == "dods-error"))
+        return dods_error;
+    else if ((value == "web_error") | (value == "web-error"))
+        return web_error;
+    else if ((value == "dap4_ddx") | (value == "dap4-ddx"))
+        return dap4_ddx;
+    else if ((value == "dap4_data") | (value == "dap4-data"))
+        return dap4_data;
+    else if ((value == "dap4_error") | (value == "dap4-error"))
+        return dap4_error;
+    else if ((value == "dap4_data_ddx") | (value == "dap4-data-ddx"))
+        return dap4_data_ddx;
+    else if ((value == "dods_ddx") | (value == "dods-ddx"))
+        return dods_ddx;
+    else
+        return unknown_type;
+}
+
+/** This function returns the ObjectType value that matches the given string.
+    Modified to include tests for the descriptions that use hyphens in addition
+    to underscores. 8/1/08 jhrg
+
+    @param value Value from the HTTP response header */
+ObjectType
+get_description_type(const string &value)
+{
+    if ((value == "dods_das") | (value == "dods-das"))
+        return dods_das;
+    else if ((value == "dods_dds") | (value == "dods-dds"))
+        return dods_dds;
+    else if ((value == "dods_data") | (value == "dods-data"))
+        return dods_data;
+    else if ((value == "dods_error") | (value == "dods-error"))
+        return dods_error;
+    else if ((value == "web_error") | (value == "web-error"))
+        return web_error;
+    else if ((value == "dods_ddx") | (value == "dods-ddx"))
+        return dods_ddx;
+    else if ((value == "dap4_ddx") | (value == "dap4-ddx"))
+        return dap4_ddx;
+    else if ((value == "dap4_data") | (value == "dap4-data"))
+        return dap4_data;
+    else if ((value == "dap4_error") | (value == "dap4-error"))
+        return dap4_error;
+    else if ((value == "dap4_data_ddx") | (value == "dap4-data-ddx"))
+        return dap4_data_ddx;
+    else if ((value == "dods_ddx") | (value == "dods-ddx"))
+        return dods_ddx;
+    else
+        return unknown_type;
+}
+
+#if FILE_METHODS
+/** Generate an HTTP 1.0 response header for a text document. This is used
+    when returning a serialized DAS or DDS object.
+
+    @deprecated
+    @param out Write the MIME header to this FILE pointer.
+    @param type The type of this this response. Defaults to
+    application/octet-stream.
+    @param ver The version string; denotes the libdap implementation
+    version.
+    @param enc How is this response encoded? Can be plain or deflate or the
+    x_... versions of those. Default is x_plain.
+    @param last_modified The time to use for the Last-Modified header value.
+    Default is zero which means use the current time. */
+void
+set_mime_text(FILE *out, ObjectType type, const string &ver,
+              EncodingType enc, const time_t last_modified)
+{
+    fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
+    if (ver == "") {
+        fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
+    }
+    else {
+        fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
+    }
+    fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
+
+    const time_t t = time(0);
+    fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
+
+    fprintf(out, "Last-Modified: ") ;
+    if (last_modified > 0)
+        fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
+    else
+        fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
+
+    if (type == dap4_ddx)
+        fprintf(out, "Content-Type: text/xml%s", CRLF) ;
+    else
+        fprintf(out, "Content-Type: text/plain%s", CRLF) ;
+
+    // Note that Content-Description is from RFC 2045 (MIME, pt 1), not 2616.
+    // jhrg 12/23/05
+    fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
+    if (type == dods_error) // don't cache our error responses.
+        fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
+    // Don't write a Content-Encoding header for x-plain since that breaks
+    // Netscape on NT. jhrg 3/23/97
+    if (enc != x_plain)
+        fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
+    fprintf(out, CRLF) ;
+}
+#endif
+
+/** Generate an HTTP 1.0 response header for a text document. This is used
+    when returning a serialized DAS or DDS object.
+
+    @deprecated
+    @param strm Write the MIME header to this stream.
+    @param type The type of this this response. Defaults to
+    application/octet-stream.
+    @param ver The version string; denotes the libdap implementation
+    version.
+    @param enc How is this response encoded? Can be plain or deflate or the
+    x_... versions of those. Default is x_plain.
+    @param last_modified The time to use for the Last-Modified header value.
+    Default is zero which means use the current time. */
+void
+set_mime_text(ostream &strm, ObjectType type, const string &ver,
+              EncodingType enc, const time_t last_modified)
+{
+    strm << "HTTP/1.0 200 OK" << CRLF ;
+    if (ver == "") {
+        strm << "XDODS-Server: " << DVR << CRLF ;
+        strm << "XOPeNDAP-Server: " << DVR << CRLF ;
+    }
+    else {
+        strm << "XDODS-Server: " << ver.c_str() << CRLF ;
+        strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
+    }
+    strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Last-Modified: " ;
+    if (last_modified > 0)
+        strm << rfc822_date(last_modified).c_str() << CRLF ;
+    else
+        strm << rfc822_date(t).c_str() << CRLF ;
+
+    if (type == dap4_ddx)
+        strm << "Content-Type: text/xml" << CRLF ;
+    else
+        strm << "Content-Type: text/plain" << CRLF ;
+
+    // Note that Content-Description is from RFC 2045 (MIME, pt 1), not 2616.
+    // jhrg 12/23/05
+    strm << "Content-Description: " << descrip[type] << CRLF ;
+    if (type == dods_error) // don't cache our error responses.
+        strm << "Cache-Control: no-cache" << CRLF ;
+    // Don't write a Content-Encoding header for x-plain since that breaks
+    // Netscape on NT. jhrg 3/23/97
+    if (enc != x_plain)
+        strm << "Content-Encoding: " << encoding[enc] << CRLF ;
+    strm << CRLF ;
+}
+
+#if FILE_METHODS
+/** Generate an HTTP 1.0 response header for a html document.
+
+    @deprecated
+    @param out Write the MIME header to this FILE pointer.
+    @param type The type of this this response.
+    @param ver The version string; denotes the libdap implementation
+    version.
+    @param enc How is this response encoded? Can be plain or deflate or the
+    x_... versions of those. Default is x_plain.
+    @param last_modified The time to use for the Last-Modified header value.
+    Default is zero which means use the current time. */
+void
+set_mime_html(FILE *out, ObjectType type, const string &ver,
+              EncodingType enc, const time_t last_modified)
+{
+    fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
+    if (ver == "") {
+        fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
+    }
+    else {
+        fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
+    }
+    fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
+
+    const time_t t = time(0);
+    fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
+
+    fprintf(out, "Last-Modified: ") ;
+    if (last_modified > 0)
+        fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
+    else
+        fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
+
+    fprintf(out, "Content-type: text/html%s", CRLF) ;
+    // See note above about Content-Description header. jhrg 12/23/05
+    fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
+    if (type == dods_error) // don't cache our error responses.
+        fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
+    // Don't write a Content-Encoding header for x-plain since that breaks
+    // Netscape on NT. jhrg 3/23/97
+    if (enc != x_plain)
+        fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
+    fprintf(out, CRLF) ;
+}
+#endif
+
+/** Generate an HTTP 1.0 response header for a html document.
+
+    @deprecated
+    @param strm Write the MIME header to this stream.
+    @param type The type of this this response.
+    @param ver The version string; denotes the libdap implementation
+    version.
+    @param enc How is this response encoded? Can be plain or deflate or the
+    x_... versions of those. Default is x_plain.
+    @param last_modified The time to use for the Last-Modified header value.
+    Default is zero which means use the current time. */
+void
+set_mime_html(ostream &strm, ObjectType type, const string &ver,
+              EncodingType enc, const time_t last_modified)
+{
+    strm << "HTTP/1.0 200 OK" << CRLF ;
+    if (ver == "") {
+        strm << "XDODS-Server: " << DVR << CRLF ;
+        strm << "XOPeNDAP-Server: " << DVR << CRLF ;
+    }
+    else {
+        strm << "XDODS-Server: " << ver.c_str() << CRLF ;
+        strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
+    }
+    strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Last-Modified: " ;
+    if (last_modified > 0)
+        strm << rfc822_date(last_modified).c_str() << CRLF ;
+    else
+        strm << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Content-type: text/html" << CRLF ;
+    // See note above about Content-Description header. jhrg 12/23/05
+    strm << "Content-Description: " << descrip[type] << CRLF ;
+    if (type == dods_error) // don't cache our error responses.
+        strm << "Cache-Control: no-cache" << CRLF ;
+    // Don't write a Content-Encoding header for x-plain since that breaks
+    // Netscape on NT. jhrg 3/23/97
+    if (enc != x_plain)
+        strm << "Content-Encoding: " << encoding[enc] << CRLF ;
+    strm << CRLF ;
+}
+
+#if FILE_METHODS
+/** Write an HTTP 1.0 response header for our binary response document (i.e.,
+    the DataDDS object).
+
+    @deprecated
+    @param out Write the MIME header to this FILE pointer.
+    @param type The type of this this response. Defaults to
+    application/octet-stream.
+    @param ver The version string; denotes the libdap implementation
+    version.
+    @param enc How is this response encoded? Can be plain or deflate or the
+    x_... versions of those. Default is x_plain.
+    @param last_modified The time to use for the Last-Modified header value.
+    Default is zero which means use the current time.
+ */
+void
+set_mime_binary(FILE *out, ObjectType type, const string &ver,
+                EncodingType enc, const time_t last_modified)
+{
+    fprintf(out, "HTTP/1.0 200 OK%s", CRLF) ;
+    if (ver == "") {
+        fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
+    }
+    else {
+        fprintf(out, "XDODS-Server: %s%s", ver.c_str(), CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", ver.c_str(), CRLF) ;
+    }
+    fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
+
+    const time_t t = time(0);
+    fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
+
+    fprintf(out, "Last-Modified: ") ;
+    if (last_modified > 0)
+        fprintf(out, "%s%s", rfc822_date(last_modified).c_str(), CRLF) ;
+    else
+        fprintf(out, "%s%s", rfc822_date(t).c_str(), CRLF) ;
+
+    fprintf(out, "Content-Type: application/octet-stream%s", CRLF) ;
+    fprintf(out, "Content-Description: %s%s", descrip[type], CRLF) ;
+    if (enc != x_plain)
+        fprintf(out, "Content-Encoding: %s%s", encoding[enc], CRLF) ;
+
+    fprintf(out, CRLF) ;
+}
+#endif
+
+/** Write an HTTP 1.0 response header for our binary response document (i.e.,
+    the DataDDS object).
+
+    @deprecated
+    @param strm Write the MIME header to this stream.
+    @param type The type of this this response. Defaults to
+    application/octet-stream.
+    @param ver The version string; denotes the libdap implementation
+    version.
+    @param enc How is this response encoded? Can be plain or deflate or the
+    x_... versions of those. Default is x_plain.
+    @param last_modified The time to use for the Last-Modified header value.
+    Default is zero which means use the current time.
+ */
+void
+set_mime_binary(ostream &strm, ObjectType type, const string &ver,
+                EncodingType enc, const time_t last_modified)
+{
+    strm << "HTTP/1.0 200 OK" << CRLF ;
+    if (ver == "") {
+        strm << "XDODS-Server: " << DVR << CRLF ;
+        strm << "XOPeNDAP-Server: " << DVR << CRLF ;
+    }
+    else {
+        strm << "XDODS-Server: " << ver.c_str() << CRLF ;
+        strm << "XOPeNDAP-Server: " << ver.c_str() << CRLF ;
+    }
+    strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Last-Modified: " ;
+    if (last_modified > 0)
+        strm << rfc822_date(last_modified).c_str() << CRLF ;
+    else
+        strm << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Content-Type: application/octet-stream" << CRLF ;
+    strm << "Content-Description: " << descrip[type] << CRLF ;
+    if (enc != x_plain)
+        strm << "Content-Encoding: " << encoding[enc] << CRLF ;
+
+    strm << CRLF ;
+}
+
+void set_mime_multipart(ostream &strm, const string &boundary,
+	const string &start, ObjectType type,
+        const string &version, EncodingType enc,
+        const time_t last_modified)
+{
+    strm << "HTTP/1.0 200 OK" << CRLF ;
+    if (version == "") {
+        strm << "XDODS-Server: " << DVR << CRLF ;
+        strm << "XOPeNDAP-Server: " << DVR << CRLF ;
+    }
+    else {
+        strm << "XDODS-Server: " << version.c_str() << CRLF ;
+        strm << "XOPeNDAP-Server: " << version.c_str() << CRLF ;
+    }
+    strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Last-Modified: " ;
+    if (last_modified > 0)
+        strm << rfc822_date(last_modified).c_str() << CRLF ;
+    else
+        strm << rfc822_date(t).c_str() << CRLF ;
+
+    strm << "Content-Type: Multipart/Related; boundary=" << boundary
+	<< "; start=\"<" << start << ">\"; type=\"Text/xml\"" << CRLF ;
+    strm << "Content-Description: " << descrip[type] << CRLF ;
+    if (enc != x_plain)
+        strm << "Content-Encoding: " << encoding[enc] << CRLF ;
+
+    strm << CRLF ;
+}
+
+void set_mime_ddx_boundary(ostream &strm, const string &boundary,
+	const string &cid, ObjectType type, EncodingType enc)
+{
+    strm << "--" << boundary << CRLF;
+    strm << "Content-Type: Text/xml; charset=iso-8859-1" << CRLF;
+    strm << "Content-Id: <" << cid << ">" << CRLF;
+    strm << "Content-Description: " << descrip[type] << CRLF ;
+    if (enc != x_plain)
+         strm << "Content-Encoding: " << encoding[enc] << CRLF ;
+
+    strm << CRLF;
+}
+
+void set_mime_data_boundary(ostream &strm, const string &boundary,
+	const string &cid, ObjectType type, EncodingType enc)
+{
+    strm << "--" << boundary << CRLF;
+    strm << "Content-Type: application/octet-stream" << CRLF;
+    strm << "Content-Id: <" << cid << ">" << CRLF;
+    strm << "Content-Description: " << descrip[type] << CRLF ;
+    if (enc != x_plain)
+         strm << "Content-Encoding: " << encoding[enc] << CRLF ;
+
+    strm << CRLF;
+}
+
+const size_t line_length = 1024;
+
+/** Read the next MIME header from the input stream and return it in a string
+    object. This function consumes any leading whitespace before the next
+    header. It returns an empty string when the blank line that separates
+    the headers from the body is found. this function works for header and
+    separator lines that use either a CRLF pair (the correct line ending) or
+    just a newline (a common error).
+
+    @deprecated
+    @param in Read from this stream (FILE *)
+    @return A string that contains the next header line or is empty indicating
+    the separator has been read.
+    @exception Error is thrown if no header or separator is found.
+    @see parse_mime_header()
+ */
+string get_next_mime_header(FILE *in)
+{
+    // Get the header line and strip \r\n. Some headers end with just \n.
+    // If a blank line is found, return an empty string.
+    char line[line_length];
+    while (!feof(in)) {
+        if (fgets(line, line_length, in)
+        	&& (strncmp(line, CRLF, 2) == 0 || line[0] == '\n'))
+            return "";
+        else {
+            size_t slen = min(strlen(line), line_length); // Never > line_length
+            line[slen - 1] = '\0'; // remove the newline
+            if (line[slen - 2] == '\r') // ...and the preceding carriage return
+                line[slen - 2] = '\0';
+            return string(line);
+        }
+    }
+
+    throw Error("I expected to find a MIME header, but got EOF instead.");
+}
+
+/** Given a string that contains a MIME header line, parse it into the
+    the header (name) and its value. Both are downcased.
+
+    @param header The input line, striped of the ending crlf pair
+    @param name A value-result parameter that holds the header name
+    @param value A value-result parameter that holds the header's value.
+ */
+void parse_mime_header(const string &header, string &name, string &value)
+{
+    istringstream iss(header);
+    // Set downcase
+    char s[line_length];
+    iss.getline(s, 1023, ':');
+    name = s;
+
+    iss.ignore(1023, ' ');
+    iss.getline(s, 1023);
+    value = s;
+
+    downcase(name);
+    downcase(value);
+}
+
+/** Is this string the same as the MPM boundary value?
+
+    @note Since fgets() is used to read into line, it is guaranteed to be
+    null terminated.
+
+    @param line The input to test
+    @param boundary The complete boundary line to test for, excluding
+    terminating characters.
+    @return true is line is a MPM boundary
+ */
+
+bool is_boundary(const char *line, const string &boundary)
+{
+    if (strlen(line) < 2 || !(line[0] == '-' && line[1] == '-'))
+		return false;
+    else
+		return strncmp(line, boundary.c_str(), boundary.length()) == 0;
+}
+
+/** Read the next line of input and test to see if it is a multipart MIME
+    boundary line. If the value of boundary is the default (an empty string)
+    then just test that the line starts with "--". In either case, return the
+    value of boundary just read.
+
+    @param boundary Value of the boundary to look for - optional
+    @param in Read from this FILE*
+    @return The value of teh boundary header read
+    @exception Error if no boundary was found.
+ */
+string read_multipart_boundary(FILE *in, const string &boundary)
+{
+    string boundary_line = get_next_mime_header(in);
+    // If the caller passed in a value for the boundary, test for that value,
+    // else just see that this line starts with '--'.
+    // The value of 'boundary_line' is returned by this function.
+    if ((!boundary.empty() && is_boundary(boundary_line.c_str(), boundary))
+	    || boundary_line.find("--") != 0)
+	throw Error(
+		"The DAP4 data response document is broken - missing or malformed boundary.");
+
+    return boundary_line;
+}
+
+/** Consume the Multipart MIME headers that prefix the DDX in a DataDDX
+    response. The stream pointer is advanced to the start of the DDX. It might
+    seem odd that this function both takes the value of the MPM boundary as
+    a parameter _and_ returns that value as a result, but this code can be
+    used in two different situations. In one case, it is called on a partial
+    document read from stdin and needs to return the value of boundary to the
+    downstream DDX parser to that code can sense the end of hte DDX. In the
+    other case, this function is told the value of boundary and tests for it
+    to ensure document correctness.
+
+    @param in Read from this stream
+    @param content_type The expected value of the Content-Type header
+    @param object_type The expected value of the Content-Description header
+    @param cid The expected value of the Content-Id header - optional.
+
+    @return The value of the MIME boundary
+    @exception Error if the boundary is not found or if any of the expected
+    header values don't match. The optional values are tested only if they
+    are given (the default values are not tested).
+ */
+void read_multipart_headers(FILE *in, const string &content_type,
+	const ObjectType object_type, const string &cid)
+{
+    bool ct = false, cd = false, ci = false;
+
+    string header = get_next_mime_header(in);
+    while (!header.empty()) {
+	string name, value;
+	parse_mime_header(header, name, value);
+
+	if (name =="content-type") {
+	    ct = true;
+	    if (value.find(content_type) == string::npos)
+		throw Error("Content-Type for this part of a DAP4 data response must be " + content_type + ".");
+	}
+	else if (name == "content-description") {
+	    cd = true;
+	    if (get_description_type(value) != object_type)
+		throw Error("Content-Description for this part of a DAP4 data response must be dap4-ddx or dap4-data-ddx");
+	}
+	else if (name == "content-id") {
+	    ci = true;
+	    if (!cid.empty() && value != cid)
+		throw Error("Content-Id mismatch. Expected: " + cid
+			+ ", but got: " + value);
+	}
+
+	header = get_next_mime_header(in);
+    }
+
+    if (!(ct && cd && ci))
+	throw Error("The DAP4 data response document is broken - missing header.");
+}
+/** Given a Content-Id read from the DDX, return the value to look for in a
+    MPM Content-Id header. This function downcases the CID to match the value
+    returned by parse_mime_header.
+
+    @param cid The Content-Id read from the DDX
+    @return The header value to look for.
+    @exception Error if the CID does not start with the string "cid:"
+ */
+string cid_to_header_value(const string &cid)
+{
+    string::size_type offset = cid.find("cid:");
+    if (offset != 0)
+	throw Error("expected CID to start with 'cid:'");
+
+    string value = "<";
+    value.append(cid.substr(offset + 4));
+    value.append(">");
+    downcase(value);
+
+    return value;
+}
+
+#if FILE_METHODS
+/** Generate an HTTP 1.0 response header for an Error object.
+
+    @deprecated
+    @param out Write the MIME header to this FILE pointer.
+    @param code HTTP 1.0 response code. Should be 400, ... 500, ...
+    @param reason Reason string of the HTTP 1.0 response header.
+    @param version The version string; denotes the DAP spec and implementation
+    version. */
+void
+set_mime_error(FILE *out, int code, const string &reason,
+               const string &version)
+{
+    fprintf(out, "HTTP/1.0 %d %s%s", code, reason.c_str(), CRLF) ;
+    if (version == "") {
+        fprintf(out, "XDODS-Server: %s%s", DVR, CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", DVR, CRLF) ;
+    }
+    else {
+        fprintf(out, "XDODS-Server: %s%s", version.c_str(), CRLF) ;
+        fprintf(out, "XOPeNDAP-Server: %s%s", version.c_str(), CRLF) ;
+    }
+    fprintf(out, "XDAP: %s%s", DAP_PROTOCOL_VERSION, CRLF) ;
+
+    const time_t t = time(0);
+    fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
+    fprintf(out, "Cache-Control: no-cache%s", CRLF) ;
+    fprintf(out, CRLF) ;
+}
+#endif
+
+/** Generate an HTTP 1.0 response header for an Error object.
+
+    @deprecated
+    @param strm Write the MIME header to this stream.
+    @param code HTTP 1.0 response code. Should be 400, ... 500, ...
+    @param reason Reason string of the HTTP 1.0 response header.
+    @param version The version string; denotes the DAP spec and implementation
+    version. */
+void
+set_mime_error(ostream &strm, int code, const string &reason,
+               const string &version)
+{
+    strm << "HTTP/1.0 " << code << " " << reason.c_str() << CRLF ;
+    if (version == "") {
+        strm << "XDODS-Server: " << DVR << CRLF ;
+        strm << "XOPeNDAP-Server: " << DVR << CRLF ;
+    }
+    else {
+        strm << "XDODS-Server: " << version.c_str() << CRLF ;
+        strm << "XOPeNDAP-Server: " << version.c_str() << CRLF ;
+    }
+    strm << "XDAP: " << DAP_PROTOCOL_VERSION << CRLF ;
+
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
+    strm << "Cache-Control: no-cache" << CRLF ;
+    strm << CRLF ;
+}
+
+#if FILE_METHODS
+/** Use this function to create a response signaling that the target of a
+    conditional get has not been modified relative to the condition given in
+    the request. This will have to be a date until the servers support ETags.
+
+    @deprecated
+    @brief Send a `Not Modified' response.
+    @param out Write the response to this FILE pointer. */
+void
+set_mime_not_modified(FILE *out)
+{
+    fprintf(out, "HTTP/1.0 304 NOT MODIFIED%s", CRLF) ;
+    const time_t t = time(0);
+    fprintf(out, "Date: %s%s", rfc822_date(t).c_str(), CRLF) ;
+    fprintf(out, CRLF) ;
+}
+#endif
+
+/** Use this function to create a response signaling that the target of a
+    conditional get has not been modified relative to the condition given in
+    the request. This will have to be a date until the servers support ETags.
+
+    @deprecated
+    @brief Send a `Not Modified' response.
+    @param strm Write the response to this stream. */
+void
+set_mime_not_modified(ostream &strm)
+{
+    strm << "HTTP/1.0 304 NOT MODIFIED" << CRLF ;
+    const time_t t = time(0);
+    strm << "Date: " << rfc822_date(t).c_str() << CRLF ;
+    strm << CRLF ;
+}
+
+/** Look for the override file by taking the dataset name and
+    appending `.ovr' to it. If such a file exists, then read it in and
+    store the contents in <tt>doc</tt>. Note that the file contents
+    are not checked to see if they are valid HTML (which they must
+    be).
+
+    @deprecated
+    @return True if the `override file' is present, false otherwise. in the
+    later case <tt>doc</tt>'s contents are undefined.  */
+bool
+found_override(string name, string &doc)
+{
+    ifstream ifs((name + ".ovr").c_str());
+    if (!ifs)
+        return false;
+
+    char tmp[256];
+    doc = "";
+    while (!ifs.eof()) {
+        ifs.getline(tmp, 255);
+        strcat(tmp, "\n");
+        doc += tmp;
+    }
+
+	ifs.close();
+    return true;
+}
+
+/** Read the input stream <tt>in</tt> and discard the MIME header. The MIME
+    header is separated from the body of the document by a single blank line.
+    If no MIME header is found, then the input stream is `emptied' and will
+    contain nothing.
+
+    @deprecated
+    @brief Read and discard the MIME header of the stream <tt>in</tt>.
+    @return True if a MIME header is found, false otherwise.
+*/
+bool
+remove_mime_header(FILE *in)
+{
+    char tmp[256];
+    while (!feof(in)) {
+        char *s = fgets(tmp, 255, in);
+        if (s && strncmp(s, CRLF, 2) == 0)
+            return true;
+    }
+
+    return false;
+}
+
+} // namespace libdap
+
diff --git a/mime_util.h b/mime_util.h
new file mode 100644
index 0000000..cef9301
--- /dev/null
+++ b/mime_util.h
@@ -0,0 +1,153 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+//      reza            Reza Nekovei <reza at intcomm.net>
+
+// External definitions for utility functions used by servers.
+//
+// 2/22/95 jhrg
+
+#ifndef _mime_util_h
+#define _mime_util_h
+
+#ifndef _dds_h
+#include "DDS.h"
+#endif
+
+#ifndef _object_type_h
+#include "ObjectType.h"
+#endif
+
+#ifndef _encoding_type_h
+#include "EncodingType.h"
+#endif
+
+namespace libdap
+{
+
+/** The CGI utilities include a variety of functions useful to
+    programmers developing OPeNDAP CGI filter programs. However, before jumping
+    in and using these, look at the class ResponseBuilder. Always choose to use
+    that class over these functions if you can. Many of these functions were used
+    by the CGI programs that made up the first DAP server; all of those are
+    deprecated and the ResponseBuilder class should be used instead. Some of
+    the other functions are used by ResponseBuilder and the client-side parsing
+    code that needs to identify MIME headers, boundaries, etc.
+
+    @name MIME Utilities
+    @brief A collection of useful functions for writing MIME headers for
+    OPeNDAP servers.
+    @see ResponseBuilder, Connect, DDXParserSAX2
+    */
+
+//@{
+string rfc822_date(const time_t t);
+time_t last_modified_time(const string &name);
+ObjectType get_description_type(const string &value);
+bool is_boundary(const char *line, const string &boundary);
+string cid_to_header_value(const string &cid);
+string read_multipart_boundary(FILE *in, const string &boundary = "");
+void parse_mime_header(const string &header, string &name, string &value);
+string name_path(const string &path);
+
+// All of these are deprecated
+bool do_version(const string &script_ver, const string &dataset_ver);
+void ErrMsgT(const string &Msgt);
+ObjectType get_type(const string &value); // deprecated
+bool remove_mime_header(FILE *in);
+string get_next_mime_header(FILE *in);
+bool found_override(string name, string &doc);
+//@}
+
+/** These functions are used to create the MIME headers for a message
+    from a server to a client. They are public but should not be called
+    directly unless absolutely necessary. Use DODSFilter instead.
+
+    NB: These functions actually write both the response status line
+    <i>and</i> the header.
+
+    @deprecated Use ResponseBuilder instead.
+    @name MIME utility functions
+    @see DODSFilter
+*/
+//@{
+void set_mime_text(FILE *out, ObjectType type = unknown_type,
+                   const string &version = "", EncodingType enc = x_plain,
+                   const time_t last_modified = 0);
+void set_mime_text(ostream &out, ObjectType type = unknown_type,
+                   const string &version = "", EncodingType enc = x_plain,
+                   const time_t last_modified = 0);
+
+void set_mime_html(FILE *out, ObjectType type = unknown_type,
+                   const string &version = "", EncodingType enc = x_plain,
+                   const time_t last_modified = 0);
+void set_mime_html(ostream &out, ObjectType type = unknown_type,
+                   const string &version = "", EncodingType enc = x_plain,
+                   const time_t last_modified = 0);
+
+void set_mime_binary(FILE *out, ObjectType type = unknown_type,
+                     const string &version = "", EncodingType enc = x_plain,
+                     const time_t last_modified = 0);
+void set_mime_binary(ostream &out, ObjectType type = unknown_type,
+                     const string &version = "", EncodingType enc = x_plain,
+                     const time_t last_modified = 0);
+
+void set_mime_multipart(ostream &out, const string &boundary,
+	const string &start, ObjectType type = unknown_type,
+        const string &version = "", EncodingType enc = x_plain,
+        const time_t last_modified = 0);
+
+void set_mime_ddx_boundary(ostream &out, const string &boundary,
+	const string &start, ObjectType type = unknown_type,
+        EncodingType enc = x_plain);
+
+void set_mime_data_boundary(ostream &out, const string &boundary,
+	const string &cid, ObjectType type = unknown_type,
+        EncodingType enc = x_plain);
+
+void read_multipart_headers(FILE *in, const string &content_type,
+	const ObjectType object_type, const string &cid = "");
+
+void set_mime_error(FILE *out, int code = 404,
+                    const string &reason = "Dataset not found",
+                    const string &version = "");
+void set_mime_error(ostream &out, int code = 404,
+                    const string &reason = "Dataset not found",
+                    const string &version = "");
+
+void set_mime_not_modified(FILE *out);
+void set_mime_not_modified(ostream &out);
+
+
+//@}
+
+} // namespace libdap
+
+#endif // _mime_util_h
diff --git a/parser-util.cc b/parser-util.cc
new file mode 100644
index 0000000..c83fc08
--- /dev/null
+++ b/parser-util.cc
@@ -0,0 +1,383 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// These functions are utility functions used by the various DAP parsers (the
+// DAS, DDS and constraint expression parsers).
+// jhrg 9/7/95
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    { "$Id: parser-util.cc 22703 2010-05-11 18:10:01Z jimg $"
+    };
+
+#include <cerrno>
+#include <cassert>
+#include <cstring>
+#include <cmath>
+#include <cstdlib>
+
+#include <iostream>
+#include <sstream>
+
+//  We wrap VC++ 6.x strtod() to account for a short comming
+//  in that function in regards to "NaN".
+#ifdef WIN32
+#include <limits>
+double w32strtod(const char *, char **);
+#endif
+
+#include "debug.h"
+#include "parser.h"             // defines constants such as ID_MAX
+#include "dods-limits.h"
+#include "util.h"               // Jose Garcia: for append_long_to_string.
+
+using std::cerr;
+using std::endl;
+
+#ifdef WIN32
+//  VC++ 6.x strtod() doesn't recognize "NaN".  Account for it
+//  by wrapping it around a check for the Nan string.  Use of
+//  the product is obsolete as of 1/2007, but it is unknown if
+//  the issue is still there in later releases of that product.
+//  ROM - 01/2007
+double w32strtod(const char *val, char **ptr)
+{
+    //  Convert the two char arrays to compare to strings.
+    string *sval = new string(val);
+    string *snan = new string("NaN");
+
+    //  If val doesn't contain "NaN|Nan|nan|etc", use strtod as
+    //  provided.
+    if (stricmp(sval->c_str(), snan->c_str()) != 0)
+        return (strtod(val, ptr));
+
+    //  But if it does, return the bit pattern for Nan and point
+    //  the parsing ptr arg at the trailing '\0'.
+    *ptr = (char *) val + strlen(val);
+    return (std::numeric_limits < double >::quiet_NaN());
+}
+#endif
+
+namespace libdap {
+
+// Deprecated, but still used by the HDF4 EOS server code.
+void
+parse_error(parser_arg * arg, const char *msg, const int line_num,
+            const char *context)
+{
+    // Jose Garcia
+    // This assert(s) is (are) only for developing purposes
+    // For production servers remove it by compiling with NDEBUG
+    assert(arg);
+    assert(msg);
+
+    arg->set_status(FALSE);
+
+    string oss = "";
+
+    if (line_num != 0) {
+        oss += "Error parsing the text on line ";
+        append_long_to_string(line_num, 10, oss);
+    }
+    else {
+        oss += "Parse error.";
+    }
+
+    if (context)
+        oss += (string) " at or near: " + context + (string) "\n" + msg
+               + (string) "\n";
+    else
+        oss += (string) "\n" + msg + (string) "\n";
+
+    arg->set_error(new Error(unknown_error, oss));
+}
+
+void
+parse_error(const char *msg, const int line_num, const char *context)
+{
+    // Jose Garcia
+    // This assert(s) is (are) only for developing purposes
+    // For production servers remove it by compiling with NDEBUG
+    assert(msg);
+
+    string oss = "";
+
+    if (line_num != 0) {
+        oss += "Error parsing the text on line ";
+        append_long_to_string(line_num, 10, oss);
+    }
+    else {
+        oss += "Parse error.";
+    }
+
+    if (context)
+        oss += (string) " at or near: " + context + (string) "\n" + msg
+               + (string) "\n";
+    else
+        oss += (string) "\n" + msg + (string) "\n";
+
+    throw Error(oss);
+}
+
+// context comes from the parser and will always be a char * unless the
+// parsers change dramatically.
+void
+parse_error(const string & msg, const int line_num, const char *context)
+{
+    parse_error(msg.c_str(), line_num, context);
+}
+
+void save_str(char *dst, const char *src, const int line_num)
+{
+    if (strlen(src) >= ID_MAX)
+        parse_error(string("The word `") + string(src)
+                    + string("' is too long (it should be no longer than ")
+                    + long_to_string(ID_MAX) + string(")."), line_num);
+
+    strncpy(dst, src, ID_MAX);
+    dst[ID_MAX - 1] = '\0';     /* in case ... */
+}
+
+void save_str(string & dst, const char *src, const int)
+{
+    dst = src;
+}
+
+bool is_keyword(string id, const string & keyword)
+{
+    downcase(id);
+    id = prune_spaces(id);
+    DBG(cerr << "is_keyword: " << keyword << " = " << id << endl);
+    return id == keyword;
+}
+
+int check_byte(const char *val)
+{
+    char *ptr;
+    long v = strtol(val, &ptr, 0);
+
+    if ((v == 0 && val == ptr) || *ptr != '\0') {
+        return FALSE;
+    }
+
+    DBG(cerr << "v: " << v << endl);
+
+    // We're very liberal here with values. Anything that can fit into 8 bits
+    // is allowed through. Clients will have to deal with the fact that the
+    // ASCII representation for the value might need to be tweaked. This is
+    // especially the case for Java clients where Byte datatypes are
+    // signed. 3/20/2000 jhrg
+    if ((v < 0 && v < DODS_SCHAR_MIN)
+        || (v > 0 && static_cast < unsigned long >(v) > DODS_UCHAR_MAX))
+        return FALSE;
+
+    return TRUE;
+}
+
+// This version of check_int will pass base 8, 10 and 16 numbers when they
+// use the ANSI standard for string representation of those number bases.
+
+int check_int16(const char *val)
+{
+    char *ptr;
+    long v = strtol(val, &ptr, 0);      // `0' --> use val to determine base
+
+    if ((v == 0 && val == ptr) || *ptr != '\0') {
+        return FALSE;
+    }
+    // Don't use the constant from limits.h, use the ones in dods-limits.h
+    if (v > DODS_SHRT_MAX || v < DODS_SHRT_MIN) {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+int check_uint16(const char *val)
+{
+    char *ptr;
+    unsigned long v = strtol(val, &ptr, 0);
+
+    if ((v == 0 && val == ptr) || *ptr != '\0') {
+        return FALSE;
+    }
+
+    if (v > DODS_USHRT_MAX) {
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+int check_int32(const char *val)
+{
+    char *ptr;
+    errno = 0;
+    long v = strtol(val, &ptr, 0);      // `0' --> use val to determine base
+
+
+    if ((v == 0 && val == ptr) || *ptr != '\0') {
+        return FALSE;
+    }
+
+    // We need to check errno since strtol return clamps on overflow so the
+    // check against the DODS values below will always pass, even for out of
+    // bounds values in the string. mjohnson 7/20/09
+    if (errno == ERANGE) {
+        return FALSE;
+    }
+    // This could be combined with the above, or course, but I'm making it
+    // separate to highlite the test. On 64-bit linux boxes 'long' may be 
+    // 64-bits and so 'v' can hold more than a DODS_INT32. jhrg 3/23/10
+    else if (v > DODS_INT_MAX || v < DODS_INT_MIN) {
+	return FALSE;
+    }
+    else {
+	return TRUE;
+    }
+}
+
+int check_uint32(const char *val)
+{
+  // Eat whitespace and check for an initial '-' sign...
+  // strtoul allows an initial minus. mjohnson
+    const char* c = val;
+    while (c && isspace(*c)) {
+         c++;
+    }
+    if (c && (*c == '-')) {
+         return FALSE;
+    }
+
+    char *ptr;
+    errno = 0;
+    unsigned long v = strtoul(val, &ptr, 0);
+
+    if ((v == 0 && val == ptr) || *ptr != '\0') {
+        return FALSE;
+    }
+
+    // check overflow first, or the below check is invalid due to
+    // clamping to the maximum value by strtoul
+    // maybe consider using long long for these checks? mjohnson
+    if (errno == ERANGE) {
+      return FALSE;
+    }
+    // See above.
+    else if (v > DODS_UINT_MAX) {
+	return FALSE;
+    }
+    else {
+	return TRUE;
+    }
+}
+
+// Check first for system errors (like numbers so small they convert
+// (erroneously) to zero. Then make sure that the value is within
+// limits.
+
+int check_float32(const char *val)
+{
+    char *ptr;
+    errno = 0;                  // Clear previous value. Fix for the 64bit
+				// IRIX from Rob Morris. 5/21/2001 jhrg
+
+#ifdef WIN32
+    double v = w32strtod(val, &ptr);
+#else
+    double v = strtod(val, &ptr);
+#endif
+
+    DBG(cerr << "v: " << v << ", ptr: " << ptr
+        << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
+
+    if (errno == ERANGE || (v == 0.0 && val == ptr) || *ptr != '\0')
+	return FALSE;
+#if 0
+    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
+        || *ptr != '\0') {
+        return FALSE;
+    }
+#endif
+
+    DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
+    double abs_val = fabs(v);
+    if (abs_val > DODS_FLT_MAX
+        || (abs_val != 0.0 && abs_val < DODS_FLT_MIN))
+        return FALSE;
+
+    return TRUE;
+}
+
+int check_float64(const char *val)
+{
+    DBG(cerr << "val: " << val << endl);
+    char *ptr;
+    errno = 0;                  // Clear previous value. 5/21/2001 jhrg
+
+#ifdef WIN32
+    double v = w32strtod(val, &ptr);
+#else
+    double v = strtod(val, &ptr);
+#endif
+
+    DBG(cerr << "v: " << v << ", ptr: " << ptr
+        << ", errno: " << errno << ", val==ptr: " << (val == ptr) << endl);
+
+
+    if (errno == ERANGE || (v == 0.0 && val == ptr) || *ptr != '\0')
+	return FALSE;
+#if 0
+    if ((v == 0.0 && (val == ptr || errno == HUGE_VAL || errno == ERANGE))
+        || *ptr != '\0') {
+        return FALSE;
+    }
+#endif
+    DBG(cerr << "fabs(" << val << ") = " << fabs(v) << endl);
+    double abs_val = fabs(v);
+    if (abs_val > DODS_DBL_MAX
+        || (abs_val != 0.0 && abs_val < DODS_DBL_MIN))
+        return FALSE;
+
+    return TRUE;
+}
+
+/*
+  Maybe someday we will really check the Urls to see if they are valid...
+*/
+
+int check_url(const char *)
+{
+    return TRUE;
+}
+
+} // namespace libdap
diff --git a/parser.h b/parser.h
new file mode 100644
index 0000000..6658c09
--- /dev/null
+++ b/parser.h
@@ -0,0 +1,196 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Constants, types and function prototypes for use with the DAP parsers.
+//
+// jhrg 2/3/96
+
+#ifndef _parser_h
+#define _parser_h
+
+#ifndef _error_h
+#include "Error.h"
+#endif
+
+#define YYDEBUG 1
+#undef YYERROR_VERBOSE
+#define YY_NO_UNPUT 1
+
+#define ID_MAX 256
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+
+namespace libdap
+{
+
+/** <tt>parser_arg</tt> is used to pass parameters to the bison parsers and get
+    error codes and objects in return. If <tt>status()</tt> is true, then the
+    <tt>object()</tt> returns a pointer to the object built during the parse
+    process. If <tt>status()</tt> is false, then the <tt>error()</tt>
+    returns a pointer to an Error object.
+
+    Note that the <tt>object()</tt> mfunc returns a void pointer.
+    @brief Pass parameters by reference to a parser.
+    @brief Pass parameters by reference to a parser.
+    */
+
+struct parser_arg
+{
+    void *_object;  // nominally a pointer to an object
+    Error *_error;  // a pointer to an Error object
+    int _status;  // parser status
+
+    parser_arg() : _object(0), _error(0), _status(1)
+    {}
+    parser_arg(void *obj) : _object(obj), _error(0), _status(1)
+    {}
+    virtual ~parser_arg()
+    {
+        if (_error) {
+            delete _error; _error = 0;
+        }
+    }
+
+    void *object()
+    {
+        return _object;
+    }
+    void set_object(void *obj)
+    {
+        _object = obj;
+    }
+    Error *error()
+    {
+        return _error;
+    }
+    void set_error(Error *obj)
+    {
+        _error = obj;
+    }
+    int status()
+    {
+        return _status;
+    }
+    void set_status(int val = 0)
+    {
+        _status = val;
+    }
+};
+
+/** <tt>parser_error()</tt> generates error messages for the various
+    parsers used by libdap. There are two versions of the
+    function, one which takes a <tt>const char *message</tt> and a
+    <tt>const int line_num</tt> and writes the message and line number
+    too stderr and a second which takes an additional <tt>parser_arg
+    *arg</tt> parameter and writes the error message into an Error
+    object which is returned to the caller via the <tt>arg</tt>
+    parameter.
+
+    \note{The second version of this function also accepts a third parameter
+    (<tt>const char *context</tt>) which can be used to provide an
+    additional line of information beyond what is in the string
+    <tt>message</tt>.}
+
+    @name parse_error
+    @return void
+    @brief Generate error messages for the various parsers.
+    */
+//@{
+void parse_error(parser_arg *arg, const char *s, const int line_num = 0,
+                 const char *context = 0);
+void parse_error(const string &msg, const int line_num,
+                 const char *context = 0);
+//@}
+
+/** Given a string (<tt>const char *src</tt>), save it to the
+    temporary variable pointed to by <tt>dst</tt>. If the string is
+    longer than <tt>ID_MAX</tt>, generate and error indicating that
+    <tt>src</tt> was truncated to <tt>ID_MAX</tt> characters during
+    the copy operation. There are two versions of this function; one
+    calls the version of <tt>parser_error()</tt> which writes to
+    stderr. The version which accepts the <tt>parser_arg *arg</tt>
+    argument calls the version of <tt>parser_error()</tt> which
+    generates and Error object.
+
+    @return void
+    @brief Save a string to a temporary variable during the parse.
+    */
+
+void save_str(char *dst, const char *src, const int line_num);
+void save_str(string &dst, const char *src, const int);
+
+bool is_keyword(string id, const string &keyword);
+
+/** Check to see if <tt>val</tt> is a valid byte value. If not,
+    generate an error message using <tt>parser_error()</tt>. There are
+    two versions of <tt>check_byte()</tt>, one which calls
+    <tt>parser_error()</tt> and prints an error message to stderr an
+    one which calls <tt>parser_error()</tt> and generates and Error
+    object.
+
+    @return Returns: True if <i>val</i> is a byte value, False otherwise.
+    @brief Is the value a valid byte?
+    */
+
+int check_byte(const char *val);
+
+/** Like <tt>check_byte()</tt> but for 32-bit integers
+    (<tt>check_uint()</tt> is for unsigned integers).
+
+
+    @brief Is the value a valid integer?
+    */
+
+int check_int16(const char *val);
+int check_uint16(const char *val);
+int check_int32(const char *val);
+int check_uint32(const char *val);
+
+/** Like <tt>check_byte()</tt> but for 64-bit float values.
+
+    @brief Is the value a valid float? */
+
+int check_float32(const char *val);
+int check_float64(const char *val);
+
+/** Currently this function always returns true.
+
+    @brief Is the value a valid URL? */
+
+int check_url(const char *val);
+
+} // namespace libdap
+
+#endif // _parser_h
+
diff --git a/tests/DASTest b/tests/DASTest
new file mode 100755
index 0000000..a351ea3
--- /dev/null
+++ b/tests/DASTest
@@ -0,0 +1,3894 @@
+#! /bin/sh
+# Generated from DASTest.at by GNU Autoconf 2.65.
+#
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This test suite is free software; the Free Software Foundation gives
+# unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+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
+IFS=$as_save_IFS
+
+     ;;
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+# 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
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# 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'"
+
+
+
+
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# How were we run?
+at_cli_args="$@"
+
+
+# Not all shells have the 'times' builtin; the subshell is needed to make
+# sure we discard the 'times: not found' message from the shell.
+at_times_p=false
+(times) >/dev/null 2>&1 && at_times_p=:
+
+# CLI Arguments to pass to the debugging scripts.
+at_debug_args=
+# -e sets to true
+at_errexit_p=false
+# Shall we be verbose?  ':' means no, empty means yes.
+at_verbose=:
+at_quiet=
+# Running several jobs in parallel, 0 means as many as test groups.
+at_jobs=1
+at_traceon=:
+at_trace_echo=:
+at_check_filter_trace=:
+
+# Shall we keep the debug scripts?  Must be `:' when the suite is
+# run by a debug script, so that the script doesn't remove itself.
+at_debug_p=false
+# Display help message?
+at_help_p=false
+# Display the version message?
+at_version_p=false
+# List test groups?
+at_list_p=false
+# --clean
+at_clean=false
+# Test groups to run
+at_groups=
+# Whether a write failure occurred
+at_write_fail=0
+
+# The directory we run the suite in.  Default to . if no -C option.
+at_dir=`pwd`
+# An absolute reference to this testsuite script.
+case $as_myself in
+  [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;;
+  * ) at_myself=$at_dir/$as_myself ;;
+esac
+# Whether -C is in effect.
+at_change_dir=false
+
+# List of the tested programs.
+at_tested=''
+# List of the all the test groups.
+at_groups_all=' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40'
+# As many question marks as there are digits in the last test group number.
+# Used to normalize the test group numbers so that `ls' lists them in
+# numerical order.
+at_format='??'
+# Description of all the test groups.
+at_help_all="1;DASTest.at:31;DAS \$abs_srcdir/das-testsuite/bad_value_test.1.das;das;
+2;DASTest.at:32;DAS \$abs_srcdir/das-testsuite/das.das;das;
+3;DASTest.at:33;DAS \$abs_srcdir/das-testsuite/special.test.das;das;
+4;DASTest.at:34;DAS \$abs_srcdir/das-testsuite/special.test.hdf.das;das;
+5;DASTest.at:35;DAS \$abs_srcdir/das-testsuite/test.1.das;das;
+6;DASTest.at:36;DAS \$abs_srcdir/das-testsuite/test.11.das;das;
+7;DASTest.at:37;DAS \$abs_srcdir/das-testsuite/test.12.das;das;
+8;DASTest.at:38;DAS \$abs_srcdir/das-testsuite/test.13.das;das;
+9;DASTest.at:39;DAS \$abs_srcdir/das-testsuite/test.14.das;das;
+10;DASTest.at:40;DAS \$abs_srcdir/das-testsuite/test.15.das;das;
+11;DASTest.at:41;DAS \$abs_srcdir/das-testsuite/test.16.das;das;
+12;DASTest.at:42;DAS \$abs_srcdir/das-testsuite/test.17.das;das;
+13;DASTest.at:43;DAS \$abs_srcdir/das-testsuite/test.18.das;das;
+14;DASTest.at:44;DAS \$abs_srcdir/das-testsuite/test.19.das;das;
+15;DASTest.at:45;DAS \$abs_srcdir/das-testsuite/test.1a.das;das;
+16;DASTest.at:46;DAS \$abs_srcdir/das-testsuite/test.2.das;das;
+17;DASTest.at:47;DAS \$abs_srcdir/das-testsuite/test.20.das;das;
+18;DASTest.at:48;DAS \$abs_srcdir/das-testsuite/test.21.das;das;
+19;DASTest.at:49;DAS \$abs_srcdir/das-testsuite/test.22.das;das;
+20;DASTest.at:50;DAS \$abs_srcdir/das-testsuite/test.23.das;das;
+21;DASTest.at:51;DAS \$abs_srcdir/das-testsuite/test.24.das;das;
+22;DASTest.at:52;DAS \$abs_srcdir/das-testsuite/test.25.das;das;
+23;DASTest.at:53;DAS \$abs_srcdir/das-testsuite/test.26.das;das;
+24;DASTest.at:54;DAS \$abs_srcdir/das-testsuite/test.27.das;das;
+25;DASTest.at:55;DAS \$abs_srcdir/das-testsuite/test.28.das;das;
+26;DASTest.at:56;DAS \$abs_srcdir/das-testsuite/test.29.das;das;
+27;DASTest.at:57;DAS \$abs_srcdir/das-testsuite/test.3.das;das;
+28;DASTest.at:58;DAS \$abs_srcdir/das-testsuite/test.3.Z.das;das;
+29;DASTest.at:59;DAS \$abs_srcdir/das-testsuite/test.30.das;das;
+30;DASTest.at:60;DAS \$abs_srcdir/das-testsuite/test.31.das;das;
+31;DASTest.at:61;DAS \$abs_srcdir/das-testsuite/test.32.das;das;
+32;DASTest.at:62;DAS \$abs_srcdir/das-testsuite/test.33.das;das;
+33;DASTest.at:63;DAS \$abs_srcdir/das-testsuite/test.34.das;das;
+34;DASTest.at:64;DAS \$abs_srcdir/das-testsuite/test.35.das;das;
+35;DASTest.at:65;DAS \$abs_srcdir/das-testsuite/test.4.das;das;
+36;DASTest.at:66;DAS \$abs_srcdir/das-testsuite/test.5.das;das;
+37;DASTest.at:67;DAS \$abs_srcdir/das-testsuite/test.6.das;das;
+38;DASTest.at:68;DAS \$abs_srcdir/das-testsuite/test.7.das;das;
+39;DASTest.at:69;DAS \$abs_srcdir/das-testsuite/test.8.das;das;
+40;DASTest.at:70;DAS \$abs_srcdir/das-testsuite/test.9.das;das;
+"
+
+# at_fn_validate_ranges NAME...
+# -----------------------------
+# Validate and normalize the test group number contained in each variable
+# NAME. Leading zeroes are treated as decimal.
+at_fn_validate_ranges ()
+{
+  for at_grp
+  do
+    eval at_value=\$$at_grp
+    if test $at_value -lt 1 || test $at_value -gt 40; then
+      $as_echo "invalid test group: $at_value" >&2
+      exit 1
+    fi
+    case $at_value in
+      0*) # We want to treat leading 0 as decimal, like expr and test, but
+	  # AS_VAR_ARITH treats it as octal if it uses $(( )).
+	  # With XSI shells, ${at_value#${at_value%%[1-9]*}} avoids the
+	  # expr fork, but it is not worth the effort to determine if the
+	  # shell supports XSI when the user can just avoid leading 0.
+	  eval $at_grp='`expr $at_value + 0`' ;;
+    esac
+  done
+}
+
+at_prev=
+for at_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$at_prev"; then
+    at_option=$at_prev=$at_option
+    at_prev=
+  fi
+
+  case $at_option in
+  *=*) at_optarg=`expr "x$at_option" : 'x[^=]*=\(.*\)'` ;;
+  *)   at_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $at_option in
+    --help | -h )
+	at_help_p=:
+	;;
+
+    --list | -l )
+	at_list_p=:
+	;;
+
+    --version | -V )
+	at_version_p=:
+	;;
+
+    --clean | -c )
+	at_clean=:
+	;;
+
+    --debug | -d )
+	at_debug_p=:
+	;;
+
+    --errexit | -e )
+	at_debug_p=:
+	at_errexit_p=:
+	;;
+
+    --verbose | -v )
+	at_verbose=; at_quiet=:
+	;;
+
+    --trace | -x )
+	at_traceon='set -x'
+	at_trace_echo=echo
+	at_check_filter_trace=at_fn_filter_trace
+	;;
+
+    [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9])
+	at_fn_validate_ranges at_option
+	as_fn_append at_groups "$at_option "
+	;;
+
+    # Ranges
+    [0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-)
+	at_range_start=`echo $at_option |tr -d X-`
+	at_fn_validate_ranges at_range_start
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/^.* \('$at_range_start' \)/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9])
+	at_range_end=`echo $at_option |tr -d X-`
+	at_fn_validate_ranges at_range_end
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/\( '$at_range_end'\) .*$/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    [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] | \
+    [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][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] )
+	at_range_start=`expr $at_option : '\(.*\)-'`
+	at_range_end=`expr $at_option : '.*-\(.*\)'`
+	if test $at_range_start -gt $at_range_end; then
+	  at_tmp=$at_range_end
+	  at_range_end=$at_range_start
+	  at_range_start=$at_tmp
+	fi
+	at_fn_validate_ranges at_range_start at_range_end
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/^.*\( '$at_range_start' \)/\1/' \
+	      -e 's/\( '$at_range_end'\) .*$/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    # Directory selection.
+    --directory | -C )
+	at_prev=--directory
+	;;
+    --directory=* )
+	at_change_dir=:
+	at_dir=$at_optarg
+	;;
+
+    # Parallel execution.
+    --jobs | -j )
+	at_jobs=0
+	;;
+    --jobs=* | -j[0-9]* )
+	if test -n "$at_optarg"; then
+	  at_jobs=$at_optarg
+	else
+	  at_jobs=`expr X$at_option : 'X-j\(.*\)'`
+	fi
+	case $at_jobs in *[!0-9]*)
+	  at_optname=`echo " $at_option" | sed 's/^ //; s/[0-9=].*//'`
+	  as_fn_error "non-numeric argument to $at_optname: $at_jobs" ;;
+	esac
+	;;
+
+    # Keywords.
+    --keywords | -k )
+	at_prev=--keywords
+	;;
+    --keywords=* )
+	at_groups_selected=$at_help_all
+	at_save_IFS=$IFS
+	IFS=,
+	set X $at_optarg
+	shift
+	IFS=$at_save_IFS
+	for at_keyword
+	do
+	  at_invert=
+	  case $at_keyword in
+	  '!'*)
+	    at_invert="-v"
+	    at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
+	    ;;
+	  esac
+	  # It is on purpose that we match the test group titles too.
+	  at_groups_selected=`$as_echo "$at_groups_selected" |
+	      grep -i $at_invert "^[1-9][^;]*;.*[; ]$at_keyword[ ;]"`
+	done
+	# Smash the newlines.
+	at_groups_selected=`$as_echo "$at_groups_selected" | sed 's/;.*//' |
+	  tr "$as_nl" ' '
+	`
+	as_fn_append at_groups "$at_groups_selected "
+	;;
+
+    *=*)
+	at_envvar=`expr "x$at_option" : 'x\([^=]*\)='`
+	# Reject names that are not valid shell variable names.
+	case $at_envvar in
+	  '' | [0-9]* | *[!_$as_cr_alnum]* )
+	    as_fn_error "invalid variable name: \`$at_envvar'" ;;
+	esac
+	at_value=`$as_echo "$at_optarg" | sed "s/'/'\\\\\\\\''/g"`
+	# Export now, but save eval for later and for debug scripts.
+	export $at_envvar
+	as_fn_append at_debug_args " $at_envvar='$at_value'"
+	;;
+
+     *) $as_echo "$as_me: invalid option: $at_option" >&2
+	$as_echo "Try \`$0 --help' for more information." >&2
+	exit 1
+	;;
+  esac
+done
+
+# Verify our last option didn't require an argument
+if test -n "$at_prev"; then :
+  as_fn_error "\`$at_prev' requires an argument."
+fi
+
+# Selected test groups.
+if test -z "$at_groups"; then
+  at_groups=$at_groups_all
+else
+  # Sort the tests, removing duplicates.
+  at_groups=`$as_echo "$at_groups" | tr ' ' "$as_nl" | sort -nu`
+fi
+
+# Help message.
+if $at_help_p; then
+  cat <<_ATEOF || at_write_fail=1
+Usage: $0 [OPTION]... [VARIABLE=VALUE]... [TESTS]
+
+Run all the tests, or the selected TESTS, given by numeric ranges, and
+save a detailed log file.  Upon failure, create debugging scripts.
+
+Do not change environment variables directly.  Instead, set them via
+command line arguments.  Set \`AUTOTEST_PATH' to select the executables
+to exercise.  Each relative directory is expanded as build and source
+directories relative to the top level of this distribution.
+E.g., from within the build directory /tmp/foo-1.0, invoking this:
+
+  $ $0 AUTOTEST_PATH=bin
+
+is equivalent to the following, assuming the source directory is /src/foo-1.0:
+
+  PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH $0
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Operation modes:
+  -h, --help     print the help message, then exit
+  -V, --version  print version number, then exit
+  -c, --clean    remove all the files this test suite might create and exit
+  -l, --list     describes all the tests, or the selected TESTS
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Execution tuning:
+  -C, --directory=DIR
+                 change to directory DIR before starting
+  -j, --jobs[=N]
+                 Allow N jobs at once; infinite jobs with no arg (default 1)
+  -k, --keywords=KEYWORDS
+                 select the tests matching all the comma-separated KEYWORDS
+                 multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD
+  -e, --errexit  abort as soon as a test fails; implies --debug
+  -v, --verbose  force more detailed output
+                 default for debugging scripts
+  -d, --debug    inhibit clean up and top-level logging
+                 default for debugging scripts
+  -x, --trace    enable tests shell tracing
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Report bugs to <opendap-tech at opendap.org>.
+_ATEOF
+  exit $at_write_fail
+fi
+
+# List of tests.
+if $at_list_p; then
+  cat <<_ATEOF || at_write_fail=1
+libdap 3.11.1 test suite: das-test test groups:
+
+ NUM: FILE-NAME:LINE     TEST-GROUP-NAME
+      KEYWORDS
+
+_ATEOF
+  # Passing at_groups is tricky.  We cannot use it to form a literal string
+  # or regexp because of the limitation of AIX awk.  And Solaris' awk
+  # doesn't grok more than 99 fields in a record, so we have to use `split'.
+  # at_groups needs to be space-separated for this script to work.
+  case $at_groups in
+    *"$as_nl"* )
+      at_groups=`$as_echo "$at_groups" | tr "$as_nl" ' '` ;;
+  esac
+  $as_echo "$at_groups$as_nl$at_help_all" |
+    awk 'BEGIN { FS = ";" }
+	 NR == 1 {
+	   for (n = split ($ 0, a, " "); n; n--)
+	     selected[a[n]] = 1
+	   next
+	 }
+	 NF > 0 {
+	   if (selected[$ 1]) {
+	     printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
+	     if ($ 4) {
+	       lmax = 79
+	       indent = "     "
+	       line = indent
+	       len = length (line)
+	       n = split ($ 4, a, " ")
+	       for (i = 1; i <= n; i++) {
+		 l = length (a[i]) + 1
+		 if (i > 1 && len + l > lmax) {
+		   print line
+		   line = indent " " a[i]
+		   len = length (line)
+		 } else {
+		   line = line " " a[i]
+		   len += l
+		 }
+	       }
+	       if (n)
+		 print line
+	     }
+	   }
+	 }' || at_write_fail=1
+  exit $at_write_fail
+fi
+if $at_version_p; then
+  $as_echo "$as_me (libdap 3.11.1)" &&
+  cat <<\_ATEOF || at_write_fail=1
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This test suite is free software; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+_ATEOF
+  exit $at_write_fail
+fi
+
+# Should we print banners?  at_groups is space-separated for entire test,
+# newline-separated if only a subset of the testsuite is run.
+case $at_groups in
+  *' '*' '* | *"$as_nl"*"$as_nl"* )
+      at_print_banners=: ;;
+  * ) at_print_banners=false ;;
+esac
+# Text for banner N, set to empty once printed.
+
+# Take any -C into account.
+if $at_change_dir ; then
+  if test x- = "x$at_dir" ; then
+    at_dir=./-
+  fi
+  test x != "x$at_dir" && cd "$at_dir" \
+    || as_fn_error "unable to change directory"
+  at_dir=`pwd`
+fi
+
+# Load the config files for any default variable assignments.
+for at_file in atconfig atlocal
+do
+  test -r $at_file || continue
+  . ./$at_file || as_fn_error "invalid content: $at_file"
+done
+
+# Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
+: ${at_top_build_prefix=$at_top_builddir}
+
+# Perform any assignments requested during argument parsing.
+eval "$at_debug_args"
+
+# atconfig delivers names relative to the directory the test suite is
+# in, but the groups themselves are run in testsuite-dir/group-dir.
+if test -n "$at_top_srcdir"; then
+  builddir=../..
+  for at_dir_var in srcdir top_srcdir top_build_prefix
+  do
+    eval at_val=\$at_$at_dir_var
+    case $at_val in
+      [\\/$]* | ?:[\\/]* ) at_prefix= ;;
+      *) at_prefix=../../ ;;
+    esac
+    eval "$at_dir_var=\$at_prefix\$at_val"
+  done
+fi
+
+## -------------------- ##
+## Directory structure. ##
+## -------------------- ##
+
+# This is the set of directories and files used by this script
+# (non-literals are capitalized):
+#
+# TESTSUITE         - the testsuite
+# TESTSUITE.log     - summarizes the complete testsuite run
+# TESTSUITE.dir/    - created during a run, remains after -d or failed test
+# + at-groups/      - during a run: status of all groups in run
+# | + NNN/          - during a run: meta-data about test group NNN
+# | | + check-line  - location (source file and line) of current AT_CHECK
+# | | + status      - exit status of current AT_CHECK
+# | | + stdout      - stdout of current AT_CHECK
+# | | + stder1      - stderr, including trace
+# | | + stderr      - stderr, with trace filtered out
+# | | + test-source - portion of testsuite that defines group
+# | | + times       - timestamps for computing duration
+# | | + pass        - created if group passed
+# | | + xpass       - created if group xpassed
+# | | + fail        - created if group failed
+# | | + xfail       - created if group xfailed
+# | | + skip        - created if group skipped
+# + at-stop         - during a run: end the run if this file exists
+# + at-source-lines - during a run: cache of TESTSUITE line numbers for extraction
+# + 0..NNN/         - created for each group NNN, remains after -d or failed test
+# | + TESTSUITE.log - summarizes the group results
+# | + ...           - files created during the group
+
+# The directory the whole suite works in.
+# Should be absolute to let the user `cd' at will.
+at_suite_dir=$at_dir/$as_me.dir
+# The file containing the suite.
+at_suite_log=$at_dir/$as_me.log
+# The directory containing helper files per test group.
+at_helper_dir=$at_suite_dir/at-groups
+# Stop file: if it exists, do not start new jobs.
+at_stop_file=$at_suite_dir/at-stop
+# The fifo used for the job dispatcher.
+at_job_fifo=$at_suite_dir/at-job-fifo
+
+if $at_clean; then
+  test -d "$at_suite_dir" &&
+    find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+  rm -f -r "$at_suite_dir" "$at_suite_log"
+  exit $?
+fi
+
+# Don't take risks: use only absolute directories in PATH.
+#
+# For stand-alone test suites (ie. atconfig was not found),
+# AUTOTEST_PATH is relative to `.'.
+#
+# For embedded test suites, AUTOTEST_PATH is relative to the top level
+# of the package.  Then expand it into build/src parts, since users
+# may create executables in both places.
+AUTOTEST_PATH=`$as_echo "$AUTOTEST_PATH" | sed "s|:|$PATH_SEPARATOR|g"`
+at_path=
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $AUTOTEST_PATH $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -n "$at_path" && as_fn_append at_path $PATH_SEPARATOR
+case $as_dir in
+  [\\/]* | ?:[\\/]* )
+    as_fn_append at_path "$as_dir"
+    ;;
+  * )
+    if test -z "$at_top_build_prefix"; then
+      # Stand-alone test suite.
+      as_fn_append at_path "$as_dir"
+    else
+      # Embedded test suite.
+      as_fn_append at_path "$at_top_build_prefix$as_dir$PATH_SEPARATOR"
+      as_fn_append at_path "$at_top_srcdir/$as_dir"
+    fi
+    ;;
+esac
+  done
+IFS=$as_save_IFS
+
+
+# Now build and simplify PATH.
+#
+# There might be directories that don't exist, but don't redirect
+# builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
+at_new_path=
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $at_path
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -d "$as_dir" || continue
+case $as_dir in
+  [\\/]* | ?:[\\/]* ) ;;
+  * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;;
+esac
+case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in
+  *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;;
+  $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;;
+  *) as_fn_append at_new_path "$PATH_SEPARATOR$as_dir" ;;
+esac
+  done
+IFS=$as_save_IFS
+
+PATH=$at_new_path
+export PATH
+
+# Setting up the FDs.
+
+
+# 5 is the log file.  Not to be overwritten if `-d'.
+if $at_debug_p; then
+  at_suite_log=/dev/null
+else
+  : >"$at_suite_log"
+fi
+exec 5>>"$at_suite_log"
+
+# Banners and logs.
+cat <<\_ASBOX
+## ----------------------------------- ##
+## libdap 3.11.1 test suite: das-test. ##
+## ----------------------------------- ##
+_ASBOX
+{
+  cat <<\_ASBOX
+## ----------------------------------- ##
+## libdap 3.11.1 test suite: das-test. ##
+## ----------------------------------- ##
+_ASBOX
+  echo
+
+  $as_echo "$as_me: command line was:"
+  $as_echo "  \$ $0 $at_cli_args"
+  echo
+
+  # Try to find a few ChangeLogs in case it might help determining the
+  # exact version.  Use the relative dir: if the top dir is a symlink,
+  # find will not follow it (and options to follow the links are not
+  # portable), which would result in no output here.  Prune directories
+  # matching the package tarname, since they tend to be leftovers from
+  # `make dist' or `make distcheck' and contain redundant or stale logs.
+  if test -n "$at_top_srcdir"; then
+    cat <<\_ASBOX
+## ----------- ##
+## ChangeLogs. ##
+## ----------- ##
+_ASBOX
+    echo
+    for at_file in `find "$at_top_srcdir" -name "libdap-*" -prune -o -name ChangeLog -print`
+    do
+      $as_echo "$as_me: $at_file:"
+      sed 's/^/| /;10q' $at_file
+      echo
+    done
+
+  fi
+
+  {
+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`
+/usr/bin/hostinfo      = `(/usr/bin/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=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+}
+  echo
+
+  # Contents of the config files.
+  for at_file in atconfig atlocal
+  do
+    test -r $at_file || continue
+    $as_echo "$as_me: $at_file:"
+    sed 's/^/| /' $at_file
+    echo
+  done
+} >&5
+
+
+## ------------------------- ##
+## Autotest shell functions. ##
+## ------------------------- ##
+
+# at_fn_banner NUMBER
+# -------------------
+# Output banner NUMBER, provided the testsuite is running multiple groups and
+# this particular banner has not yet been printed.
+at_fn_banner ()
+{
+  $at_print_banners || return 0
+  eval at_banner_text=\$at_banner_text_$1
+  test "x$at_banner_text" = x && return 0
+  eval at_banner_text_$1=
+  $as_echo "$as_nl$at_banner_text$as_nl"
+} # at_fn_banner
+
+# at_fn_check_prepare_notrace REASON LINE
+# ---------------------------------------
+# Perform AT_CHECK preparations for the command at LINE for an untraceable
+# command; REASON is the reason for disabling tracing.
+at_fn_check_prepare_notrace ()
+{
+  $at_trace_echo "Not enabling shell tracing (command contains $1)"
+  $as_echo "$2" >"$at_check_line_file"
+  at_check_trace=: at_check_filter=:
+  : >"$at_stdout"; : >"$at_stderr"
+}
+
+# at_fn_check_prepare_trace LINE
+# ------------------------------
+# Perform AT_CHECK preparations for the command at LINE for a traceable
+# command.
+at_fn_check_prepare_trace ()
+{
+  $as_echo "$1" >"$at_check_line_file"
+  at_check_trace=$at_traceon at_check_filter=$at_check_filter_trace
+  : >"$at_stdout"; : >"$at_stderr"
+}
+
+# at_fn_check_prepare_dynamic COMMAND LINE
+# ----------------------------------------
+# Decide if COMMAND at LINE is traceable at runtime, and call the appropriate
+# preparation function.
+at_fn_check_prepare_dynamic ()
+{
+  case $1 in
+    *$as_nl*)
+      at_fn_check_prepare_notrace 'an embedded newline' "$2" ;;
+    *)
+      at_fn_check_prepare_trace "$2" ;;
+  esac
+}
+
+# at_fn_filter_trace
+# ------------------
+# Remove the lines in the file "$at_stderr" generated by "set -x" and print
+# them to stderr.
+at_fn_filter_trace ()
+{
+  mv "$at_stderr" "$at_stder1"
+  grep '^ *+' "$at_stder1" >&2
+  grep -v '^ *+' "$at_stder1" >"$at_stderr"
+}
+
+# at_fn_log_failure FILE-LIST
+# ---------------------------
+# Copy the files in the list on stdout with a "> " prefix, and exit the shell
+# with a failure exit code.
+at_fn_log_failure ()
+{
+  for file
+    do $as_echo "$file:"; sed 's/^/> /' "$file"; done
+  echo 1 > "$at_status_file"
+  exit 1
+}
+
+# at_fn_check_skip EXIT-CODE LINE
+# -------------------------------
+# Check whether EXIT-CODE is a special exit code (77 or 99), and if so exit
+# the test group subshell with that same exit code. Use LINE in any report
+# about test failure.
+at_fn_check_skip ()
+{
+  case $1 in
+    99) echo 99 > "$at_status_file"; at_failed=:
+	$as_echo "$2: hard failure"; exit 99;;
+    77) echo 77 > "$at_status_file"; exit 77;;
+  esac
+}
+
+# at_fn_check_status EXPECTED EXIT-CODE LINE
+# ------------------------------------------
+# Check whether EXIT-CODE is the EXPECTED exit code, and if so do nothing.
+# Otherwise, if it is 77 or 99, exit the test group subshell with that same
+# exit code; if it is anything else print an error message referring to LINE,
+# and fail the test.
+at_fn_check_status ()
+{
+  case $2 in
+    $1 ) ;;
+    77) echo 77 > "$at_status_file"; exit 77;;
+    99) echo 99 > "$at_status_file"; at_failed=:
+	$as_echo "$3: hard failure"; exit 99;;
+    *) $as_echo "$3: exit code was $2, expected $1"
+      at_failed=:;;
+  esac
+}
+
+# at_fn_diff_devnull FILE
+# -----------------------
+# Emit a diff between /dev/null and FILE. Uses "test -s" to avoid useless diff
+# invocations.
+at_fn_diff_devnull ()
+{
+  test -s "$1" || return 0
+  $at_diff "$at_devnull" "$1"
+}
+
+# at_fn_test NUMBER
+# -----------------
+# Parse out test NUMBER from the tail of this file.
+at_fn_test ()
+{
+  eval at_sed=\$at_sed$1
+  sed "$at_sed" "$at_myself" > "$at_test_source"
+}
+
+# at_fn_create_debugging_script
+# -----------------------------
+# Create the debugging script $at_group_dir/run which will reproduce the
+# current test group.
+at_fn_create_debugging_script ()
+{
+  {
+    echo "#! /bin/sh" &&
+    echo 'test "${ZSH_VERSION+set}" = set && alias -g '\''${1+"$@"}'\''='\''"$@"'\''' &&
+    $as_echo "cd '$at_dir'" &&
+    $as_echo "exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d $at_debug_args $at_group \${1+\"\$@\"}" &&
+    echo 'exit 1'
+  } >"$at_group_dir/run" &&
+  chmod +x "$at_group_dir/run"
+}
+
+## -------------------------------- ##
+## End of autotest shell functions. ##
+## -------------------------------- ##
+{
+  cat <<\_ASBOX
+## ---------------- ##
+## Tested programs. ##
+## ---------------- ##
+_ASBOX
+  echo
+} >&5
+
+# Report what programs are being tested.
+for at_program in : $at_tested
+do
+  test "$at_program" = : && continue
+  case $at_program in
+    [\\/]* | ?:[\\/]* ) $at_program_=$at_program ;;
+    * )
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -f "$as_dir/$at_program" && break
+  done
+IFS=$as_save_IFS
+
+    at_program_=$as_dir/$at_program ;;
+  esac
+  if test -f "$at_program_"; then
+    {
+      $as_echo "$at_srcdir/DASTest.at:7: $at_program_ --version"
+      "$at_program_" --version </dev/null
+      echo
+    } >&5 2>&1
+  else
+    as_fn_error "cannot find $at_program" "$LINENO" 5
+  fi
+done
+
+{
+  cat <<\_ASBOX
+## ------------------ ##
+## Running the tests. ##
+## ------------------ ##
+_ASBOX
+} >&5
+
+at_start_date=`date`
+at_start_time=`date +%s 2>/dev/null`
+$as_echo "$as_me: starting at: $at_start_date" >&5
+
+# Create the master directory if it doesn't already exist.
+as_dir="$at_suite_dir"; as_fn_mkdir_p ||
+  as_fn_error "cannot create \`$at_suite_dir'" "$LINENO" 5
+
+# Can we diff with `/dev/null'?  DU 5.0 refuses.
+if diff /dev/null /dev/null >/dev/null 2>&1; then
+  at_devnull=/dev/null
+else
+  at_devnull=$at_suite_dir/devnull
+  >"$at_devnull"
+fi
+
+# Use `diff -u' when possible.
+if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
+then
+  at_diff='diff -u'
+else
+  at_diff=diff
+fi
+
+# Get the last needed group.
+for at_group in : $at_groups; do :; done
+
+# Extract the start and end lines of each test group at the tail
+# of this file
+awk '
+BEGIN { FS="" }
+/^#AT_START_/ {
+  start = NR
+}
+/^#AT_STOP_/ {
+  test = substr ($ 0, 10)
+  print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
+  if (test == "'"$at_group"'") exit
+}' "$at_myself" > "$at_suite_dir/at-source-lines" &&
+. "$at_suite_dir/at-source-lines" ||
+  as_fn_error "cannot create test line number cache" "$LINENO" 5
+rm -f "$at_suite_dir/at-source-lines"
+
+# Set number of jobs for `-j'; avoid more jobs than test groups.
+set X $at_groups; shift; at_max_jobs=$#
+if test $at_max_jobs -eq 0; then
+  at_jobs=1
+fi
+if test $at_jobs -ne 1 &&
+   { test $at_jobs -eq 0 || test $at_jobs -gt $at_max_jobs; }; then
+  at_jobs=$at_max_jobs
+fi
+
+# If parallel mode, don't output banners, don't split summary lines.
+if test $at_jobs -ne 1; then
+  at_print_banners=false
+  at_quiet=:
+fi
+
+# Set up helper dirs.
+rm -rf "$at_helper_dir" &&
+mkdir "$at_helper_dir" &&
+cd "$at_helper_dir" &&
+{ test -z "$at_groups" || mkdir $at_groups; } ||
+as_fn_error "testsuite directory setup failed" "$LINENO" 5
+
+# Functions for running a test group.  We leave the actual
+# test group execution outside of a shell function in order
+# to avoid hitting zsh 4.x exit status bugs.
+
+# at_fn_group_prepare
+# -------------------
+# Prepare running a test group.
+at_fn_group_prepare ()
+{
+  # The directory for additional per-group helper files.
+  at_job_dir=$at_helper_dir/$at_group
+  # The file containing the location of the last AT_CHECK.
+  at_check_line_file=$at_job_dir/check-line
+  # The file containing the exit status of the last command.
+  at_status_file=$at_job_dir/status
+  # The files containing the output of the tested commands.
+  at_stdout=$at_job_dir/stdout
+  at_stder1=$at_job_dir/stder1
+  at_stderr=$at_job_dir/stderr
+  # The file containing the code for a test group.
+  at_test_source=$at_job_dir/test-source
+  # The file containing dates.
+  at_times_file=$at_job_dir/times
+
+  # Be sure to come back to the top test directory.
+  cd "$at_suite_dir"
+
+  # Clearly separate the test groups when verbose.
+  $at_first || $at_verbose echo
+
+  at_group_normalized=$at_group
+
+  eval 'while :; do
+    case $at_group_normalized in #(
+    '"$at_format"'*) break;;
+    esac
+    at_group_normalized=0$at_group_normalized
+  done'
+
+
+  # Create a fresh directory for the next test group, and enter.
+  # If one already exists, the user may have invoked ./run from
+  # within that directory; we remove the contents, but not the
+  # directory itself, so that we aren't pulling the rug out from
+  # under the shell's notion of the current directory.
+  at_group_dir=$at_suite_dir/$at_group_normalized
+  at_group_log=$at_group_dir/$as_me.log
+  if test -d "$at_group_dir"; then
+  find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx {} \;
+  rm -fr "$at_group_dir"/* "$at_group_dir"/.[!.] "$at_group_dir"/.??*
+fi ||
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: test directory for $at_group_normalized could not be cleaned." >&5
+$as_echo "$as_me: WARNING: test directory for $at_group_normalized could not be cleaned." >&2;}
+  # Be tolerant if the above `rm' was not able to remove the directory.
+  as_dir="$at_group_dir"; as_fn_mkdir_p
+
+  echo 0 > "$at_status_file"
+
+  # In verbose mode, append to the log file *and* show on
+  # the standard output; in quiet mode only write to the log.
+  if test -z "$at_verbose"; then
+    at_tee_pipe='tee -a "$at_group_log"'
+  else
+    at_tee_pipe='cat >> "$at_group_log"'
+  fi
+}
+
+# at_fn_group_postprocess
+# -----------------------
+# Perform cleanup after running a test group.
+at_fn_group_postprocess ()
+{
+  # Be sure to come back to the suite directory, in particular
+  # since below we might `rm' the group directory we are in currently.
+  cd "$at_suite_dir"
+
+  if test ! -f "$at_check_line_file"; then
+    sed "s/^ */$as_me: WARNING: /" <<_ATEOF
+      A failure happened in a test group before any test could be
+      run. This means that test suite is improperly designed.  Please
+      report this failure to <opendap-tech at opendap.org>.
+_ATEOF
+    $as_echo "$at_setup_line" >"$at_check_line_file"
+    at_status=99
+  fi
+  $at_verbose $as_echo_n "$at_group. $at_setup_line: "
+  $as_echo_n "$at_group. $at_setup_line: " >> "$at_group_log"
+  case $at_xfail:$at_status in
+    *:99)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	;;
+    yes:0)
+	at_msg="UNEXPECTED PASS"
+	at_res=xpass
+	at_errexit=$at_errexit_p
+	;;
+    no:0)
+	at_msg="ok"
+	at_res=pass
+	at_errexit=false
+	;;
+    *:77)
+	at_msg='skipped ('`cat "$at_check_line_file"`')'
+	at_res=skip
+	at_errexit=false
+	;;
+    yes:*)
+	at_msg='expected failure ('`cat "$at_check_line_file"`')'
+	at_res=xfail
+	at_errexit=false
+	;;
+    no:*)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	;;
+  esac
+  echo "$at_res" > "$at_job_dir/$at_res"
+  # In parallel mode, output the summary line only afterwards.
+  if test $at_jobs -ne 1 && test -n "$at_verbose"; then
+    $as_echo "$at_desc_line $at_msg"
+  else
+    # Make sure there is a separator even with long titles.
+    $as_echo " $at_msg"
+  fi
+  at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
+  case $at_status in
+    0|77)
+      # $at_times_file is only available if the group succeeded.
+      # We're not including the group log, so the success message
+      # is written in the global log separately.  But we also
+      # write to the group log in case they're using -d.
+      if test -f "$at_times_file"; then
+	at_log_msg="$at_log_msg     ("`sed 1d "$at_times_file"`')'
+	rm -f "$at_times_file"
+      fi
+      $as_echo "$at_log_msg" >> "$at_group_log"
+      $as_echo "$at_log_msg" >&5
+
+      # Cleanup the group directory, unless the user wants the files.
+      if $at_debug_p; then
+	at_fn_create_debugging_script
+      else
+	if test -d "$at_group_dir"; then
+	  find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+	  rm -fr "$at_group_dir"
+	fi
+	rm -f "$at_test_source"
+      fi
+      ;;
+    *)
+      # Upon failure, include the log into the testsuite's global
+      # log.  The failure message is written in the group log.  It
+      # is later included in the global log.
+      $as_echo "$at_log_msg" >> "$at_group_log"
+
+      # Upon failure, keep the group directory for autopsy, and create
+      # the debugging script.  With -e, do not start any further tests.
+      at_fn_create_debugging_script
+      if $at_errexit; then
+	echo stop > "$at_stop_file"
+      fi
+      ;;
+  esac
+}
+
+
+## ------------ ##
+## Driver loop. ##
+## ------------ ##
+
+
+if (set -m && set +m && set +b) >/dev/null 2>&1; then
+  set +b
+  at_job_control_on='set -m' at_job_control_off='set +m' at_job_group=-
+else
+  at_job_control_on=: at_job_control_off=: at_job_group=
+fi
+
+for at_signal in 1 2 15; do
+  trap 'set +x; set +e
+	$at_job_control_off
+	at_signal='"$at_signal"'
+	echo stop > "$at_stop_file"
+	trap "" $at_signal
+	at_pgids=
+	for at_pgid in `jobs -p 2>/dev/null`; do
+	  at_pgids="$at_pgids $at_job_group$at_pgid"
+	done
+	test -z "$at_pgids" || kill -$at_signal $at_pgids 2>/dev/null
+	wait
+	if test "$at_jobs" -eq 1 || test -z "$at_verbose"; then
+	  echo >&2
+	fi
+	at_signame=`kill -l $at_signal 2>&1 || echo $at_signal`
+	set x $at_signame
+	test 1 -gt 2 && at_signame=$at_signal
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: caught signal $at_signame, bailing out" >&5
+$as_echo "$as_me: WARNING: caught signal $at_signame, bailing out" >&2;}
+	as_fn_arith 128 + $at_signal && exit_status=$as_val
+	as_fn_exit $exit_status' $at_signal
+done
+
+rm -f "$at_stop_file"
+at_first=:
+
+if test $at_jobs -ne 1 &&
+     rm -f "$at_job_fifo" &&
+     test -n "$at_job_group" &&
+     ( mkfifo "$at_job_fifo" && trap 'exit 1' PIPE STOP TSTP ) 2>/dev/null
+then
+  # FIFO job dispatcher.
+
+  trap 'at_pids=
+	for at_pid in `jobs -p`; do
+	  at_pids="$at_pids $at_job_group$at_pid"
+	done
+	if test -n "$at_pids"; then
+	  at_sig=TSTP
+	  test "${TMOUT+set}" = set && at_sig=STOP
+	  kill -$at_sig $at_pids 2>/dev/null
+	fi
+	kill -STOP $$
+	test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
+
+  echo
+  # Turn jobs into a list of numbers, starting from 1.
+  at_joblist=`$as_echo " $at_groups_all " | \
+    sed 's/\( '$at_jobs'\) .*/\1/'`
+
+  set X $at_joblist
+  shift
+  for at_group in $at_groups; do
+    $at_job_control_on 2>/dev/null
+    (
+      # Start one test group.
+      $at_job_control_off
+      exec 6>"$at_job_fifo"
+      trap 'set +x; set +e
+	    trap "" PIPE
+	    echo stop > "$at_stop_file"
+	    echo token >&6
+	    as_fn_exit 141' PIPE
+      at_fn_group_prepare
+      if cd "$at_group_dir" &&
+	 at_fn_test $at_group &&
+	 . "$at_test_source" # AT_JOB_FIFO_FD>&-
+      then :; else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+	at_failed=:
+      fi
+      at_fn_group_postprocess
+      echo token >&6
+    ) &
+    $at_job_control_off
+    if $at_first; then
+      at_first=false
+      exec 6<"$at_job_fifo"
+    fi
+    shift # Consume one token.
+    if test $# -gt 0; then :; else
+      read at_token <&6 || break
+      set x $*
+    fi
+    test -f "$at_stop_file" && break
+  done
+  # Read back the remaining ($at_jobs - 1) tokens.
+  set X $at_joblist
+  shift
+  if test $# -gt 0; then
+    shift
+    for at_job
+    do
+      read at_token
+    done <&6
+  fi
+  exec 6<&-
+  wait
+else
+  # Run serially, avoid forks and other potential surprises.
+  for at_group in $at_groups; do
+    at_fn_group_prepare
+    if cd "$at_group_dir" &&
+       at_fn_test $at_group &&
+       . "$at_test_source"; then :; else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+      at_failed=:
+    fi
+    at_fn_group_postprocess
+    test -f "$at_stop_file" && break
+    at_first=false
+  done
+fi
+
+# Wrap up the test suite with summary statistics.
+cd "$at_helper_dir"
+
+# Use ?..???? when the list must remain sorted, the faster * otherwise.
+at_pass_list=`for f in */pass; do echo $f; done | sed '/\*/d; s,/pass,,'`
+at_skip_list=`for f in */skip; do echo $f; done | sed '/\*/d; s,/skip,,'`
+at_xfail_list=`for f in */xfail; do echo $f; done | sed '/\*/d; s,/xfail,,'`
+at_xpass_list=`for f in ?/xpass ??/xpass ???/xpass ????/xpass; do
+		 echo $f; done | sed '/?/d; s,/xpass,,'`
+at_fail_list=`for f in ?/fail ??/fail ???/fail ????/fail; do
+		echo $f; done | sed '/?/d; s,/fail,,'`
+
+set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
+shift; at_group_count=$#
+set X $at_xpass_list; shift; at_xpass_count=$#; at_xpass_list=$*
+set X $at_xfail_list; shift; at_xfail_count=$#
+set X $at_fail_list; shift; at_fail_count=$#; at_fail_list=$*
+set X $at_skip_list; shift; at_skip_count=$#
+
+as_fn_arith $at_group_count - $at_skip_count && at_run_count=$as_val
+as_fn_arith $at_xpass_count + $at_fail_count && at_unexpected_count=$as_val
+as_fn_arith $at_xfail_count + $at_fail_count && at_total_fail_count=$as_val
+
+# Back to the top directory.
+cd "$at_dir"
+rm -rf "$at_helper_dir"
+
+# Compute the duration of the suite.
+at_stop_date=`date`
+at_stop_time=`date +%s 2>/dev/null`
+$as_echo "$as_me: ending at: $at_stop_date" >&5
+case $at_start_time,$at_stop_time in
+  [0-9]*,[0-9]*)
+    as_fn_arith $at_stop_time - $at_start_time && at_duration_s=$as_val
+    as_fn_arith $at_duration_s / 60 && at_duration_m=$as_val
+    as_fn_arith $at_duration_m / 60 && at_duration_h=$as_val
+    as_fn_arith $at_duration_s % 60 && at_duration_s=$as_val
+    as_fn_arith $at_duration_m % 60 && at_duration_m=$as_val
+    at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
+    $as_echo "$as_me: test suite duration: $at_duration" >&5
+    ;;
+esac
+
+echo
+cat <<\_ASBOX
+## ------------- ##
+## Test results. ##
+## ------------- ##
+_ASBOX
+echo
+{
+  echo
+  cat <<\_ASBOX
+## ------------- ##
+## Test results. ##
+## ------------- ##
+_ASBOX
+  echo
+} >&5
+
+if test $at_run_count = 1; then
+  at_result="1 test"
+  at_were=was
+else
+  at_result="$at_run_count tests"
+  at_were=were
+fi
+if $at_errexit_p && test $at_unexpected_count != 0; then
+  if test $at_xpass_count = 1; then
+    at_result="$at_result $at_were run, one passed"
+  else
+    at_result="$at_result $at_were run, one failed"
+  fi
+  at_result="$at_result unexpectedly and inhibited subsequent tests."
+else
+  # Don't you just love exponential explosion of the number of cases?
+  case $at_xpass_count:$at_fail_count:$at_xfail_count in
+    # So far, so good.
+    0:0:0) at_result="$at_result $at_were successful." ;;
+    0:0:*) at_result="$at_result behaved as expected." ;;
+
+    # Some unexpected failures
+    0:*:0) at_result="$at_result $at_were run,
+$at_fail_count failed unexpectedly." ;;
+
+    # Some failures, both expected and unexpected
+    0:*:1) at_result="$at_result $at_were run,
+$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
+    0:*:*) at_result="$at_result $at_were run,
+$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
+
+    # No unexpected failures, but some xpasses
+    *:0:*) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly." ;;
+
+    # No expected failures, but failures and xpasses
+    *:1:0) at_result="$at_result $at_were run,
+$at_unexpected_count did not behave as expected ($at_fail_count unexpected failure)." ;;
+    *:*:0) at_result="$at_result $at_were run,
+$at_unexpected_count did not behave as expected ($at_fail_count unexpected failures)." ;;
+
+    # All of them.
+    *:*:1) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly,
+$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
+    *:*:*) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly,
+$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
+  esac
+
+  if test $at_skip_count = 0 && test $at_run_count -gt 1; then
+    at_result="All $at_result"
+  fi
+fi
+
+# Now put skips in the mix.
+case $at_skip_count in
+  0) ;;
+  1) at_result="$at_result
+1 test was skipped." ;;
+  *) at_result="$at_result
+$at_skip_count tests were skipped." ;;
+esac
+
+if test $at_unexpected_count = 0; then
+  echo "$at_result"
+  echo "$at_result" >&5
+else
+  echo "ERROR: $at_result" >&2
+  echo "ERROR: $at_result" >&5
+  {
+    echo
+    cat <<\_ASBOX
+## ------------------------ ##
+## Summary of the failures. ##
+## ------------------------ ##
+_ASBOX
+
+    # Summary of failed and skipped tests.
+    if test $at_fail_count != 0; then
+      echo "Failed tests:"
+      $SHELL "$at_myself" $at_fail_list --list
+      echo
+    fi
+    if test $at_skip_count != 0; then
+      echo "Skipped tests:"
+      $SHELL "$at_myself" $at_skip_list --list
+      echo
+    fi
+    if test $at_xpass_count != 0; then
+      echo "Unexpected passes:"
+      $SHELL "$at_myself" $at_xpass_list --list
+      echo
+    fi
+    if test $at_fail_count != 0; then
+      cat <<\_ASBOX
+## ---------------------- ##
+## Detailed failed tests. ##
+## ---------------------- ##
+_ASBOX
+      echo
+      for at_group in $at_fail_list
+      do
+	at_group_normalized=$at_group
+
+  eval 'while :; do
+    case $at_group_normalized in #(
+    '"$at_format"'*) break;;
+    esac
+    at_group_normalized=0$at_group_normalized
+  done'
+
+	cat "$at_suite_dir/$at_group_normalized/$as_me.log"
+	echo
+      done
+      echo
+    fi
+    if test -n "$at_top_srcdir"; then
+      sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## ${at_top_build_prefix}config.log ##
+_ASBOX
+      sed 's/^/| /' ${at_top_build_prefix}config.log
+      echo
+    fi
+  } >&5
+
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## $as_me.log was created. ##
+_ASBOX
+
+  echo
+  if $at_debug_p; then
+    at_msg='per-test log files'
+  else
+    at_msg="\`${at_testdir+${at_testdir}/}$as_me.log'"
+  fi
+  $as_echo "Please send $at_msg and all information you think might help:
+
+   To: <opendap-tech at opendap.org>
+   Subject: [libdap 3.11.1] $as_me: $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}$at_xpass_list${at_xpass_list:+ passed unexpectedly}
+
+You may investigate any problem if you feel able to do so, in which
+case the test suite provides a good starting point.  Its output may
+be found below \`${at_testdir+${at_testdir}/}$as_me.dir'.
+"
+  exit 1
+fi
+
+exit 0
+
+## ------------- ##
+## Actual tests. ##
+## ------------- ##
+#AT_START_1
+# 1. DASTest.at:31: DAS $abs_srcdir/das-testsuite/bad_value_test.1.das
+at_setup_line='DASTest.at:31'
+at_desc="DAS \$abs_srcdir/das-testsuite/bad_value_test.1.das"
+at_desc_line="  1: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "1. DASTest.at:31: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/bad_value_test.1.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:31: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/bad_value_test.1.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/bad_value_test.1.das || true" "DASTest.at:31"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/bad_value_test.1.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:31"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:31: diff -b -B \$abs_srcdir/das-testsuite/bad_value_test.1.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/bad_value_test.1.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/bad_value_test.1.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/bad_value_test.1.das.base stderr" "DASTest.at:31"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/bad_value_test.1.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/bad_value_test.1.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:31"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_1
+#AT_START_2
+# 2. DASTest.at:32: DAS $abs_srcdir/das-testsuite/das.das
+at_setup_line='DASTest.at:32'
+at_desc="DAS \$abs_srcdir/das-testsuite/das.das"
+at_desc_line="  2: $at_desc          "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "2. DASTest.at:32: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/das.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:32: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/das.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/das.das || true" "DASTest.at:32"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/das.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:32"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:32: diff -b -B \$abs_srcdir/das-testsuite/das.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/das.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/das.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/das.das.base stderr" "DASTest.at:32"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/das.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/das.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:32"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_2
+#AT_START_3
+# 3. DASTest.at:33: DAS $abs_srcdir/das-testsuite/special.test.das
+at_setup_line='DASTest.at:33'
+at_desc="DAS \$abs_srcdir/das-testsuite/special.test.das"
+at_desc_line="  3: $at_desc "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "3. DASTest.at:33: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/special.test.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:33: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/special.test.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/special.test.das || true" "DASTest.at:33"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/special.test.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:33"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:33: diff -b -B \$abs_srcdir/das-testsuite/special.test.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/special.test.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/special.test.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/special.test.das.base stderr" "DASTest.at:33"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/special.test.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/special.test.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:33"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_3
+#AT_START_4
+# 4. DASTest.at:34: DAS $abs_srcdir/das-testsuite/special.test.hdf.das
+at_setup_line='DASTest.at:34'
+at_desc="DAS \$abs_srcdir/das-testsuite/special.test.hdf.das"
+at_desc_line="  4: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "4. DASTest.at:34: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/special.test.hdf.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:34: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/special.test.hdf.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/special.test.hdf.das || true" "DASTest.at:34"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/special.test.hdf.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:34"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:34: diff -b -B \$abs_srcdir/das-testsuite/special.test.hdf.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/special.test.hdf.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/special.test.hdf.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/special.test.hdf.das.base stderr" "DASTest.at:34"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/special.test.hdf.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/special.test.hdf.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:34"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_4
+#AT_START_5
+# 5. DASTest.at:35: DAS $abs_srcdir/das-testsuite/test.1.das
+at_setup_line='DASTest.at:35'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.1.das"
+at_desc_line="  5: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "5. DASTest.at:35: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.1.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:35: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.1.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.1.das || true" "DASTest.at:35"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.1.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:35"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:35: diff -b -B \$abs_srcdir/das-testsuite/test.1.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.1.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.1.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.1.das.base stderr" "DASTest.at:35"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.1.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.1.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:35"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_5
+#AT_START_6
+# 6. DASTest.at:36: DAS $abs_srcdir/das-testsuite/test.11.das
+at_setup_line='DASTest.at:36'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.11.das"
+at_desc_line="  6: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "6. DASTest.at:36: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.11.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:36: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.11.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.11.das || true" "DASTest.at:36"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.11.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:36"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:36: diff -b -B \$abs_srcdir/das-testsuite/test.11.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.11.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.11.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.11.das.base stderr" "DASTest.at:36"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.11.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.11.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:36"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_6
+#AT_START_7
+# 7. DASTest.at:37: DAS $abs_srcdir/das-testsuite/test.12.das
+at_setup_line='DASTest.at:37'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.12.das"
+at_desc_line="  7: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "7. DASTest.at:37: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.12.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:37: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.12.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.12.das || true" "DASTest.at:37"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.12.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:37"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:37: diff -b -B \$abs_srcdir/das-testsuite/test.12.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.12.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.12.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.12.das.base stderr" "DASTest.at:37"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.12.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.12.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:37"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_7
+#AT_START_8
+# 8. DASTest.at:38: DAS $abs_srcdir/das-testsuite/test.13.das
+at_setup_line='DASTest.at:38'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.13.das"
+at_desc_line="  8: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "8. DASTest.at:38: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.13.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:38: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.13.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.13.das || true" "DASTest.at:38"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.13.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:38"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:38: diff -b -B \$abs_srcdir/das-testsuite/test.13.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.13.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.13.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.13.das.base stderr" "DASTest.at:38"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.13.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.13.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:38"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_8
+#AT_START_9
+# 9. DASTest.at:39: DAS $abs_srcdir/das-testsuite/test.14.das
+at_setup_line='DASTest.at:39'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.14.das"
+at_desc_line="  9: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "9. DASTest.at:39: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.14.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:39: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.14.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.14.das || true" "DASTest.at:39"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.14.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:39"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:39: diff -b -B \$abs_srcdir/das-testsuite/test.14.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.14.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.14.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.14.das.base stderr" "DASTest.at:39"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.14.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.14.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:39"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_9
+#AT_START_10
+# 10. DASTest.at:40: DAS $abs_srcdir/das-testsuite/test.15.das
+at_setup_line='DASTest.at:40'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.15.das"
+at_desc_line=" 10: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "10. DASTest.at:40: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.15.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:40: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.15.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.15.das || true" "DASTest.at:40"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.15.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:40"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:40: diff -b -B \$abs_srcdir/das-testsuite/test.15.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.15.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.15.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.15.das.base stderr" "DASTest.at:40"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.15.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.15.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:40"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_10
+#AT_START_11
+# 11. DASTest.at:41: DAS $abs_srcdir/das-testsuite/test.16.das
+at_setup_line='DASTest.at:41'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.16.das"
+at_desc_line=" 11: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "11. DASTest.at:41: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.16.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:41: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.16.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.16.das || true" "DASTest.at:41"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.16.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:41"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:41: diff -b -B \$abs_srcdir/das-testsuite/test.16.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.16.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.16.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.16.das.base stderr" "DASTest.at:41"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.16.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.16.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:41"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_11
+#AT_START_12
+# 12. DASTest.at:42: DAS $abs_srcdir/das-testsuite/test.17.das
+at_setup_line='DASTest.at:42'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.17.das"
+at_desc_line=" 12: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "12. DASTest.at:42: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.17.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:42: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.17.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.17.das || true" "DASTest.at:42"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.17.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:42"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:42: diff -b -B \$abs_srcdir/das-testsuite/test.17.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.17.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.17.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.17.das.base stderr" "DASTest.at:42"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.17.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.17.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:42"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_12
+#AT_START_13
+# 13. DASTest.at:43: DAS $abs_srcdir/das-testsuite/test.18.das
+at_setup_line='DASTest.at:43'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.18.das"
+at_desc_line=" 13: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "13. DASTest.at:43: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.18.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:43: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.18.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.18.das || true" "DASTest.at:43"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.18.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:43"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:43: diff -b -B \$abs_srcdir/das-testsuite/test.18.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.18.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.18.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.18.das.base stderr" "DASTest.at:43"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.18.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.18.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:43"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_13
+#AT_START_14
+# 14. DASTest.at:44: DAS $abs_srcdir/das-testsuite/test.19.das
+at_setup_line='DASTest.at:44'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.19.das"
+at_desc_line=" 14: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "14. DASTest.at:44: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.19.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:44: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.19.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.19.das || true" "DASTest.at:44"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.19.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:44"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:44: diff -b -B \$abs_srcdir/das-testsuite/test.19.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.19.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.19.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.19.das.base stderr" "DASTest.at:44"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.19.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.19.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:44"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_14
+#AT_START_15
+# 15. DASTest.at:45: DAS $abs_srcdir/das-testsuite/test.1a.das
+at_setup_line='DASTest.at:45'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.1a.das"
+at_desc_line=" 15: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "15. DASTest.at:45: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.1a.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:45: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.1a.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.1a.das || true" "DASTest.at:45"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.1a.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:45: diff -b -B \$abs_srcdir/das-testsuite/test.1a.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.1a.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.1a.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.1a.das.base stderr" "DASTest.at:45"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.1a.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.1a.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_15
+#AT_START_16
+# 16. DASTest.at:46: DAS $abs_srcdir/das-testsuite/test.2.das
+at_setup_line='DASTest.at:46'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.2.das"
+at_desc_line=" 16: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "16. DASTest.at:46: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.2.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:46: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.2.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.2.das || true" "DASTest.at:46"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.2.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:46: diff -b -B \$abs_srcdir/das-testsuite/test.2.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.2.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.2.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.2.das.base stderr" "DASTest.at:46"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.2.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.2.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_16
+#AT_START_17
+# 17. DASTest.at:47: DAS $abs_srcdir/das-testsuite/test.20.das
+at_setup_line='DASTest.at:47'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.20.das"
+at_desc_line=" 17: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "17. DASTest.at:47: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.20.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:47: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.20.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.20.das || true" "DASTest.at:47"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.20.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:47: diff -b -B \$abs_srcdir/das-testsuite/test.20.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.20.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.20.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.20.das.base stderr" "DASTest.at:47"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.20.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.20.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_17
+#AT_START_18
+# 18. DASTest.at:48: DAS $abs_srcdir/das-testsuite/test.21.das
+at_setup_line='DASTest.at:48'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.21.das"
+at_desc_line=" 18: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "18. DASTest.at:48: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.21.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:48: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.21.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.21.das || true" "DASTest.at:48"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.21.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:48: diff -b -B \$abs_srcdir/das-testsuite/test.21.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.21.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.21.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.21.das.base stderr" "DASTest.at:48"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.21.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.21.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_18
+#AT_START_19
+# 19. DASTest.at:49: DAS $abs_srcdir/das-testsuite/test.22.das
+at_setup_line='DASTest.at:49'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.22.das"
+at_desc_line=" 19: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "19. DASTest.at:49: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.22.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:49: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.22.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.22.das || true" "DASTest.at:49"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.22.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:49: diff -b -B \$abs_srcdir/das-testsuite/test.22.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.22.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.22.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.22.das.base stderr" "DASTest.at:49"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.22.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.22.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_19
+#AT_START_20
+# 20. DASTest.at:50: DAS $abs_srcdir/das-testsuite/test.23.das
+at_setup_line='DASTest.at:50'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.23.das"
+at_desc_line=" 20: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "20. DASTest.at:50: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.23.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:50: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.23.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.23.das || true" "DASTest.at:50"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.23.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:50: diff -b -B \$abs_srcdir/das-testsuite/test.23.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.23.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.23.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.23.das.base stderr" "DASTest.at:50"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.23.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.23.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_20
+#AT_START_21
+# 21. DASTest.at:51: DAS $abs_srcdir/das-testsuite/test.24.das
+at_setup_line='DASTest.at:51'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.24.das"
+at_desc_line=" 21: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "21. DASTest.at:51: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.24.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:51: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.24.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.24.das || true" "DASTest.at:51"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.24.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:51: diff -b -B \$abs_srcdir/das-testsuite/test.24.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.24.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.24.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.24.das.base stderr" "DASTest.at:51"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.24.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.24.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_21
+#AT_START_22
+# 22. DASTest.at:52: DAS $abs_srcdir/das-testsuite/test.25.das
+at_setup_line='DASTest.at:52'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.25.das"
+at_desc_line=" 22: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "22. DASTest.at:52: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.25.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:52: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.25.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.25.das || true" "DASTest.at:52"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.25.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:52: diff -b -B \$abs_srcdir/das-testsuite/test.25.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.25.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.25.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.25.das.base stderr" "DASTest.at:52"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.25.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.25.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_22
+#AT_START_23
+# 23. DASTest.at:53: DAS $abs_srcdir/das-testsuite/test.26.das
+at_setup_line='DASTest.at:53'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.26.das"
+at_desc_line=" 23: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "23. DASTest.at:53: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.26.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:53: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.26.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.26.das || true" "DASTest.at:53"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.26.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:53"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:53: diff -b -B \$abs_srcdir/das-testsuite/test.26.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.26.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.26.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.26.das.base stderr" "DASTest.at:53"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.26.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.26.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:53"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_23
+#AT_START_24
+# 24. DASTest.at:54: DAS $abs_srcdir/das-testsuite/test.27.das
+at_setup_line='DASTest.at:54'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.27.das"
+at_desc_line=" 24: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "24. DASTest.at:54: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.27.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:54: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.27.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.27.das || true" "DASTest.at:54"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.27.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:54: diff -b -B \$abs_srcdir/das-testsuite/test.27.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.27.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.27.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.27.das.base stderr" "DASTest.at:54"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.27.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.27.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_24
+#AT_START_25
+# 25. DASTest.at:55: DAS $abs_srcdir/das-testsuite/test.28.das
+at_setup_line='DASTest.at:55'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.28.das"
+at_desc_line=" 25: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "25. DASTest.at:55: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.28.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:55: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.28.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.28.das || true" "DASTest.at:55"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.28.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:55: diff -b -B \$abs_srcdir/das-testsuite/test.28.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.28.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.28.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.28.das.base stderr" "DASTest.at:55"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.28.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.28.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_25
+#AT_START_26
+# 26. DASTest.at:56: DAS $abs_srcdir/das-testsuite/test.29.das
+at_setup_line='DASTest.at:56'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.29.das"
+at_desc_line=" 26: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "26. DASTest.at:56: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.29.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:56: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.29.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.29.das || true" "DASTest.at:56"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.29.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:56"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:56: diff -b -B \$abs_srcdir/das-testsuite/test.29.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.29.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.29.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.29.das.base stderr" "DASTest.at:56"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.29.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.29.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:56"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_26
+#AT_START_27
+# 27. DASTest.at:57: DAS $abs_srcdir/das-testsuite/test.3.das
+at_setup_line='DASTest.at:57'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.3.das"
+at_desc_line=" 27: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "27. DASTest.at:57: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.3.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:57: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.3.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.3.das || true" "DASTest.at:57"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.3.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:57: diff -b -B \$abs_srcdir/das-testsuite/test.3.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.3.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.3.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.3.das.base stderr" "DASTest.at:57"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.3.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.3.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_27
+#AT_START_28
+# 28. DASTest.at:58: DAS $abs_srcdir/das-testsuite/test.3.Z.das
+at_setup_line='DASTest.at:58'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.3.Z.das"
+at_desc_line=" 28: $at_desc     "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "28. DASTest.at:58: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.3.Z.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:58: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.3.Z.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.3.Z.das || true" "DASTest.at:58"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.3.Z.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:58: diff -b -B \$abs_srcdir/das-testsuite/test.3.Z.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.3.Z.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.3.Z.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.3.Z.das.base stderr" "DASTest.at:58"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.3.Z.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.3.Z.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_28
+#AT_START_29
+# 29. DASTest.at:59: DAS $abs_srcdir/das-testsuite/test.30.das
+at_setup_line='DASTest.at:59'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.30.das"
+at_desc_line=" 29: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "29. DASTest.at:59: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.30.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:59: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.30.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.30.das || true" "DASTest.at:59"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.30.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:59: diff -b -B \$abs_srcdir/das-testsuite/test.30.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.30.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.30.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.30.das.base stderr" "DASTest.at:59"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.30.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.30.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_29
+#AT_START_30
+# 30. DASTest.at:60: DAS $abs_srcdir/das-testsuite/test.31.das
+at_setup_line='DASTest.at:60'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.31.das"
+at_desc_line=" 30: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "30. DASTest.at:60: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.31.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:60: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.31.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.31.das || true" "DASTest.at:60"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.31.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:60"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:60: diff -b -B \$abs_srcdir/das-testsuite/test.31.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.31.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.31.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.31.das.base stderr" "DASTest.at:60"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.31.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.31.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:60"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_30
+#AT_START_31
+# 31. DASTest.at:61: DAS $abs_srcdir/das-testsuite/test.32.das
+at_setup_line='DASTest.at:61'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.32.das"
+at_desc_line=" 31: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "31. DASTest.at:61: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.32.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:61: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.32.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.32.das || true" "DASTest.at:61"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.32.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:61: diff -b -B \$abs_srcdir/das-testsuite/test.32.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.32.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.32.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.32.das.base stderr" "DASTest.at:61"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.32.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.32.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_31
+#AT_START_32
+# 32. DASTest.at:62: DAS $abs_srcdir/das-testsuite/test.33.das
+at_setup_line='DASTest.at:62'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.33.das"
+at_desc_line=" 32: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "32. DASTest.at:62: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.33.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:62: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.33.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.33.das || true" "DASTest.at:62"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.33.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:62: diff -b -B \$abs_srcdir/das-testsuite/test.33.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.33.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.33.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.33.das.base stderr" "DASTest.at:62"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.33.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.33.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_32
+#AT_START_33
+# 33. DASTest.at:63: DAS $abs_srcdir/das-testsuite/test.34.das
+at_setup_line='DASTest.at:63'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.34.das"
+at_desc_line=" 33: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "33. DASTest.at:63: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.34.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:63: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.34.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.34.das || true" "DASTest.at:63"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.34.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:63"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:63: diff -b -B \$abs_srcdir/das-testsuite/test.34.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.34.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.34.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.34.das.base stderr" "DASTest.at:63"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.34.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.34.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:63"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_33
+#AT_START_34
+# 34. DASTest.at:64: DAS $abs_srcdir/das-testsuite/test.35.das
+at_setup_line='DASTest.at:64'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.35.das"
+at_desc_line=" 34: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "34. DASTest.at:64: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.35.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:64: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.35.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.35.das || true" "DASTest.at:64"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.35.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:64"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:64: diff -b -B \$abs_srcdir/das-testsuite/test.35.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.35.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.35.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.35.das.base stderr" "DASTest.at:64"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.35.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.35.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:64"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_34
+#AT_START_35
+# 35. DASTest.at:65: DAS $abs_srcdir/das-testsuite/test.4.das
+at_setup_line='DASTest.at:65'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.4.das"
+at_desc_line=" 35: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "35. DASTest.at:65: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.4.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:65: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.4.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.4.das || true" "DASTest.at:65"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.4.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:65"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:65: diff -b -B \$abs_srcdir/das-testsuite/test.4.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.4.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.4.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.4.das.base stderr" "DASTest.at:65"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.4.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.4.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:65"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_35
+#AT_START_36
+# 36. DASTest.at:66: DAS $abs_srcdir/das-testsuite/test.5.das
+at_setup_line='DASTest.at:66'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.5.das"
+at_desc_line=" 36: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "36. DASTest.at:66: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.5.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:66: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.5.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.5.das || true" "DASTest.at:66"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.5.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:66"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:66: diff -b -B \$abs_srcdir/das-testsuite/test.5.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.5.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.5.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.5.das.base stderr" "DASTest.at:66"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.5.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.5.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:66"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_36
+#AT_START_37
+# 37. DASTest.at:67: DAS $abs_srcdir/das-testsuite/test.6.das
+at_setup_line='DASTest.at:67'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.6.das"
+at_desc_line=" 37: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "37. DASTest.at:67: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.6.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:67: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.6.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.6.das || true" "DASTest.at:67"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.6.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:67"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:67: diff -b -B \$abs_srcdir/das-testsuite/test.6.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.6.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.6.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.6.das.base stderr" "DASTest.at:67"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.6.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.6.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:67"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_37
+#AT_START_38
+# 38. DASTest.at:68: DAS $abs_srcdir/das-testsuite/test.7.das
+at_setup_line='DASTest.at:68'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.7.das"
+at_desc_line=" 38: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "38. DASTest.at:68: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.7.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:68: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.7.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.7.das || true" "DASTest.at:68"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.7.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:68"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:68: diff -b -B \$abs_srcdir/das-testsuite/test.7.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.7.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.7.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.7.das.base stderr" "DASTest.at:68"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.7.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.7.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:68"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_38
+#AT_START_39
+# 39. DASTest.at:69: DAS $abs_srcdir/das-testsuite/test.8.das
+at_setup_line='DASTest.at:69'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.8.das"
+at_desc_line=" 39: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "39. DASTest.at:69: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.8.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:69: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.8.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.8.das || true" "DASTest.at:69"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.8.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:69"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:69: diff -b -B \$abs_srcdir/das-testsuite/test.8.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.8.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.8.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.8.das.base stderr" "DASTest.at:69"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.8.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.8.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:69"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_39
+#AT_START_40
+# 40. DASTest.at:70: DAS $abs_srcdir/das-testsuite/test.9.das
+at_setup_line='DASTest.at:70'
+at_desc="DAS \$abs_srcdir/das-testsuite/test.9.das"
+at_desc_line=" 40: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "40. DASTest.at:70: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/das-test -p < $abs_srcdir/das-testsuite/test.9.das needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:70: \$abs_builddir/das-test -p < \$abs_srcdir/das-testsuite/test.9.das || true"
+at_fn_check_prepare_dynamic "$abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.9.das || true" "DASTest.at:70"
+( $at_check_trace; $abs_builddir/das-test -p < $abs_srcdir/das-testsuite/test.9.das || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:70"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DASTest.at:70: diff -b -B \$abs_srcdir/das-testsuite/test.9.das.base stdout || diff -b -B \$abs_srcdir/das-testsuite/test.9.das.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/das-testsuite/test.9.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.9.das.base stderr" "DASTest.at:70"
+( $at_check_trace; diff -b -B $abs_srcdir/das-testsuite/test.9.das.base stdout || diff -b -B $abs_srcdir/das-testsuite/test.9.das.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DASTest.at:70"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_40
diff --git a/tests/DASTest.at b/tests/DASTest.at
new file mode 100644
index 0000000..7900ace
--- /dev/null
+++ b/tests/DASTest.at
@@ -0,0 +1,70 @@
+# Process with autom4te to create an -*- Autotest -*- test suite.
+
+
+# ------------------------------
+#
+
+AT_INIT([das-test])
+# AT_COPYRIGHT([])
+
+# AT_TESTED([das-test])
+
+# Usage: _AT_TEST_*(<das source>, <baseline file>)
+
+m4_define([_AT_DAS_TEST],   
+[# AT_BANNER([Test $1 $2])
+AT_SETUP([DAS $1])
+AT_KEYWORDS([das])
+#Added || true because the $abs_srcdir/das-test -p < $1 needs to be true whether the
+#output is printed to stdout or stderr
+AT_CHECK([$abs_builddir/das-test -p < $1 || true], [], [stdout], [stderr])
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+AT_CHECK([diff -b -B $2 stdout || diff -b -B $2 stderr], [], [ignore],[],[])
+AT_CLEANUP])
+
+m4_define([AT_DAS_RESPONSE_TEST],
+[#AT_BANNER([DAS response for $1.])
+_AT_DAS_TEST([$abs_srcdir/das-testsuite/$1], [$abs_srcdir/das-testsuite/$1.base])
+])
+
+AT_DAS_RESPONSE_TEST([bad_value_test.1.das])
+AT_DAS_RESPONSE_TEST([das.das])
+AT_DAS_RESPONSE_TEST([special.test.das])
+AT_DAS_RESPONSE_TEST([special.test.hdf.das])
+AT_DAS_RESPONSE_TEST([test.1.das])
+AT_DAS_RESPONSE_TEST([test.11.das])
+AT_DAS_RESPONSE_TEST([test.12.das])
+AT_DAS_RESPONSE_TEST([test.13.das])
+AT_DAS_RESPONSE_TEST([test.14.das])
+AT_DAS_RESPONSE_TEST([test.15.das])
+AT_DAS_RESPONSE_TEST([test.16.das])
+AT_DAS_RESPONSE_TEST([test.17.das])
+AT_DAS_RESPONSE_TEST([test.18.das])
+AT_DAS_RESPONSE_TEST([test.19.das])
+AT_DAS_RESPONSE_TEST([test.1a.das])
+AT_DAS_RESPONSE_TEST([test.2.das])
+AT_DAS_RESPONSE_TEST([test.20.das])
+AT_DAS_RESPONSE_TEST([test.21.das])
+AT_DAS_RESPONSE_TEST([test.22.das])
+AT_DAS_RESPONSE_TEST([test.23.das])
+AT_DAS_RESPONSE_TEST([test.24.das])
+AT_DAS_RESPONSE_TEST([test.25.das])
+AT_DAS_RESPONSE_TEST([test.26.das])
+AT_DAS_RESPONSE_TEST([test.27.das])
+AT_DAS_RESPONSE_TEST([test.28.das])
+AT_DAS_RESPONSE_TEST([test.29.das])
+AT_DAS_RESPONSE_TEST([test.3.das])
+AT_DAS_RESPONSE_TEST([test.3.Z.das])
+AT_DAS_RESPONSE_TEST([test.30.das])
+AT_DAS_RESPONSE_TEST([test.31.das])
+AT_DAS_RESPONSE_TEST([test.32.das])
+AT_DAS_RESPONSE_TEST([test.33.das])
+AT_DAS_RESPONSE_TEST([test.34.das])
+AT_DAS_RESPONSE_TEST([test.35.das])
+AT_DAS_RESPONSE_TEST([test.4.das])
+AT_DAS_RESPONSE_TEST([test.5.das])
+AT_DAS_RESPONSE_TEST([test.6.das])
+AT_DAS_RESPONSE_TEST([test.7.das])
+AT_DAS_RESPONSE_TEST([test.8.das])
+AT_DAS_RESPONSE_TEST([test.9.das])
diff --git a/tests/DDSTest b/tests/DDSTest
new file mode 100755
index 0000000..6dfb702
--- /dev/null
+++ b/tests/DDSTest
@@ -0,0 +1,3355 @@
+#! /bin/sh
+# Generated from DDSTest.at by GNU Autoconf 2.65.
+#
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This test suite is free software; the Free Software Foundation gives
+# unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+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
+IFS=$as_save_IFS
+
+     ;;
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+# 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
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# 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'"
+
+
+
+
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# How were we run?
+at_cli_args="$@"
+
+
+# Not all shells have the 'times' builtin; the subshell is needed to make
+# sure we discard the 'times: not found' message from the shell.
+at_times_p=false
+(times) >/dev/null 2>&1 && at_times_p=:
+
+# CLI Arguments to pass to the debugging scripts.
+at_debug_args=
+# -e sets to true
+at_errexit_p=false
+# Shall we be verbose?  ':' means no, empty means yes.
+at_verbose=:
+at_quiet=
+# Running several jobs in parallel, 0 means as many as test groups.
+at_jobs=1
+at_traceon=:
+at_trace_echo=:
+at_check_filter_trace=:
+
+# Shall we keep the debug scripts?  Must be `:' when the suite is
+# run by a debug script, so that the script doesn't remove itself.
+at_debug_p=false
+# Display help message?
+at_help_p=false
+# Display the version message?
+at_version_p=false
+# List test groups?
+at_list_p=false
+# --clean
+at_clean=false
+# Test groups to run
+at_groups=
+# Whether a write failure occurred
+at_write_fail=0
+
+# The directory we run the suite in.  Default to . if no -C option.
+at_dir=`pwd`
+# An absolute reference to this testsuite script.
+case $as_myself in
+  [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;;
+  * ) at_myself=$at_dir/$as_myself ;;
+esac
+# Whether -C is in effect.
+at_change_dir=false
+
+# List of the tested programs.
+at_tested=''
+# List of the all the test groups.
+at_groups_all=' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29'
+# As many question marks as there are digits in the last test group number.
+# Used to normalize the test group numbers so that `ls' lists them in
+# numerical order.
+at_format='??'
+# Description of all the test groups.
+at_help_all="1;DDSTest.at:34;DDS \$abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds;dds;
+2;DDSTest.at:35;DDS \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds;dds;
+3;DDSTest.at:36;DDS \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds;dds;
+4;DDSTest.at:37;DDS \$abs_srcdir/dds-testsuite/AsciiOutputTest1.dds;dds;
+5;DDSTest.at:38;DDS \$abs_srcdir/dds-testsuite/fnoc1.nc.das.dds;dds;
+6;DDSTest.at:39;DDS \$abs_srcdir/dds-testsuite/fnoc1.nc.dds;dds;
+7;DDSTest.at:40;DDS \$abs_srcdir/dds-testsuite/S2000415.HDF.das.dds;dds;
+8;DDSTest.at:41;DDS \$abs_srcdir/dds-testsuite/S2000415.HDF.dds;dds;
+9;DDSTest.at:42;DDS \$abs_srcdir/dds-testsuite/test.1.dds;dds;
+10;DDSTest.at:43;DDS \$abs_srcdir/dds-testsuite/test.10.dds;dds;
+11;DDSTest.at:44;DDS \$abs_srcdir/dds-testsuite/test.11.dds;dds;
+12;DDSTest.at:45;DDS \$abs_srcdir/dds-testsuite/test.12.dds;dds;
+13;DDSTest.at:46;DDS \$abs_srcdir/dds-testsuite/test.13.dds;dds;
+14;DDSTest.at:47;DDS \$abs_srcdir/dds-testsuite/test.14.dds;dds;
+15;DDSTest.at:48;DDS \$abs_srcdir/dds-testsuite/test.15.dds;dds;
+16;DDSTest.at:49;DDS \$abs_srcdir/dds-testsuite/test.16.dds;dds;
+17;DDSTest.at:50;DDS \$abs_srcdir/dds-testsuite/test.17.dds;dds;
+18;DDSTest.at:51;DDS \$abs_srcdir/dds-testsuite/test.18.dds;dds;
+19;DDSTest.at:52;DDS \$abs_srcdir/dds-testsuite/test.19.dds;dds;
+20;DDSTest.at:53;DDS \$abs_srcdir/dds-testsuite/test.19b.das.dds;dds;
+21;DDSTest.at:54;DDS \$abs_srcdir/dds-testsuite/test.19b.dds;dds;
+22;DDSTest.at:55;DDS \$abs_srcdir/dds-testsuite/test.2.dds;dds;
+23;DDSTest.at:56;DDS \$abs_srcdir/dds-testsuite/test.20.dds;dds;
+24;DDSTest.at:57;DDS \$abs_srcdir/dds-testsuite/test.3.dds;dds;
+25;DDSTest.at:58;DDS \$abs_srcdir/dds-testsuite/test.4.dds;dds;
+26;DDSTest.at:59;DDS \$abs_srcdir/dds-testsuite/test.6.dds;dds;
+27;DDSTest.at:60;DDS \$abs_srcdir/dds-testsuite/test.7.dds;dds;
+28;DDSTest.at:61;DDS \$abs_srcdir/dds-testsuite/test.8.dds;dds;
+29;DDSTest.at:62;DDS \$abs_srcdir/dds-testsuite/test.9.dds;dds;
+"
+
+# at_fn_validate_ranges NAME...
+# -----------------------------
+# Validate and normalize the test group number contained in each variable
+# NAME. Leading zeroes are treated as decimal.
+at_fn_validate_ranges ()
+{
+  for at_grp
+  do
+    eval at_value=\$$at_grp
+    if test $at_value -lt 1 || test $at_value -gt 29; then
+      $as_echo "invalid test group: $at_value" >&2
+      exit 1
+    fi
+    case $at_value in
+      0*) # We want to treat leading 0 as decimal, like expr and test, but
+	  # AS_VAR_ARITH treats it as octal if it uses $(( )).
+	  # With XSI shells, ${at_value#${at_value%%[1-9]*}} avoids the
+	  # expr fork, but it is not worth the effort to determine if the
+	  # shell supports XSI when the user can just avoid leading 0.
+	  eval $at_grp='`expr $at_value + 0`' ;;
+    esac
+  done
+}
+
+at_prev=
+for at_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$at_prev"; then
+    at_option=$at_prev=$at_option
+    at_prev=
+  fi
+
+  case $at_option in
+  *=*) at_optarg=`expr "x$at_option" : 'x[^=]*=\(.*\)'` ;;
+  *)   at_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $at_option in
+    --help | -h )
+	at_help_p=:
+	;;
+
+    --list | -l )
+	at_list_p=:
+	;;
+
+    --version | -V )
+	at_version_p=:
+	;;
+
+    --clean | -c )
+	at_clean=:
+	;;
+
+    --debug | -d )
+	at_debug_p=:
+	;;
+
+    --errexit | -e )
+	at_debug_p=:
+	at_errexit_p=:
+	;;
+
+    --verbose | -v )
+	at_verbose=; at_quiet=:
+	;;
+
+    --trace | -x )
+	at_traceon='set -x'
+	at_trace_echo=echo
+	at_check_filter_trace=at_fn_filter_trace
+	;;
+
+    [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9])
+	at_fn_validate_ranges at_option
+	as_fn_append at_groups "$at_option "
+	;;
+
+    # Ranges
+    [0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-)
+	at_range_start=`echo $at_option |tr -d X-`
+	at_fn_validate_ranges at_range_start
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/^.* \('$at_range_start' \)/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9])
+	at_range_end=`echo $at_option |tr -d X-`
+	at_fn_validate_ranges at_range_end
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/\( '$at_range_end'\) .*$/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    [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] | \
+    [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][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] )
+	at_range_start=`expr $at_option : '\(.*\)-'`
+	at_range_end=`expr $at_option : '.*-\(.*\)'`
+	if test $at_range_start -gt $at_range_end; then
+	  at_tmp=$at_range_end
+	  at_range_end=$at_range_start
+	  at_range_start=$at_tmp
+	fi
+	at_fn_validate_ranges at_range_start at_range_end
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/^.*\( '$at_range_start' \)/\1/' \
+	      -e 's/\( '$at_range_end'\) .*$/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    # Directory selection.
+    --directory | -C )
+	at_prev=--directory
+	;;
+    --directory=* )
+	at_change_dir=:
+	at_dir=$at_optarg
+	;;
+
+    # Parallel execution.
+    --jobs | -j )
+	at_jobs=0
+	;;
+    --jobs=* | -j[0-9]* )
+	if test -n "$at_optarg"; then
+	  at_jobs=$at_optarg
+	else
+	  at_jobs=`expr X$at_option : 'X-j\(.*\)'`
+	fi
+	case $at_jobs in *[!0-9]*)
+	  at_optname=`echo " $at_option" | sed 's/^ //; s/[0-9=].*//'`
+	  as_fn_error "non-numeric argument to $at_optname: $at_jobs" ;;
+	esac
+	;;
+
+    # Keywords.
+    --keywords | -k )
+	at_prev=--keywords
+	;;
+    --keywords=* )
+	at_groups_selected=$at_help_all
+	at_save_IFS=$IFS
+	IFS=,
+	set X $at_optarg
+	shift
+	IFS=$at_save_IFS
+	for at_keyword
+	do
+	  at_invert=
+	  case $at_keyword in
+	  '!'*)
+	    at_invert="-v"
+	    at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
+	    ;;
+	  esac
+	  # It is on purpose that we match the test group titles too.
+	  at_groups_selected=`$as_echo "$at_groups_selected" |
+	      grep -i $at_invert "^[1-9][^;]*;.*[; ]$at_keyword[ ;]"`
+	done
+	# Smash the newlines.
+	at_groups_selected=`$as_echo "$at_groups_selected" | sed 's/;.*//' |
+	  tr "$as_nl" ' '
+	`
+	as_fn_append at_groups "$at_groups_selected "
+	;;
+
+    *=*)
+	at_envvar=`expr "x$at_option" : 'x\([^=]*\)='`
+	# Reject names that are not valid shell variable names.
+	case $at_envvar in
+	  '' | [0-9]* | *[!_$as_cr_alnum]* )
+	    as_fn_error "invalid variable name: \`$at_envvar'" ;;
+	esac
+	at_value=`$as_echo "$at_optarg" | sed "s/'/'\\\\\\\\''/g"`
+	# Export now, but save eval for later and for debug scripts.
+	export $at_envvar
+	as_fn_append at_debug_args " $at_envvar='$at_value'"
+	;;
+
+     *) $as_echo "$as_me: invalid option: $at_option" >&2
+	$as_echo "Try \`$0 --help' for more information." >&2
+	exit 1
+	;;
+  esac
+done
+
+# Verify our last option didn't require an argument
+if test -n "$at_prev"; then :
+  as_fn_error "\`$at_prev' requires an argument."
+fi
+
+# Selected test groups.
+if test -z "$at_groups"; then
+  at_groups=$at_groups_all
+else
+  # Sort the tests, removing duplicates.
+  at_groups=`$as_echo "$at_groups" | tr ' ' "$as_nl" | sort -nu`
+fi
+
+# Help message.
+if $at_help_p; then
+  cat <<_ATEOF || at_write_fail=1
+Usage: $0 [OPTION]... [VARIABLE=VALUE]... [TESTS]
+
+Run all the tests, or the selected TESTS, given by numeric ranges, and
+save a detailed log file.  Upon failure, create debugging scripts.
+
+Do not change environment variables directly.  Instead, set them via
+command line arguments.  Set \`AUTOTEST_PATH' to select the executables
+to exercise.  Each relative directory is expanded as build and source
+directories relative to the top level of this distribution.
+E.g., from within the build directory /tmp/foo-1.0, invoking this:
+
+  $ $0 AUTOTEST_PATH=bin
+
+is equivalent to the following, assuming the source directory is /src/foo-1.0:
+
+  PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH $0
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Operation modes:
+  -h, --help     print the help message, then exit
+  -V, --version  print version number, then exit
+  -c, --clean    remove all the files this test suite might create and exit
+  -l, --list     describes all the tests, or the selected TESTS
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Execution tuning:
+  -C, --directory=DIR
+                 change to directory DIR before starting
+  -j, --jobs[=N]
+                 Allow N jobs at once; infinite jobs with no arg (default 1)
+  -k, --keywords=KEYWORDS
+                 select the tests matching all the comma-separated KEYWORDS
+                 multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD
+  -e, --errexit  abort as soon as a test fails; implies --debug
+  -v, --verbose  force more detailed output
+                 default for debugging scripts
+  -d, --debug    inhibit clean up and top-level logging
+                 default for debugging scripts
+  -x, --trace    enable tests shell tracing
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Report bugs to <opendap-tech at opendap.org>.
+_ATEOF
+  exit $at_write_fail
+fi
+
+# List of tests.
+if $at_list_p; then
+  cat <<_ATEOF || at_write_fail=1
+libdap 3.11.1 test suite: dds-test test groups:
+
+ NUM: FILE-NAME:LINE     TEST-GROUP-NAME
+      KEYWORDS
+
+_ATEOF
+  # Passing at_groups is tricky.  We cannot use it to form a literal string
+  # or regexp because of the limitation of AIX awk.  And Solaris' awk
+  # doesn't grok more than 99 fields in a record, so we have to use `split'.
+  # at_groups needs to be space-separated for this script to work.
+  case $at_groups in
+    *"$as_nl"* )
+      at_groups=`$as_echo "$at_groups" | tr "$as_nl" ' '` ;;
+  esac
+  $as_echo "$at_groups$as_nl$at_help_all" |
+    awk 'BEGIN { FS = ";" }
+	 NR == 1 {
+	   for (n = split ($ 0, a, " "); n; n--)
+	     selected[a[n]] = 1
+	   next
+	 }
+	 NF > 0 {
+	   if (selected[$ 1]) {
+	     printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
+	     if ($ 4) {
+	       lmax = 79
+	       indent = "     "
+	       line = indent
+	       len = length (line)
+	       n = split ($ 4, a, " ")
+	       for (i = 1; i <= n; i++) {
+		 l = length (a[i]) + 1
+		 if (i > 1 && len + l > lmax) {
+		   print line
+		   line = indent " " a[i]
+		   len = length (line)
+		 } else {
+		   line = line " " a[i]
+		   len += l
+		 }
+	       }
+	       if (n)
+		 print line
+	     }
+	   }
+	 }' || at_write_fail=1
+  exit $at_write_fail
+fi
+if $at_version_p; then
+  $as_echo "$as_me (libdap 3.11.1)" &&
+  cat <<\_ATEOF || at_write_fail=1
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This test suite is free software; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+_ATEOF
+  exit $at_write_fail
+fi
+
+# Should we print banners?  at_groups is space-separated for entire test,
+# newline-separated if only a subset of the testsuite is run.
+case $at_groups in
+  *' '*' '* | *"$as_nl"*"$as_nl"* )
+      at_print_banners=: ;;
+  * ) at_print_banners=false ;;
+esac
+# Text for banner N, set to empty once printed.
+
+# Take any -C into account.
+if $at_change_dir ; then
+  if test x- = "x$at_dir" ; then
+    at_dir=./-
+  fi
+  test x != "x$at_dir" && cd "$at_dir" \
+    || as_fn_error "unable to change directory"
+  at_dir=`pwd`
+fi
+
+# Load the config files for any default variable assignments.
+for at_file in atconfig atlocal
+do
+  test -r $at_file || continue
+  . ./$at_file || as_fn_error "invalid content: $at_file"
+done
+
+# Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
+: ${at_top_build_prefix=$at_top_builddir}
+
+# Perform any assignments requested during argument parsing.
+eval "$at_debug_args"
+
+# atconfig delivers names relative to the directory the test suite is
+# in, but the groups themselves are run in testsuite-dir/group-dir.
+if test -n "$at_top_srcdir"; then
+  builddir=../..
+  for at_dir_var in srcdir top_srcdir top_build_prefix
+  do
+    eval at_val=\$at_$at_dir_var
+    case $at_val in
+      [\\/$]* | ?:[\\/]* ) at_prefix= ;;
+      *) at_prefix=../../ ;;
+    esac
+    eval "$at_dir_var=\$at_prefix\$at_val"
+  done
+fi
+
+## -------------------- ##
+## Directory structure. ##
+## -------------------- ##
+
+# This is the set of directories and files used by this script
+# (non-literals are capitalized):
+#
+# TESTSUITE         - the testsuite
+# TESTSUITE.log     - summarizes the complete testsuite run
+# TESTSUITE.dir/    - created during a run, remains after -d or failed test
+# + at-groups/      - during a run: status of all groups in run
+# | + NNN/          - during a run: meta-data about test group NNN
+# | | + check-line  - location (source file and line) of current AT_CHECK
+# | | + status      - exit status of current AT_CHECK
+# | | + stdout      - stdout of current AT_CHECK
+# | | + stder1      - stderr, including trace
+# | | + stderr      - stderr, with trace filtered out
+# | | + test-source - portion of testsuite that defines group
+# | | + times       - timestamps for computing duration
+# | | + pass        - created if group passed
+# | | + xpass       - created if group xpassed
+# | | + fail        - created if group failed
+# | | + xfail       - created if group xfailed
+# | | + skip        - created if group skipped
+# + at-stop         - during a run: end the run if this file exists
+# + at-source-lines - during a run: cache of TESTSUITE line numbers for extraction
+# + 0..NNN/         - created for each group NNN, remains after -d or failed test
+# | + TESTSUITE.log - summarizes the group results
+# | + ...           - files created during the group
+
+# The directory the whole suite works in.
+# Should be absolute to let the user `cd' at will.
+at_suite_dir=$at_dir/$as_me.dir
+# The file containing the suite.
+at_suite_log=$at_dir/$as_me.log
+# The directory containing helper files per test group.
+at_helper_dir=$at_suite_dir/at-groups
+# Stop file: if it exists, do not start new jobs.
+at_stop_file=$at_suite_dir/at-stop
+# The fifo used for the job dispatcher.
+at_job_fifo=$at_suite_dir/at-job-fifo
+
+if $at_clean; then
+  test -d "$at_suite_dir" &&
+    find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+  rm -f -r "$at_suite_dir" "$at_suite_log"
+  exit $?
+fi
+
+# Don't take risks: use only absolute directories in PATH.
+#
+# For stand-alone test suites (ie. atconfig was not found),
+# AUTOTEST_PATH is relative to `.'.
+#
+# For embedded test suites, AUTOTEST_PATH is relative to the top level
+# of the package.  Then expand it into build/src parts, since users
+# may create executables in both places.
+AUTOTEST_PATH=`$as_echo "$AUTOTEST_PATH" | sed "s|:|$PATH_SEPARATOR|g"`
+at_path=
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $AUTOTEST_PATH $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -n "$at_path" && as_fn_append at_path $PATH_SEPARATOR
+case $as_dir in
+  [\\/]* | ?:[\\/]* )
+    as_fn_append at_path "$as_dir"
+    ;;
+  * )
+    if test -z "$at_top_build_prefix"; then
+      # Stand-alone test suite.
+      as_fn_append at_path "$as_dir"
+    else
+      # Embedded test suite.
+      as_fn_append at_path "$at_top_build_prefix$as_dir$PATH_SEPARATOR"
+      as_fn_append at_path "$at_top_srcdir/$as_dir"
+    fi
+    ;;
+esac
+  done
+IFS=$as_save_IFS
+
+
+# Now build and simplify PATH.
+#
+# There might be directories that don't exist, but don't redirect
+# builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
+at_new_path=
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $at_path
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -d "$as_dir" || continue
+case $as_dir in
+  [\\/]* | ?:[\\/]* ) ;;
+  * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;;
+esac
+case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in
+  *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;;
+  $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;;
+  *) as_fn_append at_new_path "$PATH_SEPARATOR$as_dir" ;;
+esac
+  done
+IFS=$as_save_IFS
+
+PATH=$at_new_path
+export PATH
+
+# Setting up the FDs.
+
+
+# 5 is the log file.  Not to be overwritten if `-d'.
+if $at_debug_p; then
+  at_suite_log=/dev/null
+else
+  : >"$at_suite_log"
+fi
+exec 5>>"$at_suite_log"
+
+# Banners and logs.
+cat <<\_ASBOX
+## ----------------------------------- ##
+## libdap 3.11.1 test suite: dds-test. ##
+## ----------------------------------- ##
+_ASBOX
+{
+  cat <<\_ASBOX
+## ----------------------------------- ##
+## libdap 3.11.1 test suite: dds-test. ##
+## ----------------------------------- ##
+_ASBOX
+  echo
+
+  $as_echo "$as_me: command line was:"
+  $as_echo "  \$ $0 $at_cli_args"
+  echo
+
+  # Try to find a few ChangeLogs in case it might help determining the
+  # exact version.  Use the relative dir: if the top dir is a symlink,
+  # find will not follow it (and options to follow the links are not
+  # portable), which would result in no output here.  Prune directories
+  # matching the package tarname, since they tend to be leftovers from
+  # `make dist' or `make distcheck' and contain redundant or stale logs.
+  if test -n "$at_top_srcdir"; then
+    cat <<\_ASBOX
+## ----------- ##
+## ChangeLogs. ##
+## ----------- ##
+_ASBOX
+    echo
+    for at_file in `find "$at_top_srcdir" -name "libdap-*" -prune -o -name ChangeLog -print`
+    do
+      $as_echo "$as_me: $at_file:"
+      sed 's/^/| /;10q' $at_file
+      echo
+    done
+
+  fi
+
+  {
+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`
+/usr/bin/hostinfo      = `(/usr/bin/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=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+}
+  echo
+
+  # Contents of the config files.
+  for at_file in atconfig atlocal
+  do
+    test -r $at_file || continue
+    $as_echo "$as_me: $at_file:"
+    sed 's/^/| /' $at_file
+    echo
+  done
+} >&5
+
+
+## ------------------------- ##
+## Autotest shell functions. ##
+## ------------------------- ##
+
+# at_fn_banner NUMBER
+# -------------------
+# Output banner NUMBER, provided the testsuite is running multiple groups and
+# this particular banner has not yet been printed.
+at_fn_banner ()
+{
+  $at_print_banners || return 0
+  eval at_banner_text=\$at_banner_text_$1
+  test "x$at_banner_text" = x && return 0
+  eval at_banner_text_$1=
+  $as_echo "$as_nl$at_banner_text$as_nl"
+} # at_fn_banner
+
+# at_fn_check_prepare_notrace REASON LINE
+# ---------------------------------------
+# Perform AT_CHECK preparations for the command at LINE for an untraceable
+# command; REASON is the reason for disabling tracing.
+at_fn_check_prepare_notrace ()
+{
+  $at_trace_echo "Not enabling shell tracing (command contains $1)"
+  $as_echo "$2" >"$at_check_line_file"
+  at_check_trace=: at_check_filter=:
+  : >"$at_stdout"; : >"$at_stderr"
+}
+
+# at_fn_check_prepare_trace LINE
+# ------------------------------
+# Perform AT_CHECK preparations for the command at LINE for a traceable
+# command.
+at_fn_check_prepare_trace ()
+{
+  $as_echo "$1" >"$at_check_line_file"
+  at_check_trace=$at_traceon at_check_filter=$at_check_filter_trace
+  : >"$at_stdout"; : >"$at_stderr"
+}
+
+# at_fn_check_prepare_dynamic COMMAND LINE
+# ----------------------------------------
+# Decide if COMMAND at LINE is traceable at runtime, and call the appropriate
+# preparation function.
+at_fn_check_prepare_dynamic ()
+{
+  case $1 in
+    *$as_nl*)
+      at_fn_check_prepare_notrace 'an embedded newline' "$2" ;;
+    *)
+      at_fn_check_prepare_trace "$2" ;;
+  esac
+}
+
+# at_fn_filter_trace
+# ------------------
+# Remove the lines in the file "$at_stderr" generated by "set -x" and print
+# them to stderr.
+at_fn_filter_trace ()
+{
+  mv "$at_stderr" "$at_stder1"
+  grep '^ *+' "$at_stder1" >&2
+  grep -v '^ *+' "$at_stder1" >"$at_stderr"
+}
+
+# at_fn_log_failure FILE-LIST
+# ---------------------------
+# Copy the files in the list on stdout with a "> " prefix, and exit the shell
+# with a failure exit code.
+at_fn_log_failure ()
+{
+  for file
+    do $as_echo "$file:"; sed 's/^/> /' "$file"; done
+  echo 1 > "$at_status_file"
+  exit 1
+}
+
+# at_fn_check_skip EXIT-CODE LINE
+# -------------------------------
+# Check whether EXIT-CODE is a special exit code (77 or 99), and if so exit
+# the test group subshell with that same exit code. Use LINE in any report
+# about test failure.
+at_fn_check_skip ()
+{
+  case $1 in
+    99) echo 99 > "$at_status_file"; at_failed=:
+	$as_echo "$2: hard failure"; exit 99;;
+    77) echo 77 > "$at_status_file"; exit 77;;
+  esac
+}
+
+# at_fn_check_status EXPECTED EXIT-CODE LINE
+# ------------------------------------------
+# Check whether EXIT-CODE is the EXPECTED exit code, and if so do nothing.
+# Otherwise, if it is 77 or 99, exit the test group subshell with that same
+# exit code; if it is anything else print an error message referring to LINE,
+# and fail the test.
+at_fn_check_status ()
+{
+  case $2 in
+    $1 ) ;;
+    77) echo 77 > "$at_status_file"; exit 77;;
+    99) echo 99 > "$at_status_file"; at_failed=:
+	$as_echo "$3: hard failure"; exit 99;;
+    *) $as_echo "$3: exit code was $2, expected $1"
+      at_failed=:;;
+  esac
+}
+
+# at_fn_diff_devnull FILE
+# -----------------------
+# Emit a diff between /dev/null and FILE. Uses "test -s" to avoid useless diff
+# invocations.
+at_fn_diff_devnull ()
+{
+  test -s "$1" || return 0
+  $at_diff "$at_devnull" "$1"
+}
+
+# at_fn_test NUMBER
+# -----------------
+# Parse out test NUMBER from the tail of this file.
+at_fn_test ()
+{
+  eval at_sed=\$at_sed$1
+  sed "$at_sed" "$at_myself" > "$at_test_source"
+}
+
+# at_fn_create_debugging_script
+# -----------------------------
+# Create the debugging script $at_group_dir/run which will reproduce the
+# current test group.
+at_fn_create_debugging_script ()
+{
+  {
+    echo "#! /bin/sh" &&
+    echo 'test "${ZSH_VERSION+set}" = set && alias -g '\''${1+"$@"}'\''='\''"$@"'\''' &&
+    $as_echo "cd '$at_dir'" &&
+    $as_echo "exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d $at_debug_args $at_group \${1+\"\$@\"}" &&
+    echo 'exit 1'
+  } >"$at_group_dir/run" &&
+  chmod +x "$at_group_dir/run"
+}
+
+## -------------------------------- ##
+## End of autotest shell functions. ##
+## -------------------------------- ##
+{
+  cat <<\_ASBOX
+## ---------------- ##
+## Tested programs. ##
+## ---------------- ##
+_ASBOX
+  echo
+} >&5
+
+# Report what programs are being tested.
+for at_program in : $at_tested
+do
+  test "$at_program" = : && continue
+  case $at_program in
+    [\\/]* | ?:[\\/]* ) $at_program_=$at_program ;;
+    * )
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -f "$as_dir/$at_program" && break
+  done
+IFS=$as_save_IFS
+
+    at_program_=$as_dir/$at_program ;;
+  esac
+  if test -f "$at_program_"; then
+    {
+      $as_echo "$at_srcdir/DDSTest.at:7: $at_program_ --version"
+      "$at_program_" --version </dev/null
+      echo
+    } >&5 2>&1
+  else
+    as_fn_error "cannot find $at_program" "$LINENO" 5
+  fi
+done
+
+{
+  cat <<\_ASBOX
+## ------------------ ##
+## Running the tests. ##
+## ------------------ ##
+_ASBOX
+} >&5
+
+at_start_date=`date`
+at_start_time=`date +%s 2>/dev/null`
+$as_echo "$as_me: starting at: $at_start_date" >&5
+
+# Create the master directory if it doesn't already exist.
+as_dir="$at_suite_dir"; as_fn_mkdir_p ||
+  as_fn_error "cannot create \`$at_suite_dir'" "$LINENO" 5
+
+# Can we diff with `/dev/null'?  DU 5.0 refuses.
+if diff /dev/null /dev/null >/dev/null 2>&1; then
+  at_devnull=/dev/null
+else
+  at_devnull=$at_suite_dir/devnull
+  >"$at_devnull"
+fi
+
+# Use `diff -u' when possible.
+if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
+then
+  at_diff='diff -u'
+else
+  at_diff=diff
+fi
+
+# Get the last needed group.
+for at_group in : $at_groups; do :; done
+
+# Extract the start and end lines of each test group at the tail
+# of this file
+awk '
+BEGIN { FS="" }
+/^#AT_START_/ {
+  start = NR
+}
+/^#AT_STOP_/ {
+  test = substr ($ 0, 10)
+  print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
+  if (test == "'"$at_group"'") exit
+}' "$at_myself" > "$at_suite_dir/at-source-lines" &&
+. "$at_suite_dir/at-source-lines" ||
+  as_fn_error "cannot create test line number cache" "$LINENO" 5
+rm -f "$at_suite_dir/at-source-lines"
+
+# Set number of jobs for `-j'; avoid more jobs than test groups.
+set X $at_groups; shift; at_max_jobs=$#
+if test $at_max_jobs -eq 0; then
+  at_jobs=1
+fi
+if test $at_jobs -ne 1 &&
+   { test $at_jobs -eq 0 || test $at_jobs -gt $at_max_jobs; }; then
+  at_jobs=$at_max_jobs
+fi
+
+# If parallel mode, don't output banners, don't split summary lines.
+if test $at_jobs -ne 1; then
+  at_print_banners=false
+  at_quiet=:
+fi
+
+# Set up helper dirs.
+rm -rf "$at_helper_dir" &&
+mkdir "$at_helper_dir" &&
+cd "$at_helper_dir" &&
+{ test -z "$at_groups" || mkdir $at_groups; } ||
+as_fn_error "testsuite directory setup failed" "$LINENO" 5
+
+# Functions for running a test group.  We leave the actual
+# test group execution outside of a shell function in order
+# to avoid hitting zsh 4.x exit status bugs.
+
+# at_fn_group_prepare
+# -------------------
+# Prepare running a test group.
+at_fn_group_prepare ()
+{
+  # The directory for additional per-group helper files.
+  at_job_dir=$at_helper_dir/$at_group
+  # The file containing the location of the last AT_CHECK.
+  at_check_line_file=$at_job_dir/check-line
+  # The file containing the exit status of the last command.
+  at_status_file=$at_job_dir/status
+  # The files containing the output of the tested commands.
+  at_stdout=$at_job_dir/stdout
+  at_stder1=$at_job_dir/stder1
+  at_stderr=$at_job_dir/stderr
+  # The file containing the code for a test group.
+  at_test_source=$at_job_dir/test-source
+  # The file containing dates.
+  at_times_file=$at_job_dir/times
+
+  # Be sure to come back to the top test directory.
+  cd "$at_suite_dir"
+
+  # Clearly separate the test groups when verbose.
+  $at_first || $at_verbose echo
+
+  at_group_normalized=$at_group
+
+  eval 'while :; do
+    case $at_group_normalized in #(
+    '"$at_format"'*) break;;
+    esac
+    at_group_normalized=0$at_group_normalized
+  done'
+
+
+  # Create a fresh directory for the next test group, and enter.
+  # If one already exists, the user may have invoked ./run from
+  # within that directory; we remove the contents, but not the
+  # directory itself, so that we aren't pulling the rug out from
+  # under the shell's notion of the current directory.
+  at_group_dir=$at_suite_dir/$at_group_normalized
+  at_group_log=$at_group_dir/$as_me.log
+  if test -d "$at_group_dir"; then
+  find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx {} \;
+  rm -fr "$at_group_dir"/* "$at_group_dir"/.[!.] "$at_group_dir"/.??*
+fi ||
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: test directory for $at_group_normalized could not be cleaned." >&5
+$as_echo "$as_me: WARNING: test directory for $at_group_normalized could not be cleaned." >&2;}
+  # Be tolerant if the above `rm' was not able to remove the directory.
+  as_dir="$at_group_dir"; as_fn_mkdir_p
+
+  echo 0 > "$at_status_file"
+
+  # In verbose mode, append to the log file *and* show on
+  # the standard output; in quiet mode only write to the log.
+  if test -z "$at_verbose"; then
+    at_tee_pipe='tee -a "$at_group_log"'
+  else
+    at_tee_pipe='cat >> "$at_group_log"'
+  fi
+}
+
+# at_fn_group_postprocess
+# -----------------------
+# Perform cleanup after running a test group.
+at_fn_group_postprocess ()
+{
+  # Be sure to come back to the suite directory, in particular
+  # since below we might `rm' the group directory we are in currently.
+  cd "$at_suite_dir"
+
+  if test ! -f "$at_check_line_file"; then
+    sed "s/^ */$as_me: WARNING: /" <<_ATEOF
+      A failure happened in a test group before any test could be
+      run. This means that test suite is improperly designed.  Please
+      report this failure to <opendap-tech at opendap.org>.
+_ATEOF
+    $as_echo "$at_setup_line" >"$at_check_line_file"
+    at_status=99
+  fi
+  $at_verbose $as_echo_n "$at_group. $at_setup_line: "
+  $as_echo_n "$at_group. $at_setup_line: " >> "$at_group_log"
+  case $at_xfail:$at_status in
+    *:99)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	;;
+    yes:0)
+	at_msg="UNEXPECTED PASS"
+	at_res=xpass
+	at_errexit=$at_errexit_p
+	;;
+    no:0)
+	at_msg="ok"
+	at_res=pass
+	at_errexit=false
+	;;
+    *:77)
+	at_msg='skipped ('`cat "$at_check_line_file"`')'
+	at_res=skip
+	at_errexit=false
+	;;
+    yes:*)
+	at_msg='expected failure ('`cat "$at_check_line_file"`')'
+	at_res=xfail
+	at_errexit=false
+	;;
+    no:*)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	;;
+  esac
+  echo "$at_res" > "$at_job_dir/$at_res"
+  # In parallel mode, output the summary line only afterwards.
+  if test $at_jobs -ne 1 && test -n "$at_verbose"; then
+    $as_echo "$at_desc_line $at_msg"
+  else
+    # Make sure there is a separator even with long titles.
+    $as_echo " $at_msg"
+  fi
+  at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
+  case $at_status in
+    0|77)
+      # $at_times_file is only available if the group succeeded.
+      # We're not including the group log, so the success message
+      # is written in the global log separately.  But we also
+      # write to the group log in case they're using -d.
+      if test -f "$at_times_file"; then
+	at_log_msg="$at_log_msg     ("`sed 1d "$at_times_file"`')'
+	rm -f "$at_times_file"
+      fi
+      $as_echo "$at_log_msg" >> "$at_group_log"
+      $as_echo "$at_log_msg" >&5
+
+      # Cleanup the group directory, unless the user wants the files.
+      if $at_debug_p; then
+	at_fn_create_debugging_script
+      else
+	if test -d "$at_group_dir"; then
+	  find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+	  rm -fr "$at_group_dir"
+	fi
+	rm -f "$at_test_source"
+      fi
+      ;;
+    *)
+      # Upon failure, include the log into the testsuite's global
+      # log.  The failure message is written in the group log.  It
+      # is later included in the global log.
+      $as_echo "$at_log_msg" >> "$at_group_log"
+
+      # Upon failure, keep the group directory for autopsy, and create
+      # the debugging script.  With -e, do not start any further tests.
+      at_fn_create_debugging_script
+      if $at_errexit; then
+	echo stop > "$at_stop_file"
+      fi
+      ;;
+  esac
+}
+
+
+## ------------ ##
+## Driver loop. ##
+## ------------ ##
+
+
+if (set -m && set +m && set +b) >/dev/null 2>&1; then
+  set +b
+  at_job_control_on='set -m' at_job_control_off='set +m' at_job_group=-
+else
+  at_job_control_on=: at_job_control_off=: at_job_group=
+fi
+
+for at_signal in 1 2 15; do
+  trap 'set +x; set +e
+	$at_job_control_off
+	at_signal='"$at_signal"'
+	echo stop > "$at_stop_file"
+	trap "" $at_signal
+	at_pgids=
+	for at_pgid in `jobs -p 2>/dev/null`; do
+	  at_pgids="$at_pgids $at_job_group$at_pgid"
+	done
+	test -z "$at_pgids" || kill -$at_signal $at_pgids 2>/dev/null
+	wait
+	if test "$at_jobs" -eq 1 || test -z "$at_verbose"; then
+	  echo >&2
+	fi
+	at_signame=`kill -l $at_signal 2>&1 || echo $at_signal`
+	set x $at_signame
+	test 1 -gt 2 && at_signame=$at_signal
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: caught signal $at_signame, bailing out" >&5
+$as_echo "$as_me: WARNING: caught signal $at_signame, bailing out" >&2;}
+	as_fn_arith 128 + $at_signal && exit_status=$as_val
+	as_fn_exit $exit_status' $at_signal
+done
+
+rm -f "$at_stop_file"
+at_first=:
+
+if test $at_jobs -ne 1 &&
+     rm -f "$at_job_fifo" &&
+     test -n "$at_job_group" &&
+     ( mkfifo "$at_job_fifo" && trap 'exit 1' PIPE STOP TSTP ) 2>/dev/null
+then
+  # FIFO job dispatcher.
+
+  trap 'at_pids=
+	for at_pid in `jobs -p`; do
+	  at_pids="$at_pids $at_job_group$at_pid"
+	done
+	if test -n "$at_pids"; then
+	  at_sig=TSTP
+	  test "${TMOUT+set}" = set && at_sig=STOP
+	  kill -$at_sig $at_pids 2>/dev/null
+	fi
+	kill -STOP $$
+	test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
+
+  echo
+  # Turn jobs into a list of numbers, starting from 1.
+  at_joblist=`$as_echo " $at_groups_all " | \
+    sed 's/\( '$at_jobs'\) .*/\1/'`
+
+  set X $at_joblist
+  shift
+  for at_group in $at_groups; do
+    $at_job_control_on 2>/dev/null
+    (
+      # Start one test group.
+      $at_job_control_off
+      exec 6>"$at_job_fifo"
+      trap 'set +x; set +e
+	    trap "" PIPE
+	    echo stop > "$at_stop_file"
+	    echo token >&6
+	    as_fn_exit 141' PIPE
+      at_fn_group_prepare
+      if cd "$at_group_dir" &&
+	 at_fn_test $at_group &&
+	 . "$at_test_source" # AT_JOB_FIFO_FD>&-
+      then :; else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+	at_failed=:
+      fi
+      at_fn_group_postprocess
+      echo token >&6
+    ) &
+    $at_job_control_off
+    if $at_first; then
+      at_first=false
+      exec 6<"$at_job_fifo"
+    fi
+    shift # Consume one token.
+    if test $# -gt 0; then :; else
+      read at_token <&6 || break
+      set x $*
+    fi
+    test -f "$at_stop_file" && break
+  done
+  # Read back the remaining ($at_jobs - 1) tokens.
+  set X $at_joblist
+  shift
+  if test $# -gt 0; then
+    shift
+    for at_job
+    do
+      read at_token
+    done <&6
+  fi
+  exec 6<&-
+  wait
+else
+  # Run serially, avoid forks and other potential surprises.
+  for at_group in $at_groups; do
+    at_fn_group_prepare
+    if cd "$at_group_dir" &&
+       at_fn_test $at_group &&
+       . "$at_test_source"; then :; else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+      at_failed=:
+    fi
+    at_fn_group_postprocess
+    test -f "$at_stop_file" && break
+    at_first=false
+  done
+fi
+
+# Wrap up the test suite with summary statistics.
+cd "$at_helper_dir"
+
+# Use ?..???? when the list must remain sorted, the faster * otherwise.
+at_pass_list=`for f in */pass; do echo $f; done | sed '/\*/d; s,/pass,,'`
+at_skip_list=`for f in */skip; do echo $f; done | sed '/\*/d; s,/skip,,'`
+at_xfail_list=`for f in */xfail; do echo $f; done | sed '/\*/d; s,/xfail,,'`
+at_xpass_list=`for f in ?/xpass ??/xpass ???/xpass ????/xpass; do
+		 echo $f; done | sed '/?/d; s,/xpass,,'`
+at_fail_list=`for f in ?/fail ??/fail ???/fail ????/fail; do
+		echo $f; done | sed '/?/d; s,/fail,,'`
+
+set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
+shift; at_group_count=$#
+set X $at_xpass_list; shift; at_xpass_count=$#; at_xpass_list=$*
+set X $at_xfail_list; shift; at_xfail_count=$#
+set X $at_fail_list; shift; at_fail_count=$#; at_fail_list=$*
+set X $at_skip_list; shift; at_skip_count=$#
+
+as_fn_arith $at_group_count - $at_skip_count && at_run_count=$as_val
+as_fn_arith $at_xpass_count + $at_fail_count && at_unexpected_count=$as_val
+as_fn_arith $at_xfail_count + $at_fail_count && at_total_fail_count=$as_val
+
+# Back to the top directory.
+cd "$at_dir"
+rm -rf "$at_helper_dir"
+
+# Compute the duration of the suite.
+at_stop_date=`date`
+at_stop_time=`date +%s 2>/dev/null`
+$as_echo "$as_me: ending at: $at_stop_date" >&5
+case $at_start_time,$at_stop_time in
+  [0-9]*,[0-9]*)
+    as_fn_arith $at_stop_time - $at_start_time && at_duration_s=$as_val
+    as_fn_arith $at_duration_s / 60 && at_duration_m=$as_val
+    as_fn_arith $at_duration_m / 60 && at_duration_h=$as_val
+    as_fn_arith $at_duration_s % 60 && at_duration_s=$as_val
+    as_fn_arith $at_duration_m % 60 && at_duration_m=$as_val
+    at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
+    $as_echo "$as_me: test suite duration: $at_duration" >&5
+    ;;
+esac
+
+echo
+cat <<\_ASBOX
+## ------------- ##
+## Test results. ##
+## ------------- ##
+_ASBOX
+echo
+{
+  echo
+  cat <<\_ASBOX
+## ------------- ##
+## Test results. ##
+## ------------- ##
+_ASBOX
+  echo
+} >&5
+
+if test $at_run_count = 1; then
+  at_result="1 test"
+  at_were=was
+else
+  at_result="$at_run_count tests"
+  at_were=were
+fi
+if $at_errexit_p && test $at_unexpected_count != 0; then
+  if test $at_xpass_count = 1; then
+    at_result="$at_result $at_were run, one passed"
+  else
+    at_result="$at_result $at_were run, one failed"
+  fi
+  at_result="$at_result unexpectedly and inhibited subsequent tests."
+else
+  # Don't you just love exponential explosion of the number of cases?
+  case $at_xpass_count:$at_fail_count:$at_xfail_count in
+    # So far, so good.
+    0:0:0) at_result="$at_result $at_were successful." ;;
+    0:0:*) at_result="$at_result behaved as expected." ;;
+
+    # Some unexpected failures
+    0:*:0) at_result="$at_result $at_were run,
+$at_fail_count failed unexpectedly." ;;
+
+    # Some failures, both expected and unexpected
+    0:*:1) at_result="$at_result $at_were run,
+$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
+    0:*:*) at_result="$at_result $at_were run,
+$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
+
+    # No unexpected failures, but some xpasses
+    *:0:*) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly." ;;
+
+    # No expected failures, but failures and xpasses
+    *:1:0) at_result="$at_result $at_were run,
+$at_unexpected_count did not behave as expected ($at_fail_count unexpected failure)." ;;
+    *:*:0) at_result="$at_result $at_were run,
+$at_unexpected_count did not behave as expected ($at_fail_count unexpected failures)." ;;
+
+    # All of them.
+    *:*:1) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly,
+$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
+    *:*:*) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly,
+$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
+  esac
+
+  if test $at_skip_count = 0 && test $at_run_count -gt 1; then
+    at_result="All $at_result"
+  fi
+fi
+
+# Now put skips in the mix.
+case $at_skip_count in
+  0) ;;
+  1) at_result="$at_result
+1 test was skipped." ;;
+  *) at_result="$at_result
+$at_skip_count tests were skipped." ;;
+esac
+
+if test $at_unexpected_count = 0; then
+  echo "$at_result"
+  echo "$at_result" >&5
+else
+  echo "ERROR: $at_result" >&2
+  echo "ERROR: $at_result" >&5
+  {
+    echo
+    cat <<\_ASBOX
+## ------------------------ ##
+## Summary of the failures. ##
+## ------------------------ ##
+_ASBOX
+
+    # Summary of failed and skipped tests.
+    if test $at_fail_count != 0; then
+      echo "Failed tests:"
+      $SHELL "$at_myself" $at_fail_list --list
+      echo
+    fi
+    if test $at_skip_count != 0; then
+      echo "Skipped tests:"
+      $SHELL "$at_myself" $at_skip_list --list
+      echo
+    fi
+    if test $at_xpass_count != 0; then
+      echo "Unexpected passes:"
+      $SHELL "$at_myself" $at_xpass_list --list
+      echo
+    fi
+    if test $at_fail_count != 0; then
+      cat <<\_ASBOX
+## ---------------------- ##
+## Detailed failed tests. ##
+## ---------------------- ##
+_ASBOX
+      echo
+      for at_group in $at_fail_list
+      do
+	at_group_normalized=$at_group
+
+  eval 'while :; do
+    case $at_group_normalized in #(
+    '"$at_format"'*) break;;
+    esac
+    at_group_normalized=0$at_group_normalized
+  done'
+
+	cat "$at_suite_dir/$at_group_normalized/$as_me.log"
+	echo
+      done
+      echo
+    fi
+    if test -n "$at_top_srcdir"; then
+      sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## ${at_top_build_prefix}config.log ##
+_ASBOX
+      sed 's/^/| /' ${at_top_build_prefix}config.log
+      echo
+    fi
+  } >&5
+
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## $as_me.log was created. ##
+_ASBOX
+
+  echo
+  if $at_debug_p; then
+    at_msg='per-test log files'
+  else
+    at_msg="\`${at_testdir+${at_testdir}/}$as_me.log'"
+  fi
+  $as_echo "Please send $at_msg and all information you think might help:
+
+   To: <opendap-tech at opendap.org>
+   Subject: [libdap 3.11.1] $as_me: $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}$at_xpass_list${at_xpass_list:+ passed unexpectedly}
+
+You may investigate any problem if you feel able to do so, in which
+case the test suite provides a good starting point.  Its output may
+be found below \`${at_testdir+${at_testdir}/}$as_me.dir'.
+"
+  exit 1
+fi
+
+exit 0
+
+## ------------- ##
+## Actual tests. ##
+## ------------- ##
+#AT_START_1
+# 1. DDSTest.at:34: DDS $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds
+at_setup_line='DDSTest.at:34'
+at_desc="DDS \$abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds"
+at_desc_line="  1: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "1. DDSTest.at:34: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:34: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds || true" "DDSTest.at:34"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:34"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:34: diff -b -B \$abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base stderr" "DDSTest.at:34"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:34"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_1
+#AT_START_2
+# 2. DDSTest.at:35: DDS $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds
+at_setup_line='DDSTest.at:35'
+at_desc="DDS \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds"
+at_desc_line="  2: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "2. DDSTest.at:35: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:35: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds || true" "DDSTest.at:35"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:35"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:35: diff -b -B \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds.base stderr" "DDSTest.at:35"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.das.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:35"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_2
+#AT_START_3
+# 3. DDSTest.at:36: DDS $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds
+at_setup_line='DDSTest.at:36'
+at_desc="DDS \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds"
+at_desc_line="  3: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "3. DDSTest.at:36: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:36: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds || true" "DDSTest.at:36"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:36"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:36: diff -b -B \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds.base stderr" "DDSTest.at:36"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/3B42.980909.5.HDF.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:36"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_3
+#AT_START_4
+# 4. DDSTest.at:37: DDS $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds
+at_setup_line='DDSTest.at:37'
+at_desc="DDS \$abs_srcdir/dds-testsuite/AsciiOutputTest1.dds"
+at_desc_line="  4: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "4. DDSTest.at:37: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:37: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/AsciiOutputTest1.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds || true" "DDSTest.at:37"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:37"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:37: diff -b -B \$abs_srcdir/dds-testsuite/AsciiOutputTest1.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/AsciiOutputTest1.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds.base stderr" "DDSTest.at:37"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/AsciiOutputTest1.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:37"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_4
+#AT_START_5
+# 5. DDSTest.at:38: DDS $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds
+at_setup_line='DDSTest.at:38'
+at_desc="DDS \$abs_srcdir/dds-testsuite/fnoc1.nc.das.dds"
+at_desc_line="  5: $at_desc "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "5. DDSTest.at:38: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:38: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/fnoc1.nc.das.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds || true" "DDSTest.at:38"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:38"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:38: diff -b -B \$abs_srcdir/dds-testsuite/fnoc1.nc.das.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/fnoc1.nc.das.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds.base stderr" "DDSTest.at:38"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.das.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:38"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_5
+#AT_START_6
+# 6. DDSTest.at:39: DDS $abs_srcdir/dds-testsuite/fnoc1.nc.dds
+at_setup_line='DDSTest.at:39'
+at_desc="DDS \$abs_srcdir/dds-testsuite/fnoc1.nc.dds"
+at_desc_line="  6: $at_desc     "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "6. DDSTest.at:39: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/fnoc1.nc.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:39: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/fnoc1.nc.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/fnoc1.nc.dds || true" "DDSTest.at:39"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/fnoc1.nc.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:39"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:39: diff -b -B \$abs_srcdir/dds-testsuite/fnoc1.nc.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/fnoc1.nc.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.dds.base stderr" "DDSTest.at:39"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/fnoc1.nc.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:39"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_6
+#AT_START_7
+# 7. DDSTest.at:40: DDS $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds
+at_setup_line='DDSTest.at:40'
+at_desc="DDS \$abs_srcdir/dds-testsuite/S2000415.HDF.das.dds"
+at_desc_line="  7: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "7. DDSTest.at:40: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:40: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/S2000415.HDF.das.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds || true" "DDSTest.at:40"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:40"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:40: diff -b -B \$abs_srcdir/dds-testsuite/S2000415.HDF.das.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/S2000415.HDF.das.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds.base stderr" "DDSTest.at:40"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.das.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:40"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_7
+#AT_START_8
+# 8. DDSTest.at:41: DDS $abs_srcdir/dds-testsuite/S2000415.HDF.dds
+at_setup_line='DDSTest.at:41'
+at_desc="DDS \$abs_srcdir/dds-testsuite/S2000415.HDF.dds"
+at_desc_line="  8: $at_desc "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "8. DDSTest.at:41: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/S2000415.HDF.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:41: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/S2000415.HDF.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/S2000415.HDF.dds || true" "DDSTest.at:41"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/S2000415.HDF.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:41"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:41: diff -b -B \$abs_srcdir/dds-testsuite/S2000415.HDF.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/S2000415.HDF.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.dds.base stderr" "DDSTest.at:41"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/S2000415.HDF.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:41"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_8
+#AT_START_9
+# 9. DDSTest.at:42: DDS $abs_srcdir/dds-testsuite/test.1.dds
+at_setup_line='DDSTest.at:42'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.1.dds"
+at_desc_line="  9: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "9. DDSTest.at:42: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.1.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:42: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.1.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.1.dds || true" "DDSTest.at:42"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.1.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:42"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:42: diff -b -B \$abs_srcdir/dds-testsuite/test.1.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.1.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.1.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.1.dds.base stderr" "DDSTest.at:42"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.1.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.1.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:42"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_9
+#AT_START_10
+# 10. DDSTest.at:43: DDS $abs_srcdir/dds-testsuite/test.10.dds
+at_setup_line='DDSTest.at:43'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.10.dds"
+at_desc_line=" 10: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "10. DDSTest.at:43: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.10.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:43: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.10.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.10.dds || true" "DDSTest.at:43"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.10.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:43"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:43: diff -b -B \$abs_srcdir/dds-testsuite/test.10.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.10.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.10.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.10.dds.base stderr" "DDSTest.at:43"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.10.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.10.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:43"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_10
+#AT_START_11
+# 11. DDSTest.at:44: DDS $abs_srcdir/dds-testsuite/test.11.dds
+at_setup_line='DDSTest.at:44'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.11.dds"
+at_desc_line=" 11: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "11. DDSTest.at:44: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.11.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:44: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.11.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.11.dds || true" "DDSTest.at:44"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.11.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:44"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:44: diff -b -B \$abs_srcdir/dds-testsuite/test.11.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.11.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.11.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.11.dds.base stderr" "DDSTest.at:44"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.11.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.11.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:44"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_11
+#AT_START_12
+# 12. DDSTest.at:45: DDS $abs_srcdir/dds-testsuite/test.12.dds
+at_setup_line='DDSTest.at:45'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.12.dds"
+at_desc_line=" 12: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "12. DDSTest.at:45: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.12.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:45: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.12.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.12.dds || true" "DDSTest.at:45"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.12.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:45: diff -b -B \$abs_srcdir/dds-testsuite/test.12.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.12.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.12.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.12.dds.base stderr" "DDSTest.at:45"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.12.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.12.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_12
+#AT_START_13
+# 13. DDSTest.at:46: DDS $abs_srcdir/dds-testsuite/test.13.dds
+at_setup_line='DDSTest.at:46'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.13.dds"
+at_desc_line=" 13: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "13. DDSTest.at:46: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.13.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:46: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.13.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.13.dds || true" "DDSTest.at:46"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.13.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:46: diff -b -B \$abs_srcdir/dds-testsuite/test.13.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.13.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.13.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.13.dds.base stderr" "DDSTest.at:46"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.13.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.13.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_13
+#AT_START_14
+# 14. DDSTest.at:47: DDS $abs_srcdir/dds-testsuite/test.14.dds
+at_setup_line='DDSTest.at:47'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.14.dds"
+at_desc_line=" 14: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "14. DDSTest.at:47: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.14.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:47: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.14.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.14.dds || true" "DDSTest.at:47"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.14.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:47: diff -b -B \$abs_srcdir/dds-testsuite/test.14.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.14.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.14.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.14.dds.base stderr" "DDSTest.at:47"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.14.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.14.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_14
+#AT_START_15
+# 15. DDSTest.at:48: DDS $abs_srcdir/dds-testsuite/test.15.dds
+at_setup_line='DDSTest.at:48'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.15.dds"
+at_desc_line=" 15: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "15. DDSTest.at:48: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.15.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:48: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.15.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.15.dds || true" "DDSTest.at:48"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.15.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:48: diff -b -B \$abs_srcdir/dds-testsuite/test.15.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.15.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.15.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.15.dds.base stderr" "DDSTest.at:48"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.15.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.15.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_15
+#AT_START_16
+# 16. DDSTest.at:49: DDS $abs_srcdir/dds-testsuite/test.16.dds
+at_setup_line='DDSTest.at:49'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.16.dds"
+at_desc_line=" 16: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "16. DDSTest.at:49: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.16.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:49: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.16.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.16.dds || true" "DDSTest.at:49"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.16.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:49: diff -b -B \$abs_srcdir/dds-testsuite/test.16.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.16.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.16.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.16.dds.base stderr" "DDSTest.at:49"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.16.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.16.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_16
+#AT_START_17
+# 17. DDSTest.at:50: DDS $abs_srcdir/dds-testsuite/test.17.dds
+at_setup_line='DDSTest.at:50'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.17.dds"
+at_desc_line=" 17: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "17. DDSTest.at:50: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.17.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:50: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.17.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.17.dds || true" "DDSTest.at:50"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.17.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:50: diff -b -B \$abs_srcdir/dds-testsuite/test.17.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.17.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.17.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.17.dds.base stderr" "DDSTest.at:50"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.17.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.17.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_17
+#AT_START_18
+# 18. DDSTest.at:51: DDS $abs_srcdir/dds-testsuite/test.18.dds
+at_setup_line='DDSTest.at:51'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.18.dds"
+at_desc_line=" 18: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "18. DDSTest.at:51: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.18.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:51: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.18.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.18.dds || true" "DDSTest.at:51"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.18.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:51: diff -b -B \$abs_srcdir/dds-testsuite/test.18.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.18.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.18.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.18.dds.base stderr" "DDSTest.at:51"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.18.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.18.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_18
+#AT_START_19
+# 19. DDSTest.at:52: DDS $abs_srcdir/dds-testsuite/test.19.dds
+at_setup_line='DDSTest.at:52'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.19.dds"
+at_desc_line=" 19: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "19. DDSTest.at:52: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.19.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:52: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.19.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.19.dds || true" "DDSTest.at:52"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.19.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:52: diff -b -B \$abs_srcdir/dds-testsuite/test.19.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.19.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.19.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.19.dds.base stderr" "DDSTest.at:52"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.19.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.19.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_19
+#AT_START_20
+# 20. DDSTest.at:53: DDS $abs_srcdir/dds-testsuite/test.19b.das.dds
+at_setup_line='DDSTest.at:53'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.19b.das.dds"
+at_desc_line=" 20: $at_desc "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "20. DDSTest.at:53: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.19b.das.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:53: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.19b.das.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.19b.das.dds || true" "DDSTest.at:53"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.19b.das.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:53"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:53: diff -b -B \$abs_srcdir/dds-testsuite/test.19b.das.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.19b.das.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.19b.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.19b.das.dds.base stderr" "DDSTest.at:53"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.19b.das.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.19b.das.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:53"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_20
+#AT_START_21
+# 21. DDSTest.at:54: DDS $abs_srcdir/dds-testsuite/test.19b.dds
+at_setup_line='DDSTest.at:54'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.19b.dds"
+at_desc_line=" 21: $at_desc     "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "21. DDSTest.at:54: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.19b.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:54: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.19b.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.19b.dds || true" "DDSTest.at:54"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.19b.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:54: diff -b -B \$abs_srcdir/dds-testsuite/test.19b.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.19b.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.19b.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.19b.dds.base stderr" "DDSTest.at:54"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.19b.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.19b.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_21
+#AT_START_22
+# 22. DDSTest.at:55: DDS $abs_srcdir/dds-testsuite/test.2.dds
+at_setup_line='DDSTest.at:55'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.2.dds"
+at_desc_line=" 22: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "22. DDSTest.at:55: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.2.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:55: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.2.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.2.dds || true" "DDSTest.at:55"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.2.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:55: diff -b -B \$abs_srcdir/dds-testsuite/test.2.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.2.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.2.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.2.dds.base stderr" "DDSTest.at:55"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.2.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.2.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_22
+#AT_START_23
+# 23. DDSTest.at:56: DDS $abs_srcdir/dds-testsuite/test.20.dds
+at_setup_line='DDSTest.at:56'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.20.dds"
+at_desc_line=" 23: $at_desc      "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "23. DDSTest.at:56: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.20.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:56: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.20.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.20.dds || true" "DDSTest.at:56"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.20.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:56"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:56: diff -b -B \$abs_srcdir/dds-testsuite/test.20.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.20.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.20.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.20.dds.base stderr" "DDSTest.at:56"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.20.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.20.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:56"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_23
+#AT_START_24
+# 24. DDSTest.at:57: DDS $abs_srcdir/dds-testsuite/test.3.dds
+at_setup_line='DDSTest.at:57'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.3.dds"
+at_desc_line=" 24: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "24. DDSTest.at:57: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.3.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:57: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.3.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.3.dds || true" "DDSTest.at:57"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.3.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:57: diff -b -B \$abs_srcdir/dds-testsuite/test.3.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.3.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.3.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.3.dds.base stderr" "DDSTest.at:57"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.3.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.3.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_24
+#AT_START_25
+# 25. DDSTest.at:58: DDS $abs_srcdir/dds-testsuite/test.4.dds
+at_setup_line='DDSTest.at:58'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.4.dds"
+at_desc_line=" 25: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "25. DDSTest.at:58: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.4.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:58: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.4.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.4.dds || true" "DDSTest.at:58"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.4.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:58: diff -b -B \$abs_srcdir/dds-testsuite/test.4.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.4.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.4.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.4.dds.base stderr" "DDSTest.at:58"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.4.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.4.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_25
+#AT_START_26
+# 26. DDSTest.at:59: DDS $abs_srcdir/dds-testsuite/test.6.dds
+at_setup_line='DDSTest.at:59'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.6.dds"
+at_desc_line=" 26: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "26. DDSTest.at:59: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.6.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:59: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.6.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.6.dds || true" "DDSTest.at:59"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.6.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:59: diff -b -B \$abs_srcdir/dds-testsuite/test.6.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.6.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.6.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.6.dds.base stderr" "DDSTest.at:59"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.6.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.6.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_26
+#AT_START_27
+# 27. DDSTest.at:60: DDS $abs_srcdir/dds-testsuite/test.7.dds
+at_setup_line='DDSTest.at:60'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.7.dds"
+at_desc_line=" 27: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "27. DDSTest.at:60: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.7.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:60: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.7.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.7.dds || true" "DDSTest.at:60"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.7.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:60"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:60: diff -b -B \$abs_srcdir/dds-testsuite/test.7.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.7.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.7.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.7.dds.base stderr" "DDSTest.at:60"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.7.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.7.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:60"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_27
+#AT_START_28
+# 28. DDSTest.at:61: DDS $abs_srcdir/dds-testsuite/test.8.dds
+at_setup_line='DDSTest.at:61'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.8.dds"
+at_desc_line=" 28: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "28. DDSTest.at:61: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.8.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:61: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.8.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.8.dds || true" "DDSTest.at:61"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.8.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:61: diff -b -B \$abs_srcdir/dds-testsuite/test.8.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.8.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.8.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.8.dds.base stderr" "DDSTest.at:61"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.8.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.8.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_28
+#AT_START_29
+# 29. DDSTest.at:62: DDS $abs_srcdir/dds-testsuite/test.9.dds
+at_setup_line='DDSTest.at:62'
+at_desc="DDS \$abs_srcdir/dds-testsuite/test.9.dds"
+at_desc_line=" 29: $at_desc       "
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "29. DDSTest.at:62: testing ..."
+  $at_traceon
+
+
+#Added || true because the $abs_srcdir/dds-test -p < $abs_srcdir/dds-testsuite/test.9.dds needs to be true whether the
+#output is printed to stdout or stderr
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:62: \$abs_builddir/dds-test -p < \$abs_srcdir/dds-testsuite/test.9.dds || true"
+at_fn_check_prepare_dynamic "$abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.9.dds || true" "DDSTest.at:62"
+( $at_check_trace; $abs_builddir/dds-test -p < $abs_srcdir/dds-testsuite/test.9.dds || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+{ set +x
+$as_echo "$at_srcdir/DDSTest.at:62: diff -b -B \$abs_srcdir/dds-testsuite/test.9.dds.base stdout || diff -b -B \$abs_srcdir/dds-testsuite/test.9.dds.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/dds-testsuite/test.9.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.9.dds.base stderr" "DDSTest.at:62"
+( $at_check_trace; diff -b -B $abs_srcdir/dds-testsuite/test.9.dds.base stdout || diff -b -B $abs_srcdir/dds-testsuite/test.9.dds.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/DDSTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+  set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_29
diff --git a/tests/DDSTest.at b/tests/DDSTest.at
new file mode 100644
index 0000000..383a595
--- /dev/null
+++ b/tests/DDSTest.at
@@ -0,0 +1,63 @@
+# Process with autom4te to create an -*- Autotest -*- test suite.
+
+
+# ------------------------------
+#
+
+AT_INIT([dds-test])
+# AT_COPYRIGHT([])
+
+#AT_TESTED([dds-test])
+
+# Usage: _AT_TEST_*(<dds source>, <baseline file>)
+
+m4_define([_AT_DDS_TEST],   
+[
+# AT_BANNER([Test $1 $2])
+AT_SETUP([DDS $1])
+AT_KEYWORDS([dds])
+#Added || true because the $abs_srcdir/dds-test -p < $1 needs to be true whether the
+#output is printed to stdout or stderr
+AT_CHECK([$abs_builddir/dds-test -p < $1 || true], [], [stdout], [stderr])
+#Need to compare either stdout or stderr because of the directory the above
+#AT_CHECK prints output to
+AT_CHECK([diff -b -B $2 stdout || diff -b -B $2 stderr], [], [ignore],[],[])
+AT_CLEANUP])
+
+m4_define([AT_DDS_RESPONSE_TEST],
+[
+# AT_BANNER([DDS response for $1.])
+_AT_DDS_TEST([$abs_srcdir/dds-testsuite/$1], [$abs_srcdir/dds-testsuite/$1.base])
+])
+
+
+AT_DDS_RESPONSE_TEST([3B42.980909.5.hacked.HDF.das.dds])
+AT_DDS_RESPONSE_TEST([3B42.980909.5.HDF.das.dds])
+AT_DDS_RESPONSE_TEST([3B42.980909.5.HDF.dds])
+AT_DDS_RESPONSE_TEST([AsciiOutputTest1.dds])
+AT_DDS_RESPONSE_TEST([fnoc1.nc.das.dds])
+AT_DDS_RESPONSE_TEST([fnoc1.nc.dds])
+AT_DDS_RESPONSE_TEST([S2000415.HDF.das.dds])
+AT_DDS_RESPONSE_TEST([S2000415.HDF.dds])
+AT_DDS_RESPONSE_TEST([test.1.dds])
+AT_DDS_RESPONSE_TEST([test.10.dds])
+AT_DDS_RESPONSE_TEST([test.11.dds])
+AT_DDS_RESPONSE_TEST([test.12.dds])
+AT_DDS_RESPONSE_TEST([test.13.dds])
+AT_DDS_RESPONSE_TEST([test.14.dds])
+AT_DDS_RESPONSE_TEST([test.15.dds])
+AT_DDS_RESPONSE_TEST([test.16.dds])
+AT_DDS_RESPONSE_TEST([test.17.dds])
+AT_DDS_RESPONSE_TEST([test.18.dds])
+AT_DDS_RESPONSE_TEST([test.19.dds])
+AT_DDS_RESPONSE_TEST([test.19b.das.dds])
+AT_DDS_RESPONSE_TEST([test.19b.dds])
+AT_DDS_RESPONSE_TEST([test.2.dds])
+AT_DDS_RESPONSE_TEST([test.20.dds])
+AT_DDS_RESPONSE_TEST([test.3.dds])
+AT_DDS_RESPONSE_TEST([test.4.dds])
+AT_DDS_RESPONSE_TEST([test.6.dds])
+AT_DDS_RESPONSE_TEST([test.7.dds])
+AT_DDS_RESPONSE_TEST([test.8.dds])
+AT_DDS_RESPONSE_TEST([test.9.dds])
+
diff --git a/tests/EXPRTest b/tests/EXPRTest
new file mode 100755
index 0000000..ed07660
--- /dev/null
+++ b/tests/EXPRTest
@@ -0,0 +1,8644 @@
+#! /bin/sh
+# Generated from EXPRTest.at by GNU Autoconf 2.65.
+#
+# Copyright (C) 2009 Free Software Foundation, Inc.
+#
+# This test suite is free software; the Free Software Foundation gives
+# unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='print -r --'
+  as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+  as_echo='printf %s\n'
+  as_echo_n='printf %s'
+else
+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+    as_echo_n='/usr/ucb/echo -n'
+  else
+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+    as_echo_n_body='eval
+      arg=$1;
+      case $arg in #(
+      *"$as_nl"*)
+	expr "X$arg" : "X\\(.*\\)$as_nl";
+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+      esac;
+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+    '
+    export as_echo_n_body
+    as_echo_n='sh -c $as_echo_n_body as_echo'
+  fi
+  export as_echo_body
+  as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  PATH_SEPARATOR=:
+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+      PATH_SEPARATOR=';'
+  }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.  Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" ""	$as_nl"
+
+# Find who we are.  Look in the path if we contain no directory separator.
+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
+IFS=$as_save_IFS
+
+     ;;
+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
+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there.  '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  emulate sh
+  NULLCMD=:
+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '\${1+\"\$@\"}'='\"\$@\"'
+  setopt NO_GLOB_SUBST
+else
+  case \`(set -o) 2>/dev/null\` in #(
+  *posix*) :
+    set -o posix ;; #(
+  *) :
+     ;;
+esac
+fi
+"
+  as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+  exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+  if (eval "$as_required") 2>/dev/null; then :
+  as_have_required=yes
+else
+  as_have_required=no
+fi
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  as_found=:
+  case $as_dir in #(
+	 /*)
+	   for as_base in sh bash ksh sh5; do
+	     # Try only shells that exist, to save several forks.
+	     as_shell=$as_dir/$as_base
+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  CONFIG_SHELL=$as_shell as_have_required=yes
+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+  break 2
+fi
+fi
+	   done;;
+       esac
+  as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+      if test "x$CONFIG_SHELL" != x; then :
+  # We cannot yet assume a decent shell, so we have to provide a
+	# neutralization value for shells without unset; and this also
+	# works around shells that cannot unset nonexistent variables.
+	BASH_ENV=/dev/null
+	ENV=/dev/null
+	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+	export CONFIG_SHELL
+	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+    if test x$as_have_required = xno; then :
+  $as_echo "$0: This script requires a shell more modern than all"
+  $as_echo "$0: the shells that I found on your system."
+  if test x${ZSH_VERSION+set} = xset ; then
+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+  else
+    $as_echo "$0: Please tell bug-autoconf at gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+  fi
+  exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+  { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+  return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+  set +e
+  as_fn_set_status $1
+  exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+  case $as_dir in #(
+  -*) as_dir=./$as_dir;;
+  esac
+  test -d "$as_dir" || eval $as_mkdir_p || {
+    as_dirs=
+    while :; do
+      case $as_dir in #(
+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *) as_qdir=$as_dir;;
+      esac
+      as_dirs="'$as_qdir' $as_dirs"
+      as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+      test -d "$as_dir" && break
+    done
+    test -z "$as_dirs" || eval "mkdir $as_dirs"
+  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+  eval 'as_fn_append ()
+  {
+    eval $1+=\$2
+  }'
+else
+  as_fn_append ()
+  {
+    eval $1=\$$1\$2
+  }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+  eval 'as_fn_arith ()
+  {
+    as_val=$(( $* ))
+  }'
+else
+  as_fn_arith ()
+  {
+    as_val=`expr "$@" || test $? -eq 1`
+  }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+  as_status=$?; test $as_status -eq 0 && as_status=1
+  if test "$3"; then
+    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  fi
+  $as_echo "$as_me: error: $1" >&2
+  as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+   test "X`expr 00001 : '.*\(...\)'`" = X001; 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
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\/\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+  as_dirname=dirname
+else
+  as_dirname=false
+fi
+
+# 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
+
+
+  as_lineno_1=$LINENO as_lineno_1a=$LINENO
+  as_lineno_2=$LINENO as_lineno_2a=$LINENO
+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)
+  sed -n '
+    p
+    /[$]LINENO/=
+  ' <$as_myself |
+    sed '
+      s/[$]LINENO.*/&-/
+      t lineno
+      b
+      :lineno
+      N
+      :loop
+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+      t loop
+      s/-\n.*//
+    ' >$as_me.lineno &&
+  chmod +x "$as_me.lineno" ||
+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_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 sensitive to this).
+  . "./$as_me.lineno"
+  # Exit status is that of the last command.
+  exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+  case `echo 'xy\c'` in
+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.
+  xy)  ECHO_C='\c';;
+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null
+       ECHO_T='	';;
+  esac;;
+*)
+  ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+  rm -f conf$$.dir/conf$$.file
+else
+  rm -f conf$$.dir
+  mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+  if ln -s conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s='ln -s'
+    # ... but there are two gotchas:
+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+    # In both cases, we have to default to `cp -p'.
+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+      as_ln_s='cp -p'
+  elif ln conf$$.file conf$$ 2>/dev/null; then
+    as_ln_s=ln
+  else
+    as_ln_s='cp -p'
+  fi
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p='mkdir -p "$as_dir"'
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+  as_test_x='test -x'
+else
+  if ls -dL / >/dev/null 2>&1; then
+    as_ls_L_option=L
+  else
+    as_ls_L_option=
+  fi
+  as_test_x='
+    eval sh -c '\''
+      if test -d "$1"; then
+	test -d "$1/.";
+      else
+	case $1 in #(
+	-*)set "./$1";;
+	esac;
+	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+	???[sx]*):;;*)false;;esac;fi
+    '\'' sh
+  '
+fi
+as_executable_p=$as_test_x
+
+# 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'"
+
+
+
+
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# How were we run?
+at_cli_args="$@"
+
+
+# Not all shells have the 'times' builtin; the subshell is needed to make
+# sure we discard the 'times: not found' message from the shell.
+at_times_p=false
+(times) >/dev/null 2>&1 && at_times_p=:
+
+# CLI Arguments to pass to the debugging scripts.
+at_debug_args=
+# -e sets to true
+at_errexit_p=false
+# Shall we be verbose?  ':' means no, empty means yes.
+at_verbose=:
+at_quiet=
+# Running several jobs in parallel, 0 means as many as test groups.
+at_jobs=1
+at_traceon=:
+at_trace_echo=:
+at_check_filter_trace=:
+
+# Shall we keep the debug scripts?  Must be `:' when the suite is
+# run by a debug script, so that the script doesn't remove itself.
+at_debug_p=false
+# Display help message?
+at_help_p=false
+# Display the version message?
+at_version_p=false
+# List test groups?
+at_list_p=false
+# --clean
+at_clean=false
+# Test groups to run
+at_groups=
+# Whether a write failure occurred
+at_write_fail=0
+
+# The directory we run the suite in.  Default to . if no -C option.
+at_dir=`pwd`
+# An absolute reference to this testsuite script.
+case $as_myself in
+  [\\/]* | ?:[\\/]* ) at_myself=$as_myself ;;
+  * ) at_myself=$at_dir/$as_myself ;;
+esac
+# Whether -C is in effect.
+at_change_dir=false
+
+# List of the tested programs.
+at_tested=''
+# List of the all the test groups.
+at_groups_all=' 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 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 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122'
+# As many question marks as there are digits in the last test group number.
+# Used to normalize the test group numbers so that `ls' lists them in
+# numerical order.
+at_format='???'
+# Description of all the test groups.
+at_help_all="1;EXPRTest.at:45;expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k i (pass);expr;
+2;EXPRTest.at:45;expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k i (pass);expr;
+3;EXPRTest.at:46;expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k i,j (pass);expr;
+4;EXPRTest.at:46;expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k i,j (pass);expr;
+5;EXPRTest.at:47;expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' (pass);expr;
+6;EXPRTest.at:47;expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' (pass);expr;
+7;EXPRTest.at:48;expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' (pass);expr;
+8;EXPRTest.at:48;expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' (pass);expr;
+9;EXPRTest.at:49;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s1 (pass);expr;
+10;EXPRTest.at:49;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s1 (pass);expr;
+11;EXPRTest.at:50;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2 (pass);expr;
+12;EXPRTest.at:50;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2 (pass);expr;
+13;EXPRTest.at:51;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2,s3 (pass);expr;
+14;EXPRTest.at:51;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2,s3 (pass);expr;
+15;EXPRTest.at:52;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o (pass);expr;
+16;EXPRTest.at:52;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o (pass);expr;
+17;EXPRTest.at:54;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m (pass);expr;
+18;EXPRTest.at:54;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m (pass);expr;
+19;EXPRTest.at:55;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l (pass);expr;
+20;EXPRTest.at:55;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l (pass);expr;
+21;EXPRTest.at:57;expr-test -w \$abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] (pass);expr;
+22;EXPRTest.at:57;expr-test -W \$abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] (pass);expr;
+23;EXPRTest.at:58;expr-test -w \$abs_srcdir/expr-testsuite/test.3 -k i[1:10] (pass);expr;
+24;EXPRTest.at:58;expr-test -W \$abs_srcdir/expr-testsuite/test.3 -k i[1:10] (pass);expr;
+25;EXPRTest.at:59;expr-test -w \$abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' (pass);expr;
+26;EXPRTest.at:59;expr-test -W \$abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' (pass);expr;
+27;EXPRTest.at:61;expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass);expr;
+28;EXPRTest.at:61;expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass);expr;
+29;EXPRTest.at:62;expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass);expr;
+30;EXPRTest.at:62;expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass);expr;
+31;EXPRTest.at:63;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass);expr;
+32;EXPRTest.at:63;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass);expr;
+33;EXPRTest.at:64;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass);expr;
+34;EXPRTest.at:64;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass);expr;
+35;EXPRTest.at:65;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i (pass);expr;
+36;EXPRTest.at:65;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i (pass);expr;
+37;EXPRTest.at:66;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass);expr;
+38;EXPRTest.at:66;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass);expr;
+39;EXPRTest.at:67;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass);expr;
+40;EXPRTest.at:67;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass);expr;
+41;EXPRTest.at:68;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass);expr;
+42;EXPRTest.at:68;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass);expr;
+43;EXPRTest.at:69;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass);expr;
+44;EXPRTest.at:69;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass);expr;
+45;EXPRTest.at:70;expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass);expr;
+46;EXPRTest.at:70;expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass);expr;
+47;EXPRTest.at:71;expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass);expr;
+48;EXPRTest.at:71;expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass);expr;
+49;EXPRTest.at:72;expr-test -w \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass);expr;
+50;EXPRTest.at:72;expr-test -W \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass);expr;
+51;EXPRTest.at:73;expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass);expr;
+52;EXPRTest.at:73;expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass);expr;
+53;EXPRTest.at:74;expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass);expr;
+54;EXPRTest.at:74;expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass);expr;
+55;EXPRTest.at:75;expr-test -w \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" (pass);expr;
+56;EXPRTest.at:75;expr-test -W \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" (pass);expr;
+57;EXPRTest.at:76;expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass);expr;
+58;EXPRTest.at:76;expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass);expr;
+59;EXPRTest.at:77;expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass);expr;
+60;EXPRTest.at:77;expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass);expr;
+61;EXPRTest.at:78;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass);expr;
+62;EXPRTest.at:78;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass);expr;
+63;EXPRTest.at:79;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass);expr;
+64;EXPRTest.at:79;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass);expr;
+65;EXPRTest.at:80;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass);expr;
+66;EXPRTest.at:80;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass);expr;
+67;EXPRTest.at:81;expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass);expr;
+68;EXPRTest.at:81;expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass);expr;
+69;EXPRTest.at:82;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass);expr;
+70;EXPRTest.at:82;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass);expr;
+71;EXPRTest.at:83;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass);expr;
+72;EXPRTest.at:83;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass);expr;
+73;EXPRTest.at:84;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass);expr;
+74;EXPRTest.at:84;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass);expr;
+75;EXPRTest.at:85;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass);expr;
+76;EXPRTest.at:85;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass);expr;
+77;EXPRTest.at:86;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass);expr;
+78;EXPRTest.at:86;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass);expr;
+79;EXPRTest.at:87;expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass);expr;
+80;EXPRTest.at:87;expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass);expr;
+81;EXPRTest.at:88;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass);expr;
+82;EXPRTest.at:88;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass);expr;
+83;EXPRTest.at:89;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass);expr;
+84;EXPRTest.at:89;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass);expr;
+85;EXPRTest.at:90;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass);expr;
+86;EXPRTest.at:90;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass);expr;
+87;EXPRTest.at:91;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass);expr;
+88;EXPRTest.at:91;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass);expr;
+89;EXPRTest.at:92;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass);expr;
+90;EXPRTest.at:92;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass);expr;
+91;EXPRTest.at:93;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass);expr;
+92;EXPRTest.at:93;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass);expr;
+93;EXPRTest.at:94;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass);expr;
+94;EXPRTest.at:94;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass);expr;
+95;EXPRTest.at:95;expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass);expr;
+96;EXPRTest.at:95;expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass);expr;
+97;EXPRTest.at:97;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k i (pass);expr;
+98;EXPRTest.at:97;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k i (pass);expr;
+99;EXPRTest.at:98;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass);expr;
+100;EXPRTest.at:98;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass);expr;
+101;EXPRTest.at:99;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass);expr;
+102;EXPRTest.at:99;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass);expr;
+103;EXPRTest.at:100;expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass);expr;
+104;EXPRTest.at:100;expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass);expr;
+105;EXPRTest.at:101;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" (pass);expr;
+106;EXPRTest.at:101;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" (pass);expr;
+107;EXPRTest.at:102;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass);expr;
+108;EXPRTest.at:102;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass);expr;
+109;EXPRTest.at:104;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+110;EXPRTest.at:104;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+111;EXPRTest.at:105;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+112;EXPRTest.at:105;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+113;EXPRTest.at:106;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+114;EXPRTest.at:106;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+115;EXPRTest.at:107;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass);expr;
+116;EXPRTest.at:107;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass);expr;
+117;EXPRTest.at:108;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+118;EXPRTest.at:108;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" (pass);expr;
+119;EXPRTest.at:109;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass);expr;
+120;EXPRTest.at:109;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass);expr;
+121;EXPRTest.at:110;expr-test -b -w \$abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" (pass);expr;
+122;EXPRTest.at:110;expr-test -b -W \$abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" (pass);expr;
+"
+
+# at_fn_validate_ranges NAME...
+# -----------------------------
+# Validate and normalize the test group number contained in each variable
+# NAME. Leading zeroes are treated as decimal.
+at_fn_validate_ranges ()
+{
+  for at_grp
+  do
+    eval at_value=\$$at_grp
+    if test $at_value -lt 1 || test $at_value -gt 122; then
+      $as_echo "invalid test group: $at_value" >&2
+      exit 1
+    fi
+    case $at_value in
+      0*) # We want to treat leading 0 as decimal, like expr and test, but
+	  # AS_VAR_ARITH treats it as octal if it uses $(( )).
+	  # With XSI shells, ${at_value#${at_value%%[1-9]*}} avoids the
+	  # expr fork, but it is not worth the effort to determine if the
+	  # shell supports XSI when the user can just avoid leading 0.
+	  eval $at_grp='`expr $at_value + 0`' ;;
+    esac
+  done
+}
+
+at_prev=
+for at_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$at_prev"; then
+    at_option=$at_prev=$at_option
+    at_prev=
+  fi
+
+  case $at_option in
+  *=*) at_optarg=`expr "x$at_option" : 'x[^=]*=\(.*\)'` ;;
+  *)   at_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $at_option in
+    --help | -h )
+	at_help_p=:
+	;;
+
+    --list | -l )
+	at_list_p=:
+	;;
+
+    --version | -V )
+	at_version_p=:
+	;;
+
+    --clean | -c )
+	at_clean=:
+	;;
+
+    --debug | -d )
+	at_debug_p=:
+	;;
+
+    --errexit | -e )
+	at_debug_p=:
+	at_errexit_p=:
+	;;
+
+    --verbose | -v )
+	at_verbose=; at_quiet=:
+	;;
+
+    --trace | -x )
+	at_traceon='set -x'
+	at_trace_echo=echo
+	at_check_filter_trace=at_fn_filter_trace
+	;;
+
+    [0-9] | [0-9][0-9] | [0-9][0-9][0-9] | [0-9][0-9][0-9][0-9])
+	at_fn_validate_ranges at_option
+	as_fn_append at_groups "$at_option "
+	;;
+
+    # Ranges
+    [0-9]- | [0-9][0-9]- | [0-9][0-9][0-9]- | [0-9][0-9][0-9][0-9]-)
+	at_range_start=`echo $at_option |tr -d X-`
+	at_fn_validate_ranges at_range_start
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/^.* \('$at_range_start' \)/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    -[0-9] | -[0-9][0-9] | -[0-9][0-9][0-9] | -[0-9][0-9][0-9][0-9])
+	at_range_end=`echo $at_option |tr -d X-`
+	at_fn_validate_ranges at_range_end
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/\( '$at_range_end'\) .*$/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    [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] | \
+    [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][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] )
+	at_range_start=`expr $at_option : '\(.*\)-'`
+	at_range_end=`expr $at_option : '.*-\(.*\)'`
+	if test $at_range_start -gt $at_range_end; then
+	  at_tmp=$at_range_end
+	  at_range_end=$at_range_start
+	  at_range_start=$at_tmp
+	fi
+	at_fn_validate_ranges at_range_start at_range_end
+	at_range=`$as_echo " $at_groups_all " | \
+	  sed -e 's/^.*\( '$at_range_start' \)/\1/' \
+	      -e 's/\( '$at_range_end'\) .*$/\1/'`
+	as_fn_append at_groups "$at_range "
+	;;
+
+    # Directory selection.
+    --directory | -C )
+	at_prev=--directory
+	;;
+    --directory=* )
+	at_change_dir=:
+	at_dir=$at_optarg
+	;;
+
+    # Parallel execution.
+    --jobs | -j )
+	at_jobs=0
+	;;
+    --jobs=* | -j[0-9]* )
+	if test -n "$at_optarg"; then
+	  at_jobs=$at_optarg
+	else
+	  at_jobs=`expr X$at_option : 'X-j\(.*\)'`
+	fi
+	case $at_jobs in *[!0-9]*)
+	  at_optname=`echo " $at_option" | sed 's/^ //; s/[0-9=].*//'`
+	  as_fn_error "non-numeric argument to $at_optname: $at_jobs" ;;
+	esac
+	;;
+
+    # Keywords.
+    --keywords | -k )
+	at_prev=--keywords
+	;;
+    --keywords=* )
+	at_groups_selected=$at_help_all
+	at_save_IFS=$IFS
+	IFS=,
+	set X $at_optarg
+	shift
+	IFS=$at_save_IFS
+	for at_keyword
+	do
+	  at_invert=
+	  case $at_keyword in
+	  '!'*)
+	    at_invert="-v"
+	    at_keyword=`expr "X$at_keyword" : 'X!\(.*\)'`
+	    ;;
+	  esac
+	  # It is on purpose that we match the test group titles too.
+	  at_groups_selected=`$as_echo "$at_groups_selected" |
+	      grep -i $at_invert "^[1-9][^;]*;.*[; ]$at_keyword[ ;]"`
+	done
+	# Smash the newlines.
+	at_groups_selected=`$as_echo "$at_groups_selected" | sed 's/;.*//' |
+	  tr "$as_nl" ' '
+	`
+	as_fn_append at_groups "$at_groups_selected "
+	;;
+
+    *=*)
+	at_envvar=`expr "x$at_option" : 'x\([^=]*\)='`
+	# Reject names that are not valid shell variable names.
+	case $at_envvar in
+	  '' | [0-9]* | *[!_$as_cr_alnum]* )
+	    as_fn_error "invalid variable name: \`$at_envvar'" ;;
+	esac
+	at_value=`$as_echo "$at_optarg" | sed "s/'/'\\\\\\\\''/g"`
+	# Export now, but save eval for later and for debug scripts.
+	export $at_envvar
+	as_fn_append at_debug_args " $at_envvar='$at_value'"
+	;;
+
+     *) $as_echo "$as_me: invalid option: $at_option" >&2
+	$as_echo "Try \`$0 --help' for more information." >&2
+	exit 1
+	;;
+  esac
+done
+
+# Verify our last option didn't require an argument
+if test -n "$at_prev"; then :
+  as_fn_error "\`$at_prev' requires an argument."
+fi
+
+# Selected test groups.
+if test -z "$at_groups"; then
+  at_groups=$at_groups_all
+else
+  # Sort the tests, removing duplicates.
+  at_groups=`$as_echo "$at_groups" | tr ' ' "$as_nl" | sort -nu`
+fi
+
+# Help message.
+if $at_help_p; then
+  cat <<_ATEOF || at_write_fail=1
+Usage: $0 [OPTION]... [VARIABLE=VALUE]... [TESTS]
+
+Run all the tests, or the selected TESTS, given by numeric ranges, and
+save a detailed log file.  Upon failure, create debugging scripts.
+
+Do not change environment variables directly.  Instead, set them via
+command line arguments.  Set \`AUTOTEST_PATH' to select the executables
+to exercise.  Each relative directory is expanded as build and source
+directories relative to the top level of this distribution.
+E.g., from within the build directory /tmp/foo-1.0, invoking this:
+
+  $ $0 AUTOTEST_PATH=bin
+
+is equivalent to the following, assuming the source directory is /src/foo-1.0:
+
+  PATH=/tmp/foo-1.0/bin:/src/foo-1.0/bin:\$PATH $0
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Operation modes:
+  -h, --help     print the help message, then exit
+  -V, --version  print version number, then exit
+  -c, --clean    remove all the files this test suite might create and exit
+  -l, --list     describes all the tests, or the selected TESTS
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Execution tuning:
+  -C, --directory=DIR
+                 change to directory DIR before starting
+  -j, --jobs[=N]
+                 Allow N jobs at once; infinite jobs with no arg (default 1)
+  -k, --keywords=KEYWORDS
+                 select the tests matching all the comma-separated KEYWORDS
+                 multiple \`-k' accumulate; prefixed \`!' negates a KEYWORD
+  -e, --errexit  abort as soon as a test fails; implies --debug
+  -v, --verbose  force more detailed output
+                 default for debugging scripts
+  -d, --debug    inhibit clean up and top-level logging
+                 default for debugging scripts
+  -x, --trace    enable tests shell tracing
+_ATEOF
+cat <<_ATEOF || at_write_fail=1
+
+Report bugs to <opendap-tech at opendap.org>.
+_ATEOF
+  exit $at_write_fail
+fi
+
+# List of tests.
+if $at_list_p; then
+  cat <<_ATEOF || at_write_fail=1
+libdap 3.11.1 test suite: expr-test test groups:
+
+ NUM: FILE-NAME:LINE     TEST-GROUP-NAME
+      KEYWORDS
+
+_ATEOF
+  # Passing at_groups is tricky.  We cannot use it to form a literal string
+  # or regexp because of the limitation of AIX awk.  And Solaris' awk
+  # doesn't grok more than 99 fields in a record, so we have to use `split'.
+  # at_groups needs to be space-separated for this script to work.
+  case $at_groups in
+    *"$as_nl"* )
+      at_groups=`$as_echo "$at_groups" | tr "$as_nl" ' '` ;;
+  esac
+  $as_echo "$at_groups$as_nl$at_help_all" |
+    awk 'BEGIN { FS = ";" }
+	 NR == 1 {
+	   for (n = split ($ 0, a, " "); n; n--)
+	     selected[a[n]] = 1
+	   next
+	 }
+	 NF > 0 {
+	   if (selected[$ 1]) {
+	     printf " %3d: %-18s %s\n", $ 1, $ 2, $ 3
+	     if ($ 4) {
+	       lmax = 79
+	       indent = "     "
+	       line = indent
+	       len = length (line)
+	       n = split ($ 4, a, " ")
+	       for (i = 1; i <= n; i++) {
+		 l = length (a[i]) + 1
+		 if (i > 1 && len + l > lmax) {
+		   print line
+		   line = indent " " a[i]
+		   len = length (line)
+		 } else {
+		   line = line " " a[i]
+		   len += l
+		 }
+	       }
+	       if (n)
+		 print line
+	     }
+	   }
+	 }' || at_write_fail=1
+  exit $at_write_fail
+fi
+if $at_version_p; then
+  $as_echo "$as_me (libdap 3.11.1)" &&
+  cat <<\_ATEOF || at_write_fail=1
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This test suite is free software; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+_ATEOF
+  exit $at_write_fail
+fi
+
+# Should we print banners?  at_groups is space-separated for entire test,
+# newline-separated if only a subset of the testsuite is run.
+case $at_groups in
+  *' '*' '* | *"$as_nl"*"$as_nl"* )
+      at_print_banners=: ;;
+  * ) at_print_banners=false ;;
+esac
+# Text for banner N, set to empty once printed.
+
+# Take any -C into account.
+if $at_change_dir ; then
+  if test x- = "x$at_dir" ; then
+    at_dir=./-
+  fi
+  test x != "x$at_dir" && cd "$at_dir" \
+    || as_fn_error "unable to change directory"
+  at_dir=`pwd`
+fi
+
+# Load the config files for any default variable assignments.
+for at_file in atconfig atlocal
+do
+  test -r $at_file || continue
+  . ./$at_file || as_fn_error "invalid content: $at_file"
+done
+
+# Autoconf <=2.59b set at_top_builddir instead of at_top_build_prefix:
+: ${at_top_build_prefix=$at_top_builddir}
+
+# Perform any assignments requested during argument parsing.
+eval "$at_debug_args"
+
+# atconfig delivers names relative to the directory the test suite is
+# in, but the groups themselves are run in testsuite-dir/group-dir.
+if test -n "$at_top_srcdir"; then
+  builddir=../..
+  for at_dir_var in srcdir top_srcdir top_build_prefix
+  do
+    eval at_val=\$at_$at_dir_var
+    case $at_val in
+      [\\/$]* | ?:[\\/]* ) at_prefix= ;;
+      *) at_prefix=../../ ;;
+    esac
+    eval "$at_dir_var=\$at_prefix\$at_val"
+  done
+fi
+
+## -------------------- ##
+## Directory structure. ##
+## -------------------- ##
+
+# This is the set of directories and files used by this script
+# (non-literals are capitalized):
+#
+# TESTSUITE         - the testsuite
+# TESTSUITE.log     - summarizes the complete testsuite run
+# TESTSUITE.dir/    - created during a run, remains after -d or failed test
+# + at-groups/      - during a run: status of all groups in run
+# | + NNN/          - during a run: meta-data about test group NNN
+# | | + check-line  - location (source file and line) of current AT_CHECK
+# | | + status      - exit status of current AT_CHECK
+# | | + stdout      - stdout of current AT_CHECK
+# | | + stder1      - stderr, including trace
+# | | + stderr      - stderr, with trace filtered out
+# | | + test-source - portion of testsuite that defines group
+# | | + times       - timestamps for computing duration
+# | | + pass        - created if group passed
+# | | + xpass       - created if group xpassed
+# | | + fail        - created if group failed
+# | | + xfail       - created if group xfailed
+# | | + skip        - created if group skipped
+# + at-stop         - during a run: end the run if this file exists
+# + at-source-lines - during a run: cache of TESTSUITE line numbers for extraction
+# + 0..NNN/         - created for each group NNN, remains after -d or failed test
+# | + TESTSUITE.log - summarizes the group results
+# | + ...           - files created during the group
+
+# The directory the whole suite works in.
+# Should be absolute to let the user `cd' at will.
+at_suite_dir=$at_dir/$as_me.dir
+# The file containing the suite.
+at_suite_log=$at_dir/$as_me.log
+# The directory containing helper files per test group.
+at_helper_dir=$at_suite_dir/at-groups
+# Stop file: if it exists, do not start new jobs.
+at_stop_file=$at_suite_dir/at-stop
+# The fifo used for the job dispatcher.
+at_job_fifo=$at_suite_dir/at-job-fifo
+
+if $at_clean; then
+  test -d "$at_suite_dir" &&
+    find "$at_suite_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+  rm -f -r "$at_suite_dir" "$at_suite_log"
+  exit $?
+fi
+
+# Don't take risks: use only absolute directories in PATH.
+#
+# For stand-alone test suites (ie. atconfig was not found),
+# AUTOTEST_PATH is relative to `.'.
+#
+# For embedded test suites, AUTOTEST_PATH is relative to the top level
+# of the package.  Then expand it into build/src parts, since users
+# may create executables in both places.
+AUTOTEST_PATH=`$as_echo "$AUTOTEST_PATH" | sed "s|:|$PATH_SEPARATOR|g"`
+at_path=
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $AUTOTEST_PATH $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -n "$at_path" && as_fn_append at_path $PATH_SEPARATOR
+case $as_dir in
+  [\\/]* | ?:[\\/]* )
+    as_fn_append at_path "$as_dir"
+    ;;
+  * )
+    if test -z "$at_top_build_prefix"; then
+      # Stand-alone test suite.
+      as_fn_append at_path "$as_dir"
+    else
+      # Embedded test suite.
+      as_fn_append at_path "$at_top_build_prefix$as_dir$PATH_SEPARATOR"
+      as_fn_append at_path "$at_top_srcdir/$as_dir"
+    fi
+    ;;
+esac
+  done
+IFS=$as_save_IFS
+
+
+# Now build and simplify PATH.
+#
+# There might be directories that don't exist, but don't redirect
+# builtins' (eg., cd) stderr directly: Ultrix's sh hates that.
+at_new_path=
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $at_path
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -d "$as_dir" || continue
+case $as_dir in
+  [\\/]* | ?:[\\/]* ) ;;
+  * ) as_dir=`(cd "$as_dir" && pwd) 2>/dev/null` ;;
+esac
+case $PATH_SEPARATOR$at_new_path$PATH_SEPARATOR in
+  *$PATH_SEPARATOR$as_dir$PATH_SEPARATOR*) ;;
+  $PATH_SEPARATOR$PATH_SEPARATOR) at_new_path=$as_dir ;;
+  *) as_fn_append at_new_path "$PATH_SEPARATOR$as_dir" ;;
+esac
+  done
+IFS=$as_save_IFS
+
+PATH=$at_new_path
+export PATH
+
+# Setting up the FDs.
+
+
+# 5 is the log file.  Not to be overwritten if `-d'.
+if $at_debug_p; then
+  at_suite_log=/dev/null
+else
+  : >"$at_suite_log"
+fi
+exec 5>>"$at_suite_log"
+
+# Banners and logs.
+cat <<\_ASBOX
+## ------------------------------------ ##
+## libdap 3.11.1 test suite: expr-test. ##
+## ------------------------------------ ##
+_ASBOX
+{
+  cat <<\_ASBOX
+## ------------------------------------ ##
+## libdap 3.11.1 test suite: expr-test. ##
+## ------------------------------------ ##
+_ASBOX
+  echo
+
+  $as_echo "$as_me: command line was:"
+  $as_echo "  \$ $0 $at_cli_args"
+  echo
+
+  # Try to find a few ChangeLogs in case it might help determining the
+  # exact version.  Use the relative dir: if the top dir is a symlink,
+  # find will not follow it (and options to follow the links are not
+  # portable), which would result in no output here.  Prune directories
+  # matching the package tarname, since they tend to be leftovers from
+  # `make dist' or `make distcheck' and contain redundant or stale logs.
+  if test -n "$at_top_srcdir"; then
+    cat <<\_ASBOX
+## ----------- ##
+## ChangeLogs. ##
+## ----------- ##
+_ASBOX
+    echo
+    for at_file in `find "$at_top_srcdir" -name "libdap-*" -prune -o -name ChangeLog -print`
+    do
+      $as_echo "$as_me: $at_file:"
+      sed 's/^/| /;10q' $at_file
+      echo
+    done
+
+  fi
+
+  {
+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`
+/usr/bin/hostinfo      = `(/usr/bin/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=.
+    $as_echo "PATH: $as_dir"
+  done
+IFS=$as_save_IFS
+
+}
+  echo
+
+  # Contents of the config files.
+  for at_file in atconfig atlocal
+  do
+    test -r $at_file || continue
+    $as_echo "$as_me: $at_file:"
+    sed 's/^/| /' $at_file
+    echo
+  done
+} >&5
+
+
+## ------------------------- ##
+## Autotest shell functions. ##
+## ------------------------- ##
+
+# at_fn_banner NUMBER
+# -------------------
+# Output banner NUMBER, provided the testsuite is running multiple groups and
+# this particular banner has not yet been printed.
+at_fn_banner ()
+{
+  $at_print_banners || return 0
+  eval at_banner_text=\$at_banner_text_$1
+  test "x$at_banner_text" = x && return 0
+  eval at_banner_text_$1=
+  $as_echo "$as_nl$at_banner_text$as_nl"
+} # at_fn_banner
+
+# at_fn_check_prepare_notrace REASON LINE
+# ---------------------------------------
+# Perform AT_CHECK preparations for the command at LINE for an untraceable
+# command; REASON is the reason for disabling tracing.
+at_fn_check_prepare_notrace ()
+{
+  $at_trace_echo "Not enabling shell tracing (command contains $1)"
+  $as_echo "$2" >"$at_check_line_file"
+  at_check_trace=: at_check_filter=:
+  : >"$at_stdout"; : >"$at_stderr"
+}
+
+# at_fn_check_prepare_trace LINE
+# ------------------------------
+# Perform AT_CHECK preparations for the command at LINE for a traceable
+# command.
+at_fn_check_prepare_trace ()
+{
+  $as_echo "$1" >"$at_check_line_file"
+  at_check_trace=$at_traceon at_check_filter=$at_check_filter_trace
+  : >"$at_stdout"; : >"$at_stderr"
+}
+
+# at_fn_check_prepare_dynamic COMMAND LINE
+# ----------------------------------------
+# Decide if COMMAND at LINE is traceable at runtime, and call the appropriate
+# preparation function.
+at_fn_check_prepare_dynamic ()
+{
+  case $1 in
+    *$as_nl*)
+      at_fn_check_prepare_notrace 'an embedded newline' "$2" ;;
+    *)
+      at_fn_check_prepare_trace "$2" ;;
+  esac
+}
+
+# at_fn_filter_trace
+# ------------------
+# Remove the lines in the file "$at_stderr" generated by "set -x" and print
+# them to stderr.
+at_fn_filter_trace ()
+{
+  mv "$at_stderr" "$at_stder1"
+  grep '^ *+' "$at_stder1" >&2
+  grep -v '^ *+' "$at_stder1" >"$at_stderr"
+}
+
+# at_fn_log_failure FILE-LIST
+# ---------------------------
+# Copy the files in the list on stdout with a "> " prefix, and exit the shell
+# with a failure exit code.
+at_fn_log_failure ()
+{
+  for file
+    do $as_echo "$file:"; sed 's/^/> /' "$file"; done
+  echo 1 > "$at_status_file"
+  exit 1
+}
+
+# at_fn_check_skip EXIT-CODE LINE
+# -------------------------------
+# Check whether EXIT-CODE is a special exit code (77 or 99), and if so exit
+# the test group subshell with that same exit code. Use LINE in any report
+# about test failure.
+at_fn_check_skip ()
+{
+  case $1 in
+    99) echo 99 > "$at_status_file"; at_failed=:
+	$as_echo "$2: hard failure"; exit 99;;
+    77) echo 77 > "$at_status_file"; exit 77;;
+  esac
+}
+
+# at_fn_check_status EXPECTED EXIT-CODE LINE
+# ------------------------------------------
+# Check whether EXIT-CODE is the EXPECTED exit code, and if so do nothing.
+# Otherwise, if it is 77 or 99, exit the test group subshell with that same
+# exit code; if it is anything else print an error message referring to LINE,
+# and fail the test.
+at_fn_check_status ()
+{
+  case $2 in
+    $1 ) ;;
+    77) echo 77 > "$at_status_file"; exit 77;;
+    99) echo 99 > "$at_status_file"; at_failed=:
+	$as_echo "$3: hard failure"; exit 99;;
+    *) $as_echo "$3: exit code was $2, expected $1"
+      at_failed=:;;
+  esac
+}
+
+# at_fn_diff_devnull FILE
+# -----------------------
+# Emit a diff between /dev/null and FILE. Uses "test -s" to avoid useless diff
+# invocations.
+at_fn_diff_devnull ()
+{
+  test -s "$1" || return 0
+  $at_diff "$at_devnull" "$1"
+}
+
+# at_fn_test NUMBER
+# -----------------
+# Parse out test NUMBER from the tail of this file.
+at_fn_test ()
+{
+  eval at_sed=\$at_sed$1
+  sed "$at_sed" "$at_myself" > "$at_test_source"
+}
+
+# at_fn_create_debugging_script
+# -----------------------------
+# Create the debugging script $at_group_dir/run which will reproduce the
+# current test group.
+at_fn_create_debugging_script ()
+{
+  {
+    echo "#! /bin/sh" &&
+    echo 'test "${ZSH_VERSION+set}" = set && alias -g '\''${1+"$@"}'\''='\''"$@"'\''' &&
+    $as_echo "cd '$at_dir'" &&
+    $as_echo "exec \${CONFIG_SHELL-$SHELL} \"$at_myself\" -v -d $at_debug_args $at_group \${1+\"\$@\"}" &&
+    echo 'exit 1'
+  } >"$at_group_dir/run" &&
+  chmod +x "$at_group_dir/run"
+}
+
+## -------------------------------- ##
+## End of autotest shell functions. ##
+## -------------------------------- ##
+{
+  cat <<\_ASBOX
+## ---------------- ##
+## Tested programs. ##
+## ---------------- ##
+_ASBOX
+  echo
+} >&5
+
+# Report what programs are being tested.
+for at_program in : $at_tested
+do
+  test "$at_program" = : && continue
+  case $at_program in
+    [\\/]* | ?:[\\/]* ) $at_program_=$at_program ;;
+    * )
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+    test -f "$as_dir/$at_program" && break
+  done
+IFS=$as_save_IFS
+
+    at_program_=$as_dir/$at_program ;;
+  esac
+  if test -f "$at_program_"; then
+    {
+      $as_echo "$at_srcdir/EXPRTest.at:3: $at_program_ --version"
+      "$at_program_" --version </dev/null
+      echo
+    } >&5 2>&1
+  else
+    as_fn_error "cannot find $at_program" "$LINENO" 5
+  fi
+done
+
+{
+  cat <<\_ASBOX
+## ------------------ ##
+## Running the tests. ##
+## ------------------ ##
+_ASBOX
+} >&5
+
+at_start_date=`date`
+at_start_time=`date +%s 2>/dev/null`
+$as_echo "$as_me: starting at: $at_start_date" >&5
+
+# Create the master directory if it doesn't already exist.
+as_dir="$at_suite_dir"; as_fn_mkdir_p ||
+  as_fn_error "cannot create \`$at_suite_dir'" "$LINENO" 5
+
+# Can we diff with `/dev/null'?  DU 5.0 refuses.
+if diff /dev/null /dev/null >/dev/null 2>&1; then
+  at_devnull=/dev/null
+else
+  at_devnull=$at_suite_dir/devnull
+  >"$at_devnull"
+fi
+
+# Use `diff -u' when possible.
+if at_diff=`diff -u "$at_devnull" "$at_devnull" 2>&1` && test -z "$at_diff"
+then
+  at_diff='diff -u'
+else
+  at_diff=diff
+fi
+
+# Get the last needed group.
+for at_group in : $at_groups; do :; done
+
+# Extract the start and end lines of each test group at the tail
+# of this file
+awk '
+BEGIN { FS="" }
+/^#AT_START_/ {
+  start = NR
+}
+/^#AT_STOP_/ {
+  test = substr ($ 0, 10)
+  print "at_sed" test "=\"1," start "d;" (NR-1) "q\""
+  if (test == "'"$at_group"'") exit
+}' "$at_myself" > "$at_suite_dir/at-source-lines" &&
+. "$at_suite_dir/at-source-lines" ||
+  as_fn_error "cannot create test line number cache" "$LINENO" 5
+rm -f "$at_suite_dir/at-source-lines"
+
+# Set number of jobs for `-j'; avoid more jobs than test groups.
+set X $at_groups; shift; at_max_jobs=$#
+if test $at_max_jobs -eq 0; then
+  at_jobs=1
+fi
+if test $at_jobs -ne 1 &&
+   { test $at_jobs -eq 0 || test $at_jobs -gt $at_max_jobs; }; then
+  at_jobs=$at_max_jobs
+fi
+
+# If parallel mode, don't output banners, don't split summary lines.
+if test $at_jobs -ne 1; then
+  at_print_banners=false
+  at_quiet=:
+fi
+
+# Set up helper dirs.
+rm -rf "$at_helper_dir" &&
+mkdir "$at_helper_dir" &&
+cd "$at_helper_dir" &&
+{ test -z "$at_groups" || mkdir $at_groups; } ||
+as_fn_error "testsuite directory setup failed" "$LINENO" 5
+
+# Functions for running a test group.  We leave the actual
+# test group execution outside of a shell function in order
+# to avoid hitting zsh 4.x exit status bugs.
+
+# at_fn_group_prepare
+# -------------------
+# Prepare running a test group.
+at_fn_group_prepare ()
+{
+  # The directory for additional per-group helper files.
+  at_job_dir=$at_helper_dir/$at_group
+  # The file containing the location of the last AT_CHECK.
+  at_check_line_file=$at_job_dir/check-line
+  # The file containing the exit status of the last command.
+  at_status_file=$at_job_dir/status
+  # The files containing the output of the tested commands.
+  at_stdout=$at_job_dir/stdout
+  at_stder1=$at_job_dir/stder1
+  at_stderr=$at_job_dir/stderr
+  # The file containing the code for a test group.
+  at_test_source=$at_job_dir/test-source
+  # The file containing dates.
+  at_times_file=$at_job_dir/times
+
+  # Be sure to come back to the top test directory.
+  cd "$at_suite_dir"
+
+  # Clearly separate the test groups when verbose.
+  $at_first || $at_verbose echo
+
+  at_group_normalized=$at_group
+
+  eval 'while :; do
+    case $at_group_normalized in #(
+    '"$at_format"'*) break;;
+    esac
+    at_group_normalized=0$at_group_normalized
+  done'
+
+
+  # Create a fresh directory for the next test group, and enter.
+  # If one already exists, the user may have invoked ./run from
+  # within that directory; we remove the contents, but not the
+  # directory itself, so that we aren't pulling the rug out from
+  # under the shell's notion of the current directory.
+  at_group_dir=$at_suite_dir/$at_group_normalized
+  at_group_log=$at_group_dir/$as_me.log
+  if test -d "$at_group_dir"; then
+  find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx {} \;
+  rm -fr "$at_group_dir"/* "$at_group_dir"/.[!.] "$at_group_dir"/.??*
+fi ||
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: test directory for $at_group_normalized could not be cleaned." >&5
+$as_echo "$as_me: WARNING: test directory for $at_group_normalized could not be cleaned." >&2;}
+  # Be tolerant if the above `rm' was not able to remove the directory.
+  as_dir="$at_group_dir"; as_fn_mkdir_p
+
+  echo 0 > "$at_status_file"
+
+  # In verbose mode, append to the log file *and* show on
+  # the standard output; in quiet mode only write to the log.
+  if test -z "$at_verbose"; then
+    at_tee_pipe='tee -a "$at_group_log"'
+  else
+    at_tee_pipe='cat >> "$at_group_log"'
+  fi
+}
+
+# at_fn_group_postprocess
+# -----------------------
+# Perform cleanup after running a test group.
+at_fn_group_postprocess ()
+{
+  # Be sure to come back to the suite directory, in particular
+  # since below we might `rm' the group directory we are in currently.
+  cd "$at_suite_dir"
+
+  if test ! -f "$at_check_line_file"; then
+    sed "s/^ */$as_me: WARNING: /" <<_ATEOF
+      A failure happened in a test group before any test could be
+      run. This means that test suite is improperly designed.  Please
+      report this failure to <opendap-tech at opendap.org>.
+_ATEOF
+    $as_echo "$at_setup_line" >"$at_check_line_file"
+    at_status=99
+  fi
+  $at_verbose $as_echo_n "$at_group. $at_setup_line: "
+  $as_echo_n "$at_group. $at_setup_line: " >> "$at_group_log"
+  case $at_xfail:$at_status in
+    *:99)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	;;
+    yes:0)
+	at_msg="UNEXPECTED PASS"
+	at_res=xpass
+	at_errexit=$at_errexit_p
+	;;
+    no:0)
+	at_msg="ok"
+	at_res=pass
+	at_errexit=false
+	;;
+    *:77)
+	at_msg='skipped ('`cat "$at_check_line_file"`')'
+	at_res=skip
+	at_errexit=false
+	;;
+    yes:*)
+	at_msg='expected failure ('`cat "$at_check_line_file"`')'
+	at_res=xfail
+	at_errexit=false
+	;;
+    no:*)
+	at_msg='FAILED ('`cat "$at_check_line_file"`')'
+	at_res=fail
+	at_errexit=$at_errexit_p
+	;;
+  esac
+  echo "$at_res" > "$at_job_dir/$at_res"
+  # In parallel mode, output the summary line only afterwards.
+  if test $at_jobs -ne 1 && test -n "$at_verbose"; then
+    $as_echo "$at_desc_line $at_msg"
+  else
+    # Make sure there is a separator even with long titles.
+    $as_echo " $at_msg"
+  fi
+  at_log_msg="$at_group. $at_desc ($at_setup_line): $at_msg"
+  case $at_status in
+    0|77)
+      # $at_times_file is only available if the group succeeded.
+      # We're not including the group log, so the success message
+      # is written in the global log separately.  But we also
+      # write to the group log in case they're using -d.
+      if test -f "$at_times_file"; then
+	at_log_msg="$at_log_msg     ("`sed 1d "$at_times_file"`')'
+	rm -f "$at_times_file"
+      fi
+      $as_echo "$at_log_msg" >> "$at_group_log"
+      $as_echo "$at_log_msg" >&5
+
+      # Cleanup the group directory, unless the user wants the files.
+      if $at_debug_p; then
+	at_fn_create_debugging_script
+      else
+	if test -d "$at_group_dir"; then
+	  find "$at_group_dir" -type d ! -perm -700 -exec chmod u+rwx \{\} \;
+	  rm -fr "$at_group_dir"
+	fi
+	rm -f "$at_test_source"
+      fi
+      ;;
+    *)
+      # Upon failure, include the log into the testsuite's global
+      # log.  The failure message is written in the group log.  It
+      # is later included in the global log.
+      $as_echo "$at_log_msg" >> "$at_group_log"
+
+      # Upon failure, keep the group directory for autopsy, and create
+      # the debugging script.  With -e, do not start any further tests.
+      at_fn_create_debugging_script
+      if $at_errexit; then
+	echo stop > "$at_stop_file"
+      fi
+      ;;
+  esac
+}
+
+
+## ------------ ##
+## Driver loop. ##
+## ------------ ##
+
+
+if (set -m && set +m && set +b) >/dev/null 2>&1; then
+  set +b
+  at_job_control_on='set -m' at_job_control_off='set +m' at_job_group=-
+else
+  at_job_control_on=: at_job_control_off=: at_job_group=
+fi
+
+for at_signal in 1 2 15; do
+  trap 'set +x; set +e
+	$at_job_control_off
+	at_signal='"$at_signal"'
+	echo stop > "$at_stop_file"
+	trap "" $at_signal
+	at_pgids=
+	for at_pgid in `jobs -p 2>/dev/null`; do
+	  at_pgids="$at_pgids $at_job_group$at_pgid"
+	done
+	test -z "$at_pgids" || kill -$at_signal $at_pgids 2>/dev/null
+	wait
+	if test "$at_jobs" -eq 1 || test -z "$at_verbose"; then
+	  echo >&2
+	fi
+	at_signame=`kill -l $at_signal 2>&1 || echo $at_signal`
+	set x $at_signame
+	test 1 -gt 2 && at_signame=$at_signal
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: caught signal $at_signame, bailing out" >&5
+$as_echo "$as_me: WARNING: caught signal $at_signame, bailing out" >&2;}
+	as_fn_arith 128 + $at_signal && exit_status=$as_val
+	as_fn_exit $exit_status' $at_signal
+done
+
+rm -f "$at_stop_file"
+at_first=:
+
+if test $at_jobs -ne 1 &&
+     rm -f "$at_job_fifo" &&
+     test -n "$at_job_group" &&
+     ( mkfifo "$at_job_fifo" && trap 'exit 1' PIPE STOP TSTP ) 2>/dev/null
+then
+  # FIFO job dispatcher.
+
+  trap 'at_pids=
+	for at_pid in `jobs -p`; do
+	  at_pids="$at_pids $at_job_group$at_pid"
+	done
+	if test -n "$at_pids"; then
+	  at_sig=TSTP
+	  test "${TMOUT+set}" = set && at_sig=STOP
+	  kill -$at_sig $at_pids 2>/dev/null
+	fi
+	kill -STOP $$
+	test -z "$at_pids" || kill -CONT $at_pids 2>/dev/null' TSTP
+
+  echo
+  # Turn jobs into a list of numbers, starting from 1.
+  at_joblist=`$as_echo " $at_groups_all " | \
+    sed 's/\( '$at_jobs'\) .*/\1/'`
+
+  set X $at_joblist
+  shift
+  for at_group in $at_groups; do
+    $at_job_control_on 2>/dev/null
+    (
+      # Start one test group.
+      $at_job_control_off
+      exec 6>"$at_job_fifo"
+      trap 'set +x; set +e
+	    trap "" PIPE
+	    echo stop > "$at_stop_file"
+	    echo token >&6
+	    as_fn_exit 141' PIPE
+      at_fn_group_prepare
+      if cd "$at_group_dir" &&
+	 at_fn_test $at_group &&
+	 . "$at_test_source" # AT_JOB_FIFO_FD>&-
+      then :; else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+	at_failed=:
+      fi
+      at_fn_group_postprocess
+      echo token >&6
+    ) &
+    $at_job_control_off
+    if $at_first; then
+      at_first=false
+      exec 6<"$at_job_fifo"
+    fi
+    shift # Consume one token.
+    if test $# -gt 0; then :; else
+      read at_token <&6 || break
+      set x $*
+    fi
+    test -f "$at_stop_file" && break
+  done
+  # Read back the remaining ($at_jobs - 1) tokens.
+  set X $at_joblist
+  shift
+  if test $# -gt 0; then
+    shift
+    for at_job
+    do
+      read at_token
+    done <&6
+  fi
+  exec 6<&-
+  wait
+else
+  # Run serially, avoid forks and other potential surprises.
+  for at_group in $at_groups; do
+    at_fn_group_prepare
+    if cd "$at_group_dir" &&
+       at_fn_test $at_group &&
+       . "$at_test_source"; then :; else
+      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unable to parse test group: $at_group" >&5
+$as_echo "$as_me: WARNING: unable to parse test group: $at_group" >&2;}
+      at_failed=:
+    fi
+    at_fn_group_postprocess
+    test -f "$at_stop_file" && break
+    at_first=false
+  done
+fi
+
+# Wrap up the test suite with summary statistics.
+cd "$at_helper_dir"
+
+# Use ?..???? when the list must remain sorted, the faster * otherwise.
+at_pass_list=`for f in */pass; do echo $f; done | sed '/\*/d; s,/pass,,'`
+at_skip_list=`for f in */skip; do echo $f; done | sed '/\*/d; s,/skip,,'`
+at_xfail_list=`for f in */xfail; do echo $f; done | sed '/\*/d; s,/xfail,,'`
+at_xpass_list=`for f in ?/xpass ??/xpass ???/xpass ????/xpass; do
+		 echo $f; done | sed '/?/d; s,/xpass,,'`
+at_fail_list=`for f in ?/fail ??/fail ???/fail ????/fail; do
+		echo $f; done | sed '/?/d; s,/fail,,'`
+
+set X $at_pass_list $at_xpass_list $at_xfail_list $at_fail_list $at_skip_list
+shift; at_group_count=$#
+set X $at_xpass_list; shift; at_xpass_count=$#; at_xpass_list=$*
+set X $at_xfail_list; shift; at_xfail_count=$#
+set X $at_fail_list; shift; at_fail_count=$#; at_fail_list=$*
+set X $at_skip_list; shift; at_skip_count=$#
+
+as_fn_arith $at_group_count - $at_skip_count && at_run_count=$as_val
+as_fn_arith $at_xpass_count + $at_fail_count && at_unexpected_count=$as_val
+as_fn_arith $at_xfail_count + $at_fail_count && at_total_fail_count=$as_val
+
+# Back to the top directory.
+cd "$at_dir"
+rm -rf "$at_helper_dir"
+
+# Compute the duration of the suite.
+at_stop_date=`date`
+at_stop_time=`date +%s 2>/dev/null`
+$as_echo "$as_me: ending at: $at_stop_date" >&5
+case $at_start_time,$at_stop_time in
+  [0-9]*,[0-9]*)
+    as_fn_arith $at_stop_time - $at_start_time && at_duration_s=$as_val
+    as_fn_arith $at_duration_s / 60 && at_duration_m=$as_val
+    as_fn_arith $at_duration_m / 60 && at_duration_h=$as_val
+    as_fn_arith $at_duration_s % 60 && at_duration_s=$as_val
+    as_fn_arith $at_duration_m % 60 && at_duration_m=$as_val
+    at_duration="${at_duration_h}h ${at_duration_m}m ${at_duration_s}s"
+    $as_echo "$as_me: test suite duration: $at_duration" >&5
+    ;;
+esac
+
+echo
+cat <<\_ASBOX
+## ------------- ##
+## Test results. ##
+## ------------- ##
+_ASBOX
+echo
+{
+  echo
+  cat <<\_ASBOX
+## ------------- ##
+## Test results. ##
+## ------------- ##
+_ASBOX
+  echo
+} >&5
+
+if test $at_run_count = 1; then
+  at_result="1 test"
+  at_were=was
+else
+  at_result="$at_run_count tests"
+  at_were=were
+fi
+if $at_errexit_p && test $at_unexpected_count != 0; then
+  if test $at_xpass_count = 1; then
+    at_result="$at_result $at_were run, one passed"
+  else
+    at_result="$at_result $at_were run, one failed"
+  fi
+  at_result="$at_result unexpectedly and inhibited subsequent tests."
+else
+  # Don't you just love exponential explosion of the number of cases?
+  case $at_xpass_count:$at_fail_count:$at_xfail_count in
+    # So far, so good.
+    0:0:0) at_result="$at_result $at_were successful." ;;
+    0:0:*) at_result="$at_result behaved as expected." ;;
+
+    # Some unexpected failures
+    0:*:0) at_result="$at_result $at_were run,
+$at_fail_count failed unexpectedly." ;;
+
+    # Some failures, both expected and unexpected
+    0:*:1) at_result="$at_result $at_were run,
+$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
+    0:*:*) at_result="$at_result $at_were run,
+$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
+
+    # No unexpected failures, but some xpasses
+    *:0:*) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly." ;;
+
+    # No expected failures, but failures and xpasses
+    *:1:0) at_result="$at_result $at_were run,
+$at_unexpected_count did not behave as expected ($at_fail_count unexpected failure)." ;;
+    *:*:0) at_result="$at_result $at_were run,
+$at_unexpected_count did not behave as expected ($at_fail_count unexpected failures)." ;;
+
+    # All of them.
+    *:*:1) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly,
+$at_total_fail_count failed ($at_xfail_count expected failure)." ;;
+    *:*:*) at_result="$at_result $at_were run,
+$at_xpass_count passed unexpectedly,
+$at_total_fail_count failed ($at_xfail_count expected failures)." ;;
+  esac
+
+  if test $at_skip_count = 0 && test $at_run_count -gt 1; then
+    at_result="All $at_result"
+  fi
+fi
+
+# Now put skips in the mix.
+case $at_skip_count in
+  0) ;;
+  1) at_result="$at_result
+1 test was skipped." ;;
+  *) at_result="$at_result
+$at_skip_count tests were skipped." ;;
+esac
+
+if test $at_unexpected_count = 0; then
+  echo "$at_result"
+  echo "$at_result" >&5
+else
+  echo "ERROR: $at_result" >&2
+  echo "ERROR: $at_result" >&5
+  {
+    echo
+    cat <<\_ASBOX
+## ------------------------ ##
+## Summary of the failures. ##
+## ------------------------ ##
+_ASBOX
+
+    # Summary of failed and skipped tests.
+    if test $at_fail_count != 0; then
+      echo "Failed tests:"
+      $SHELL "$at_myself" $at_fail_list --list
+      echo
+    fi
+    if test $at_skip_count != 0; then
+      echo "Skipped tests:"
+      $SHELL "$at_myself" $at_skip_list --list
+      echo
+    fi
+    if test $at_xpass_count != 0; then
+      echo "Unexpected passes:"
+      $SHELL "$at_myself" $at_xpass_list --list
+      echo
+    fi
+    if test $at_fail_count != 0; then
+      cat <<\_ASBOX
+## ---------------------- ##
+## Detailed failed tests. ##
+## ---------------------- ##
+_ASBOX
+      echo
+      for at_group in $at_fail_list
+      do
+	at_group_normalized=$at_group
+
+  eval 'while :; do
+    case $at_group_normalized in #(
+    '"$at_format"'*) break;;
+    esac
+    at_group_normalized=0$at_group_normalized
+  done'
+
+	cat "$at_suite_dir/$at_group_normalized/$as_me.log"
+	echo
+      done
+      echo
+    fi
+    if test -n "$at_top_srcdir"; then
+      sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## ${at_top_build_prefix}config.log ##
+_ASBOX
+      sed 's/^/| /' ${at_top_build_prefix}config.log
+      echo
+    fi
+  } >&5
+
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## $as_me.log was created. ##
+_ASBOX
+
+  echo
+  if $at_debug_p; then
+    at_msg='per-test log files'
+  else
+    at_msg="\`${at_testdir+${at_testdir}/}$as_me.log'"
+  fi
+  $as_echo "Please send $at_msg and all information you think might help:
+
+   To: <opendap-tech at opendap.org>
+   Subject: [libdap 3.11.1] $as_me: $at_fail_list${at_fail_list:+ failed${at_xpass_list:+, }}$at_xpass_list${at_xpass_list:+ passed unexpectedly}
+
+You may investigate any problem if you feel able to do so, in which
+case the test suite provides a good starting point.  Its output may
+be found below \`${at_testdir+${at_testdir}/}$as_me.dir'.
+"
+  exit 1
+fi
+
+exit 0
+
+## ------------- ##
+## Actual tests. ##
+## ------------- ##
+#AT_START_1
+# 1. EXPRTest.at:45: expr-test -w $abs_srcdir/expr-testsuite/test.1 -k i (pass)
+at_setup_line='EXPRTest.at:45'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k i (pass)"
+at_desc_line="  1: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "1. EXPRTest.at:45: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:45: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k i -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k i -f \"dummy\" || true" "EXPRTest.at:45"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k i -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:45: diff -b -B \$abs_srcdir/expr-testsuite/test.1.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1.base stderr" "EXPRTest.at:45"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_1
+#AT_START_2
+# 2. EXPRTest.at:45: expr-test -W $abs_srcdir/expr-testsuite/test.1 -k i (pass)
+at_setup_line='EXPRTest.at:45'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k i (pass)"
+at_desc_line="  2: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "2. EXPRTest.at:45: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:45: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k i -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k i -f \"dummy\" || true" "EXPRTest.at:45"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k i -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:45: diff -b -B \$abs_srcdir/expr-testsuite/test.1.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1.base stderr" "EXPRTest.at:45"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:45"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_2
+#AT_START_3
+# 3. EXPRTest.at:46: expr-test -w $abs_srcdir/expr-testsuite/test.1 -k i,j (pass)
+at_setup_line='EXPRTest.at:46'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k i,j (pass)"
+at_desc_line="  3: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "3. EXPRTest.at:46: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:46: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k i,j -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k i,j -f \"dummy\" || true" "EXPRTest.at:46"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k i,j -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:46: diff -b -B \$abs_srcdir/expr-testsuite/test.1a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stderr" "EXPRTest.at:46"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_3
+#AT_START_4
+# 4. EXPRTest.at:46: expr-test -W $abs_srcdir/expr-testsuite/test.1 -k i,j (pass)
+at_setup_line='EXPRTest.at:46'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k i,j (pass)"
+at_desc_line="  4: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "4. EXPRTest.at:46: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:46: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k i,j -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k i,j -f \"dummy\" || true" "EXPRTest.at:46"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k i,j -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:46: diff -b -B \$abs_srcdir/expr-testsuite/test.1a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stderr" "EXPRTest.at:46"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:46"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_4
+#AT_START_5
+# 5. EXPRTest.at:47: expr-test -w $abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' (pass)
+at_setup_line='EXPRTest.at:47'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' (pass)"
+at_desc_line="  5: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "5. EXPRTest.at:47: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:47: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' -f \"dummy\" || true" "EXPRTest.at:47"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:47: diff -b -B \$abs_srcdir/expr-testsuite/test.1b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stderr" "EXPRTest.at:47"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_5
+#AT_START_6
+# 6. EXPRTest.at:47: expr-test -W $abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' (pass)
+at_setup_line='EXPRTest.at:47'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' (pass)"
+at_desc_line="  6: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "6. EXPRTest.at:47: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:47: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' -f \"dummy\" || true" "EXPRTest.at:47"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k 'i,j&i=j' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:47: diff -b -B \$abs_srcdir/expr-testsuite/test.1b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stderr" "EXPRTest.at:47"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:47"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_6
+#AT_START_7
+# 7. EXPRTest.at:48: expr-test -w $abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' (pass)
+at_setup_line='EXPRTest.at:48'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' (pass)"
+at_desc_line="  7: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "7. EXPRTest.at:48: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:48: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' -f \"dummy\" || true" "EXPRTest.at:48"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:48: diff -b -B \$abs_srcdir/expr-testsuite/test.1d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stderr" "EXPRTest.at:48"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_7
+#AT_START_8
+# 8. EXPRTest.at:48: expr-test -W $abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' (pass)
+at_setup_line='EXPRTest.at:48'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' (pass)"
+at_desc_line="  8: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "8. EXPRTest.at:48: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:48: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' -f \"dummy\" || true" "EXPRTest.at:48"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.1 -k 'i&i=j' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:48: diff -b -B \$abs_srcdir/expr-testsuite/test.1d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.1d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stderr" "EXPRTest.at:48"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.1d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:48"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_8
+#AT_START_9
+# 9. EXPRTest.at:49: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s1 (pass)
+at_setup_line='EXPRTest.at:49'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s1 (pass)"
+at_desc_line="  9: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "9. EXPRTest.at:49: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:49: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s1 -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s1 -f \"dummy\" || true" "EXPRTest.at:49"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s1 -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:49: diff -b -B \$abs_srcdir/expr-testsuite/test.2.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2.base stderr" "EXPRTest.at:49"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_9
+#AT_START_10
+# 10. EXPRTest.at:49: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s1 (pass)
+at_setup_line='EXPRTest.at:49'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s1 (pass)"
+at_desc_line=" 10: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "10. EXPRTest.at:49: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:49: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s1 -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s1 -f \"dummy\" || true" "EXPRTest.at:49"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s1 -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:49: diff -b -B \$abs_srcdir/expr-testsuite/test.2.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2.base stderr" "EXPRTest.at:49"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:49"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_10
+#AT_START_11
+# 11. EXPRTest.at:50: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2 (pass)
+at_setup_line='EXPRTest.at:50'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2 (pass)"
+at_desc_line=" 11: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "11. EXPRTest.at:50: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:50: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2 -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2 -f \"dummy\" || true" "EXPRTest.at:50"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2 -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:50: diff -b -B \$abs_srcdir/expr-testsuite/test.2a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stderr" "EXPRTest.at:50"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_11
+#AT_START_12
+# 12. EXPRTest.at:50: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2 (pass)
+at_setup_line='EXPRTest.at:50'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2 (pass)"
+at_desc_line=" 12: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "12. EXPRTest.at:50: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:50: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2 -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2 -f \"dummy\" || true" "EXPRTest.at:50"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2 -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:50: diff -b -B \$abs_srcdir/expr-testsuite/test.2a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stderr" "EXPRTest.at:50"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:50"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_12
+#AT_START_13
+# 13. EXPRTest.at:51: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2,s3 (pass)
+at_setup_line='EXPRTest.at:51'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2,s3 (pass)"
+at_desc_line=" 13: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "13. EXPRTest.at:51: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:51: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2,s3 -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2,s3 -f \"dummy\" || true" "EXPRTest.at:51"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2,s3 -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:51: diff -b -B \$abs_srcdir/expr-testsuite/test.2b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stderr" "EXPRTest.at:51"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_13
+#AT_START_14
+# 14. EXPRTest.at:51: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2,s3 (pass)
+at_setup_line='EXPRTest.at:51'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2,s3 (pass)"
+at_desc_line=" 14: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "14. EXPRTest.at:51: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:51: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2,s3 -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2,s3 -f \"dummy\" || true" "EXPRTest.at:51"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2,s3 -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:51: diff -b -B \$abs_srcdir/expr-testsuite/test.2b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stderr" "EXPRTest.at:51"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:51"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_14
+#AT_START_15
+# 15. EXPRTest.at:52: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o (pass)
+at_setup_line='EXPRTest.at:52'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o (pass)"
+at_desc_line=" 15: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "15. EXPRTest.at:52: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:52: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o -f \"dummy\" || true" "EXPRTest.at:52"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:52: diff -b -B \$abs_srcdir/expr-testsuite/test.2c.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2c.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stderr" "EXPRTest.at:52"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_15
+#AT_START_16
+# 16. EXPRTest.at:52: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o (pass)
+at_setup_line='EXPRTest.at:52'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o (pass)"
+at_desc_line=" 16: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "16. EXPRTest.at:52: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:52: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o -f \"dummy\" || true" "EXPRTest.at:52"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4],s3.o -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:52: diff -b -B \$abs_srcdir/expr-testsuite/test.2c.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2c.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stderr" "EXPRTest.at:52"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2c.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:52"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_16
+#AT_START_17
+# 17. EXPRTest.at:54: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m (pass)
+at_setup_line='EXPRTest.at:54'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m (pass)"
+at_desc_line=" 17: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "17. EXPRTest.at:54: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:54: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m -f \"dummy\" || true" "EXPRTest.at:54"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:54: diff -b -B \$abs_srcdir/expr-testsuite/test.2d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stderr" "EXPRTest.at:54"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_17
+#AT_START_18
+# 18. EXPRTest.at:54: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m (pass)
+at_setup_line='EXPRTest.at:54'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m (pass)"
+at_desc_line=" 18: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "18. EXPRTest.at:54: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:54: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m -f \"dummy\" || true" "EXPRTest.at:54"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:54: diff -b -B \$abs_srcdir/expr-testsuite/test.2d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stderr" "EXPRTest.at:54"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:54"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_18
+#AT_START_19
+# 19. EXPRTest.at:55: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l (pass)
+at_setup_line='EXPRTest.at:55'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l (pass)"
+at_desc_line=" 19: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "19. EXPRTest.at:55: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:55: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l -f \"dummy\" || true" "EXPRTest.at:55"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:55: diff -b -B \$abs_srcdir/expr-testsuite/test.2e.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2e.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stderr" "EXPRTest.at:55"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_19
+#AT_START_20
+# 20. EXPRTest.at:55: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l (pass)
+at_setup_line='EXPRTest.at:55'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l (pass)"
+at_desc_line=" 20: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "20. EXPRTest.at:55: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:55: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l -f \"dummy\" || true" "EXPRTest.at:55"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k s2[2:2:4].m,s2[2:2:4].l -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:55: diff -b -B \$abs_srcdir/expr-testsuite/test.2e.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2e.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stderr" "EXPRTest.at:55"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2e.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:55"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_20
+#AT_START_21
+# 21. EXPRTest.at:57: expr-test -w $abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] (pass)
+at_setup_line='EXPRTest.at:57'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] (pass)"
+at_desc_line=" 21: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "21. EXPRTest.at:57: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:57: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] -f \"dummy\" || true" "EXPRTest.at:57"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:57: diff -b -B \$abs_srcdir/expr-testsuite/test.2f.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2f.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stderr" "EXPRTest.at:57"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_21
+#AT_START_22
+# 22. EXPRTest.at:57: expr-test -W $abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] (pass)
+at_setup_line='EXPRTest.at:57'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] (pass)"
+at_desc_line=" 22: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "22. EXPRTest.at:57: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:57: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] -f \"dummy\" || true" "EXPRTest.at:57"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2a -k s2[2:4].m[0:4],s2[2:4].l[0:5] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:57: diff -b -B \$abs_srcdir/expr-testsuite/test.2f.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2f.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stderr" "EXPRTest.at:57"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2f.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:57"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_22
+#AT_START_23
+# 23. EXPRTest.at:58: expr-test -w $abs_srcdir/expr-testsuite/test.3 -k i[1:10] (pass)
+at_setup_line='EXPRTest.at:58'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.3 -k i[1:10] (pass)"
+at_desc_line=" 23: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "23. EXPRTest.at:58: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:58: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.3 -k i[1:10] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.3 -k i[1:10] -f \"dummy\" || true" "EXPRTest.at:58"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.3 -k i[1:10] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:58: diff -b -B \$abs_srcdir/expr-testsuite/test.3.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.3.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.3.base stderr" "EXPRTest.at:58"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.3.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_23
+#AT_START_24
+# 24. EXPRTest.at:58: expr-test -W $abs_srcdir/expr-testsuite/test.3 -k i[1:10] (pass)
+at_setup_line='EXPRTest.at:58'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.3 -k i[1:10] (pass)"
+at_desc_line=" 24: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "24. EXPRTest.at:58: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:58: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.3 -k i[1:10] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.3 -k i[1:10] -f \"dummy\" || true" "EXPRTest.at:58"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.3 -k i[1:10] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:58: diff -b -B \$abs_srcdir/expr-testsuite/test.3.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.3.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.3.base stderr" "EXPRTest.at:58"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.3.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:58"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_24
+#AT_START_25
+# 25. EXPRTest.at:59: expr-test -w $abs_srcdir/expr-testsuite/test.4 -k 's&s=~"^Silly.*"' (pass)
+at_setup_line='EXPRTest.at:59'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' (pass)"
+at_desc_line=" 25: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "25. EXPRTest.at:59: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:59: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' -f \"dummy\" || true" "EXPRTest.at:59"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.4 -k 's&s=~"^Silly.*"' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:59: diff -b -B \$abs_srcdir/expr-testsuite/test.4.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.4.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.4.base stderr" "EXPRTest.at:59"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.4.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_25
+#AT_START_26
+# 26. EXPRTest.at:59: expr-test -W $abs_srcdir/expr-testsuite/test.4 -k 's&s=~"^Silly.*"' (pass)
+at_setup_line='EXPRTest.at:59'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' (pass)"
+at_desc_line=" 26: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "26. EXPRTest.at:59: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:59: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.4 -k 's&s=~\"^Silly.*\"' -f \"dummy\" || true" "EXPRTest.at:59"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.4 -k 's&s=~"^Silly.*"' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:59: diff -b -B \$abs_srcdir/expr-testsuite/test.4.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.4.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.4.base stderr" "EXPRTest.at:59"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.4.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:59"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_26
+#AT_START_27
+# 27. EXPRTest.at:61: expr-test -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 3"' (pass)
+at_setup_line='EXPRTest.at:61'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass)"
+at_desc_line=" 27: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "27. EXPRTest.at:61: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:61: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' -f \"dummy\" || true" "EXPRTest.at:61"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 3"' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:61: diff -b -B \$abs_srcdir/expr-testsuite/test.ea.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ea.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stderr" "EXPRTest.at:61"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_27
+#AT_START_28
+# 28. EXPRTest.at:61: expr-test -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 3"' (pass)
+at_setup_line='EXPRTest.at:61'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' (pass)"
+at_desc_line=" 28: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "28. EXPRTest.at:61: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:61: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 3\"' -f \"dummy\" || true" "EXPRTest.at:61"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 3"' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:61: diff -b -B \$abs_srcdir/expr-testsuite/test.ea.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ea.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stderr" "EXPRTest.at:61"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ea.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:61"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_28
+#AT_START_29
+# 29. EXPRTest.at:62: expr-test -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 5"' (pass)
+at_setup_line='EXPRTest.at:62'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass)"
+at_desc_line=" 29: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "29. EXPRTest.at:62: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:62: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' -f \"dummy\" || true" "EXPRTest.at:62"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 5"' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:62: diff -b -B \$abs_srcdir/expr-testsuite/test.eb.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.eb.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stderr" "EXPRTest.at:62"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_29
+#AT_START_30
+# 30. EXPRTest.at:62: expr-test -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 5"' (pass)
+at_setup_line='EXPRTest.at:62'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' (pass)"
+at_desc_line=" 30: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "30. EXPRTest.at:62: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:62: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~\".*: 5\"' -f \"dummy\" || true" "EXPRTest.at:62"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.e -k 'names.s&names.s=~".*: 5"' -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:62: diff -b -B \$abs_srcdir/expr-testsuite/test.eb.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.eb.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stderr" "EXPRTest.at:62"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.eb.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:62"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_30
+#AT_START_31
+# 31. EXPRTest.at:63: expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass)
+at_setup_line='EXPRTest.at:63'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass)"
+at_desc_line=" 31: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "31. EXPRTest.at:63: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:63: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] -f \"dummy\" || true" "EXPRTest.at:63"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:63"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:63: diff -b -B \$abs_srcdir/expr-testsuite/test.5.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.base stderr" "EXPRTest.at:63"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:63"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_31
+#AT_START_32
+# 32. EXPRTest.at:63: expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass)
+at_setup_line='EXPRTest.at:63'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] (pass)"
+at_desc_line=" 32: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "32. EXPRTest.at:63: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:63: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] -f \"dummy\" || true" "EXPRTest.at:63"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0][0] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:63"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:63: diff -b -B \$abs_srcdir/expr-testsuite/test.5.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.base stderr" "EXPRTest.at:63"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:63"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_32
+#AT_START_33
+# 33. EXPRTest.at:64: expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass)
+at_setup_line='EXPRTest.at:64'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass)"
+at_desc_line=" 33: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "33. EXPRTest.at:64: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:64: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] -f \"dummy\" || true" "EXPRTest.at:64"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:64"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:64: diff -b -B \$abs_srcdir/expr-testsuite/test.5a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stderr" "EXPRTest.at:64"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:64"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_33
+#AT_START_34
+# 34. EXPRTest.at:64: expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass)
+at_setup_line='EXPRTest.at:64'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] (pass)"
+at_desc_line=" 34: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "34. EXPRTest.at:64: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:64: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] -f \"dummy\" || true" "EXPRTest.at:64"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[0:2:4][0:2:4][0:2:4] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:64"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:64: diff -b -B \$abs_srcdir/expr-testsuite/test.5a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stderr" "EXPRTest.at:64"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:64"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_34
+#AT_START_35
+# 35. EXPRTest.at:65: expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i (pass)
+at_setup_line='EXPRTest.at:65'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i (pass)"
+at_desc_line=" 35: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "35. EXPRTest.at:65: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:65: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i -f \"dummy\" || true" "EXPRTest.at:65"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:65"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:65: diff -b -B \$abs_srcdir/expr-testsuite/test.6.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.base stderr" "EXPRTest.at:65"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:65"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_35
+#AT_START_36
+# 36. EXPRTest.at:65: expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i (pass)
+at_setup_line='EXPRTest.at:65'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i (pass)"
+at_desc_line=" 36: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "36. EXPRTest.at:65: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:65: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i -f \"dummy\" || true" "EXPRTest.at:65"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:65"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:65: diff -b -B \$abs_srcdir/expr-testsuite/test.6.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.base stderr" "EXPRTest.at:65"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:65"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_36
+#AT_START_37
+# 37. EXPRTest.at:66: expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass)
+at_setup_line='EXPRTest.at:66'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass)"
+at_desc_line=" 37: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "37. EXPRTest.at:66: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:66: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] -f \"dummy\" || true" "EXPRTest.at:66"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:66"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:66: diff -b -B \$abs_srcdir/expr-testsuite/test.6a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stderr" "EXPRTest.at:66"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:66"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_37
+#AT_START_38
+# 38. EXPRTest.at:66: expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass)
+at_setup_line='EXPRTest.at:66'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] (pass)"
+at_desc_line=" 38: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "38. EXPRTest.at:66: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:66: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] -f \"dummy\" || true" "EXPRTest.at:66"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i[1:2][2:4] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:66"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:66: diff -b -B \$abs_srcdir/expr-testsuite/test.6a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stderr" "EXPRTest.at:66"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:66"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_38
+#AT_START_39
+# 39. EXPRTest.at:67: expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass)
+at_setup_line='EXPRTest.at:67'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass)"
+at_desc_line=" 39: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "39. EXPRTest.at:67: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:67: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] -f \"dummy\" || true" "EXPRTest.at:67"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:67"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:67: diff -b -B \$abs_srcdir/expr-testsuite/test.5b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stderr" "EXPRTest.at:67"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:67"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_39
+#AT_START_40
+# 40. EXPRTest.at:67: expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass)
+at_setup_line='EXPRTest.at:67'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] (pass)"
+at_desc_line=" 40: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "40. EXPRTest.at:67: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:67: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] -f \"dummy\" || true" "EXPRTest.at:67"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.val[0:1][0:1][0:1] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:67"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:67: diff -b -B \$abs_srcdir/expr-testsuite/test.5b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stderr" "EXPRTest.at:67"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:67"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_40
+#AT_START_41
+# 41. EXPRTest.at:68: expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.length (pass)
+at_setup_line='EXPRTest.at:68'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass)"
+at_desc_line=" 41: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "41. EXPRTest.at:68: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:68: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.length -f \"dummy\" || true" "EXPRTest.at:68"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.length -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:68"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:68: diff -b -B \$abs_srcdir/expr-testsuite/test.5c.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5c.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stderr" "EXPRTest.at:68"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:68"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_41
+#AT_START_42
+# 42. EXPRTest.at:68: expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.length (pass)
+at_setup_line='EXPRTest.at:68'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length (pass)"
+at_desc_line=" 42: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "42. EXPRTest.at:68: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:68: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.length -f \"dummy\" || true" "EXPRTest.at:68"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.length -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:68"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:68: diff -b -B \$abs_srcdir/expr-testsuite/test.5c.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5c.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stderr" "EXPRTest.at:68"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5c.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:68"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_42
+#AT_START_43
+# 43. EXPRTest.at:69: expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass)
+at_setup_line='EXPRTest.at:69'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass)"
+at_desc_line=" 43: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "43. EXPRTest.at:69: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:69: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.length,g.width -f \"dummy\" || true" "EXPRTest.at:69"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g.length,g.width -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:69"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:69: diff -b -B \$abs_srcdir/expr-testsuite/test.5d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stderr" "EXPRTest.at:69"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:69"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_43
+#AT_START_44
+# 44. EXPRTest.at:69: expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass)
+at_setup_line='EXPRTest.at:69'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width (pass)"
+at_desc_line=" 44: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "44. EXPRTest.at:69: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:69: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g.length,g.width -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.length,g.width -f \"dummy\" || true" "EXPRTest.at:69"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g.length,g.width -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:69"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:69: diff -b -B \$abs_srcdir/expr-testsuite/test.5d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stderr" "EXPRTest.at:69"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:69"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_44
+#AT_START_45
+# 45. EXPRTest.at:70: expr-test -w $abs_srcdir/expr-testsuite/test.2 -k j,o (pass)
+at_setup_line='EXPRTest.at:70'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass)"
+at_desc_line=" 45: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "45. EXPRTest.at:70: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:70: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.2 -k j,o -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k j,o -f \"dummy\" || true" "EXPRTest.at:70"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.2 -k j,o -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:70"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:70: diff -b -B \$abs_srcdir/expr-testsuite/test.2g.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2g.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stderr" "EXPRTest.at:70"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:70"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_45
+#AT_START_46
+# 46. EXPRTest.at:70: expr-test -W $abs_srcdir/expr-testsuite/test.2 -k j,o (pass)
+at_setup_line='EXPRTest.at:70'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k j,o (pass)"
+at_desc_line=" 46: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "46. EXPRTest.at:70: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:70: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.2 -k j,o -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k j,o -f \"dummy\" || true" "EXPRTest.at:70"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.2 -k j,o -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:70"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:70: diff -b -B \$abs_srcdir/expr-testsuite/test.2g.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.2g.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stderr" "EXPRTest.at:70"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.2g.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:70"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_46
+#AT_START_47
+# 47. EXPRTest.at:71: expr-test -w $abs_srcdir/expr-testsuite/test.8 -k "data%23i[0:2:9][0:2]" (pass)
+at_setup_line='EXPRTest.at:71'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass)"
+at_desc_line=" 47: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "47. EXPRTest.at:71: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:71: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" -f \"dummy\" || true" "EXPRTest.at:71"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.8 -k "data%23i[0:2:9][0:2]" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:71"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:71: diff -b -B \$abs_srcdir/expr-testsuite/test.8.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.8.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8.base stderr" "EXPRTest.at:71"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:71"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_47
+#AT_START_48
+# 48. EXPRTest.at:71: expr-test -W $abs_srcdir/expr-testsuite/test.8 -k "data%23i[0:2:9][0:2]" (pass)
+at_setup_line='EXPRTest.at:71'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" (pass)"
+at_desc_line=" 48: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "48. EXPRTest.at:71: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:71: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.8 -k \"data%23i[0:2:9][0:2]\" -f \"dummy\" || true" "EXPRTest.at:71"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.8 -k "data%23i[0:2:9][0:2]" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:71"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:71: diff -b -B \$abs_srcdir/expr-testsuite/test.8.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.8.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8.base stderr" "EXPRTest.at:71"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:71"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_48
+#AT_START_49
+# 49. EXPRTest.at:72: expr-test -w $abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass)
+at_setup_line='EXPRTest.at:72'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass)"
+at_desc_line=" 49: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "49. EXPRTest.at:72: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:72: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.7 -k x,y,f -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.7 -k x,y,f -f \"dummy\" || true" "EXPRTest.at:72"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.7 -k x,y,f -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:72"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:72: diff -b -B \$abs_srcdir/expr-testsuite/test.7.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.7.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.7.base stderr" "EXPRTest.at:72"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.7.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:72"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_49
+#AT_START_50
+# 50. EXPRTest.at:72: expr-test -W $abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass)
+at_setup_line='EXPRTest.at:72'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.7 -k x,y,f (pass)"
+at_desc_line=" 50: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "50. EXPRTest.at:72: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:72: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.7 -k x,y,f -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.7 -k x,y,f -f \"dummy\" || true" "EXPRTest.at:72"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.7 -k x,y,f -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:72"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:72: diff -b -B \$abs_srcdir/expr-testsuite/test.7.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.7.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.7.base stderr" "EXPRTest.at:72"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.7.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:72"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_50
+#AT_START_51
+# 51. EXPRTest.at:73: expr-test -w $abs_srcdir/expr-testsuite/test.8 -k "x%23y,y" (pass)
+at_setup_line='EXPRTest.at:73'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass)"
+at_desc_line=" 51: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "51. EXPRTest.at:73: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:73: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" -f \"dummy\" || true" "EXPRTest.at:73"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.8 -k "x%23y,y" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:73"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:73: diff -b -B \$abs_srcdir/expr-testsuite/test.8a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.8a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stderr" "EXPRTest.at:73"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:73"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_51
+#AT_START_52
+# 52. EXPRTest.at:73: expr-test -W $abs_srcdir/expr-testsuite/test.8 -k "x%23y,y" (pass)
+at_setup_line='EXPRTest.at:73'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" (pass)"
+at_desc_line=" 52: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "52. EXPRTest.at:73: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:73: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.8 -k \"x%23y,y\" -f \"dummy\" || true" "EXPRTest.at:73"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.8 -k "x%23y,y" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:73"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:73: diff -b -B \$abs_srcdir/expr-testsuite/test.8a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.8a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stderr" "EXPRTest.at:73"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:73"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_52
+#AT_START_53
+# 53. EXPRTest.at:74: expr-test -w $abs_srcdir/expr-testsuite/test.8 -k "data%20name,y" (pass)
+at_setup_line='EXPRTest.at:74'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass)"
+at_desc_line=" 53: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "53. EXPRTest.at:74: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:74: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" -f \"dummy\" || true" "EXPRTest.at:74"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.8 -k "data%20name,y" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:74"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:74: diff -b -B \$abs_srcdir/expr-testsuite/test.8b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.8b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stderr" "EXPRTest.at:74"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:74"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_53
+#AT_START_54
+# 54. EXPRTest.at:74: expr-test -W $abs_srcdir/expr-testsuite/test.8 -k "data%20name,y" (pass)
+at_setup_line='EXPRTest.at:74'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" (pass)"
+at_desc_line=" 54: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "54. EXPRTest.at:74: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:74: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.8 -k \"data%20name,y\" -f \"dummy\" || true" "EXPRTest.at:74"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.8 -k "data%20name,y" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:74"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:74: diff -b -B \$abs_srcdir/expr-testsuite/test.8b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.8b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stderr" "EXPRTest.at:74"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.8b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:74"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_54
+#AT_START_55
+# 55. EXPRTest.at:75: expr-test -w $abs_srcdir/expr-testsuite/test.9 -k "Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]" (pass)
+at_setup_line='EXPRTest.at:75'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" (pass)"
+at_desc_line=" 55: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "55. EXPRTest.at:75: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:75: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" -f \"dummy\" || true" "EXPRTest.at:75"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.9 -k "Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:75"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:75: diff -b -B \$abs_srcdir/expr-testsuite/test.9.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.9.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.9.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.9.base stderr" "EXPRTest.at:75"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.9.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.9.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:75"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_55
+#AT_START_56
+# 56. EXPRTest.at:75: expr-test -W $abs_srcdir/expr-testsuite/test.9 -k "Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]" (pass)
+at_setup_line='EXPRTest.at:75'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" (pass)"
+at_desc_line=" 56: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "56. EXPRTest.at:75: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:75: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.9 -k \"Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]\" -f \"dummy\" || true" "EXPRTest.at:75"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.9 -k "Data-Set-2.fakeDim0[0:3],Data-Set-2.fakeDim1[0:3]" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:75"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:75: diff -b -B \$abs_srcdir/expr-testsuite/test.9.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.9.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.9.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.9.base stderr" "EXPRTest.at:75"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.9.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.9.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:75"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_56
+#AT_START_57
+# 57. EXPRTest.at:76: expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass)
+at_setup_line='EXPRTest.at:76'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass)"
+at_desc_line=" 57: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "57. EXPRTest.at:76: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:76: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] -f \"dummy\" || true" "EXPRTest.at:76"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:76"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:76: diff -b -B \$abs_srcdir/expr-testsuite/test.5e.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5e.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stderr" "EXPRTest.at:76"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:76"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_57
+#AT_START_58
+# 58. EXPRTest.at:76: expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass)
+at_setup_line='EXPRTest.at:76'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] (pass)"
+at_desc_line=" 58: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "58. EXPRTest.at:76: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:76: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] -f \"dummy\" || true" "EXPRTest.at:76"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.5 -k g[1:4:9] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:76"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:76: diff -b -B \$abs_srcdir/expr-testsuite/test.5e.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.5e.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stderr" "EXPRTest.at:76"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.5e.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:76"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_58
+#AT_START_59
+# 59. EXPRTest.at:77: expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass)
+at_setup_line='EXPRTest.at:77'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass)"
+at_desc_line=" 59: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "59. EXPRTest.at:77: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:77: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] -f \"dummy\" || true" "EXPRTest.at:77"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:77"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:77: diff -b -B \$abs_srcdir/expr-testsuite/test.6b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stderr" "EXPRTest.at:77"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:77"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_59
+#AT_START_60
+# 60. EXPRTest.at:77: expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass)
+at_setup_line='EXPRTest.at:77'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] (pass)"
+at_desc_line=" 60: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "60. EXPRTest.at:77: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:77: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] -f \"dummy\" || true" "EXPRTest.at:77"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.6 -k i[1:4:9] -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:77"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:77: diff -b -B \$abs_srcdir/expr-testsuite/test.6b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.6b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stderr" "EXPRTest.at:77"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.6b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:77"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_60
+#AT_START_61
+# 61. EXPRTest.at:78: expr-test -w $abs_srcdir/expr-testsuite/test.a -k "" -b (pass)
+at_setup_line='EXPRTest.at:78'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass)"
+at_desc_line=" 61: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "61. EXPRTest.at:78: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:78: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k \"\" -b -f \"dummy\" || true" "EXPRTest.at:78"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k "" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:78"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:78: diff -b -B \$abs_srcdir/expr-testsuite/test.a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.a.base stderr" "EXPRTest.at:78"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:78"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_61
+#AT_START_62
+# 62. EXPRTest.at:78: expr-test -W $abs_srcdir/expr-testsuite/test.a -k "" -b (pass)
+at_setup_line='EXPRTest.at:78'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"\" -b (pass)"
+at_desc_line=" 62: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "62. EXPRTest.at:78: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:78: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k \"\" -b -f \"dummy\" || true" "EXPRTest.at:78"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k "" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:78"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:78: diff -b -B \$abs_srcdir/expr-testsuite/test.a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.a.base stderr" "EXPRTest.at:78"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:78"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_62
+#AT_START_63
+# 63. EXPRTest.at:79: expr-test -w $abs_srcdir/expr-testsuite/test.a -k "&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:79'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass)"
+at_desc_line=" 63: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "63. EXPRTest.at:79: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:79: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:79"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k "&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:79"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:79: diff -b -B \$abs_srcdir/expr-testsuite/test.aa.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.aa.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stderr" "EXPRTest.at:79"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:79"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_63
+#AT_START_64
+# 64. EXPRTest.at:79: expr-test -W $abs_srcdir/expr-testsuite/test.a -k "&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:79'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b (pass)"
+at_desc_line=" 64: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "64. EXPRTest.at:79: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:79: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k \"&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:79"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k "&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:79"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:79: diff -b -B \$abs_srcdir/expr-testsuite/test.aa.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.aa.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stderr" "EXPRTest.at:79"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.aa.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:79"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_64
+#AT_START_65
+# 65. EXPRTest.at:80: expr-test -w $abs_srcdir/expr-testsuite/test.a -k "j&i>2000" -b (pass)
+at_setup_line='EXPRTest.at:80'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass)"
+at_desc_line=" 65: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "65. EXPRTest.at:80: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:80: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b -f \"dummy\" || true" "EXPRTest.at:80"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k "j&i>2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:80"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:80: diff -b -B \$abs_srcdir/expr-testsuite/test.ab.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ab.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stderr" "EXPRTest.at:80"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:80"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_65
+#AT_START_66
+# 66. EXPRTest.at:80: expr-test -W $abs_srcdir/expr-testsuite/test.a -k "j&i>2000" -b (pass)
+at_setup_line='EXPRTest.at:80'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b (pass)"
+at_desc_line=" 66: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "66. EXPRTest.at:80: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:80: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k \"j&i>2000\" -b -f \"dummy\" || true" "EXPRTest.at:80"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k "j&i>2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:80"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:80: diff -b -B \$abs_srcdir/expr-testsuite/test.ab.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ab.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stderr" "EXPRTest.at:80"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ab.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:80"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_66
+#AT_START_67
+# 67. EXPRTest.at:81: expr-test -w $abs_srcdir/expr-testsuite/test.a -k "i,j&i<0" -b (pass)
+at_setup_line='EXPRTest.at:81'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass)"
+at_desc_line=" 67: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "67. EXPRTest.at:81: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:81: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b -f \"dummy\" || true" "EXPRTest.at:81"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.a -k "i,j&i<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:81"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:81: diff -b -B \$abs_srcdir/expr-testsuite/test.ac.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ac.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stderr" "EXPRTest.at:81"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:81"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_67
+#AT_START_68
+# 68. EXPRTest.at:81: expr-test -W $abs_srcdir/expr-testsuite/test.a -k "i,j&i<0" -b (pass)
+at_setup_line='EXPRTest.at:81'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b (pass)"
+at_desc_line=" 68: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "68. EXPRTest.at:81: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:81: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k \"i,j&i<0\" -b -f \"dummy\" || true" "EXPRTest.at:81"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.a -k "i,j&i<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:81"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:81: diff -b -B \$abs_srcdir/expr-testsuite/test.ac.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ac.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stderr" "EXPRTest.at:81"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ac.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:81"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_68
+#AT_START_69
+# 69. EXPRTest.at:82: expr-test -w $abs_srcdir/expr-testsuite/test.b -k "" -b (pass)
+at_setup_line='EXPRTest.at:82'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass)"
+at_desc_line=" 69: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "69. EXPRTest.at:82: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:82: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k \"\" -b -f \"dummy\" || true" "EXPRTest.at:82"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:82"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:82: diff -b -B \$abs_srcdir/expr-testsuite/test.b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.b.base stderr" "EXPRTest.at:82"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:82"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_69
+#AT_START_70
+# 70. EXPRTest.at:82: expr-test -W $abs_srcdir/expr-testsuite/test.b -k "" -b (pass)
+at_setup_line='EXPRTest.at:82'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"\" -b (pass)"
+at_desc_line=" 70: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "70. EXPRTest.at:82: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:82: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k \"\" -b -f \"dummy\" || true" "EXPRTest.at:82"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:82"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:82: diff -b -B \$abs_srcdir/expr-testsuite/test.b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.b.base stderr" "EXPRTest.at:82"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:82"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_70
+#AT_START_71
+# 71. EXPRTest.at:83: expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,f" -b (pass)
+at_setup_line='EXPRTest.at:83'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass)"
+at_desc_line=" 71: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "71. EXPRTest.at:83: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:83: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b -f \"dummy\" || true" "EXPRTest.at:83"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,f" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:83"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:83: diff -b -B \$abs_srcdir/expr-testsuite/test.ba.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ba.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stderr" "EXPRTest.at:83"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:83"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_71
+#AT_START_72
+# 72. EXPRTest.at:83: expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,f" -b (pass)
+at_setup_line='EXPRTest.at:83'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b (pass)"
+at_desc_line=" 72: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "72. EXPRTest.at:83: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:83: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k \"i,f\" -b -f \"dummy\" || true" "EXPRTest.at:83"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,f" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:83"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:83: diff -b -B \$abs_srcdir/expr-testsuite/test.ba.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.ba.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stderr" "EXPRTest.at:83"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.ba.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:83"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_72
+#AT_START_73
+# 73. EXPRTest.at:84: expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,f&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:84'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass)"
+at_desc_line=" 73: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "73. EXPRTest.at:84: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:84: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:84"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,f&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:84"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:84: diff -b -B \$abs_srcdir/expr-testsuite/test.bb.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.bb.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stderr" "EXPRTest.at:84"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:84"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_73
+#AT_START_74
+# 74. EXPRTest.at:84: expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,f&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:84'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b (pass)"
+at_desc_line=" 74: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "74. EXPRTest.at:84: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:84: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k \"i,f&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:84"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,f&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:84"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:84: diff -b -B \$abs_srcdir/expr-testsuite/test.bb.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.bb.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stderr" "EXPRTest.at:84"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bb.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:84"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_74
+#AT_START_75
+# 75. EXPRTest.at:85: expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,f&f<0" -b (pass)
+at_setup_line='EXPRTest.at:85'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass)"
+at_desc_line=" 75: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "75. EXPRTest.at:85: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:85: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b -f \"dummy\" || true" "EXPRTest.at:85"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,f&f<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:85"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:85: diff -b -B \$abs_srcdir/expr-testsuite/test.bc.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.bc.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stderr" "EXPRTest.at:85"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:85"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_75
+#AT_START_76
+# 76. EXPRTest.at:85: expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,f&f<0" -b (pass)
+at_setup_line='EXPRTest.at:85'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b (pass)"
+at_desc_line=" 76: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "76. EXPRTest.at:85: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:85: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k \"i,f&f<0\" -b -f \"dummy\" || true" "EXPRTest.at:85"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,f&f<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:85"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:85: diff -b -B \$abs_srcdir/expr-testsuite/test.bc.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.bc.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stderr" "EXPRTest.at:85"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bc.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:85"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_76
+#AT_START_77
+# 77. EXPRTest.at:86: expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,j&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:86'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass)"
+at_desc_line=" 77: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "77. EXPRTest.at:86: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:86: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:86"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "i,j&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:86"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:86: diff -b -B \$abs_srcdir/expr-testsuite/test.bd.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.bd.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stderr" "EXPRTest.at:86"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:86"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_77
+#AT_START_78
+# 78. EXPRTest.at:86: expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,j&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:86'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b (pass)"
+at_desc_line=" 78: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "78. EXPRTest.at:86: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:86: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k \"i,j&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:86"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "i,j&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:86"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:86: diff -b -B \$abs_srcdir/expr-testsuite/test.bd.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.bd.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stderr" "EXPRTest.at:86"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.bd.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:86"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_78
+#AT_START_79
+# 79. EXPRTest.at:87: expr-test -w $abs_srcdir/expr-testsuite/test.b -k "&i<0" -b (pass)
+at_setup_line='EXPRTest.at:87'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass)"
+at_desc_line=" 79: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "79. EXPRTest.at:87: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:87: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b -f \"dummy\" || true" "EXPRTest.at:87"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.b -k "&i<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:87"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:87: diff -b -B \$abs_srcdir/expr-testsuite/test.be.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.be.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.be.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.be.base stderr" "EXPRTest.at:87"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.be.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.be.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:87"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_79
+#AT_START_80
+# 80. EXPRTest.at:87: expr-test -W $abs_srcdir/expr-testsuite/test.b -k "&i<0" -b (pass)
+at_setup_line='EXPRTest.at:87'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b (pass)"
+at_desc_line=" 80: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "80. EXPRTest.at:87: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:87: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k \"&i<0\" -b -f \"dummy\" || true" "EXPRTest.at:87"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.b -k "&i<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:87"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:87: diff -b -B \$abs_srcdir/expr-testsuite/test.be.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.be.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.be.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.be.base stderr" "EXPRTest.at:87"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.be.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.be.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:87"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_80
+#AT_START_81
+# 81. EXPRTest.at:88: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "" -b (pass)
+at_setup_line='EXPRTest.at:88'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass)"
+at_desc_line=" 81: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "81. EXPRTest.at:88: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:88: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"\" -b -f \"dummy\" || true" "EXPRTest.at:88"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:88"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:88: diff -b -B \$abs_srcdir/expr-testsuite/test.d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.d.base stderr" "EXPRTest.at:88"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:88"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_81
+#AT_START_82
+# 82. EXPRTest.at:88: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "" -b (pass)
+at_setup_line='EXPRTest.at:88'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"\" -b (pass)"
+at_desc_line=" 82: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "82. EXPRTest.at:88: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:88: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"\" -b -f \"dummy\" || true" "EXPRTest.at:88"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:88"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:88: diff -b -B \$abs_srcdir/expr-testsuite/test.d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.d.base stderr" "EXPRTest.at:88"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:88"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_82
+#AT_START_83
+# 83. EXPRTest.at:89: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a" -b (pass)
+at_setup_line='EXPRTest.at:89'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass)"
+at_desc_line=" 83: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "83. EXPRTest.at:89: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:89: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b -f \"dummy\" || true" "EXPRTest.at:89"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:89"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:89: diff -b -B \$abs_srcdir/expr-testsuite/test.da.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.da.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.da.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.da.base stderr" "EXPRTest.at:89"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.da.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.da.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:89"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_83
+#AT_START_84
+# 84. EXPRTest.at:89: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a" -b (pass)
+at_setup_line='EXPRTest.at:89'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b (pass)"
+at_desc_line=" 84: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "84. EXPRTest.at:89: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:89: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i,f,a\" -b -f \"dummy\" || true" "EXPRTest.at:89"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:89"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:89: diff -b -B \$abs_srcdir/expr-testsuite/test.da.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.da.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.da.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.da.base stderr" "EXPRTest.at:89"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.da.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.da.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:89"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_84
+#AT_START_85
+# 85. EXPRTest.at:90: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:90'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass)"
+at_desc_line=" 85: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "85. EXPRTest.at:90: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:90: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:90"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:90"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:90: diff -b -B \$abs_srcdir/expr-testsuite/test.db.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.db.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.db.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.db.base stderr" "EXPRTest.at:90"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.db.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.db.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:90"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_85
+#AT_START_86
+# 86. EXPRTest.at:90: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:90'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b (pass)"
+at_desc_line=" 86: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "86. EXPRTest.at:90: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:90: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:90"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:90"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:90: diff -b -B \$abs_srcdir/expr-testsuite/test.db.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.db.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.db.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.db.base stderr" "EXPRTest.at:90"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.db.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.db.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:90"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_86
+#AT_START_87
+# 87. EXPRTest.at:91: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&f<0" -b (pass)
+at_setup_line='EXPRTest.at:91'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass)"
+at_desc_line=" 87: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "87. EXPRTest.at:91: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:91: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b -f \"dummy\" || true" "EXPRTest.at:91"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&f<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:91"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:91: diff -b -B \$abs_srcdir/expr-testsuite/test.dc.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.dc.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stderr" "EXPRTest.at:91"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:91"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_87
+#AT_START_88
+# 88. EXPRTest.at:91: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&f<0" -b (pass)
+at_setup_line='EXPRTest.at:91'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b (pass)"
+at_desc_line=" 88: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "88. EXPRTest.at:91: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:91: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&f<0\" -b -f \"dummy\" || true" "EXPRTest.at:91"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&f<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:91"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:91: diff -b -B \$abs_srcdir/expr-testsuite/test.dc.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.dc.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stderr" "EXPRTest.at:91"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dc.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:91"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_88
+#AT_START_89
+# 89. EXPRTest.at:92: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&a<10" -b (pass)
+at_setup_line='EXPRTest.at:92'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass)"
+at_desc_line=" 89: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "89. EXPRTest.at:92: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:92: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b -f \"dummy\" || true" "EXPRTest.at:92"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&a<10" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:92"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:92: diff -b -B \$abs_srcdir/expr-testsuite/test.dd.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.dd.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stderr" "EXPRTest.at:92"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:92"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_89
+#AT_START_90
+# 90. EXPRTest.at:92: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&a<10" -b (pass)
+at_setup_line='EXPRTest.at:92'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b (pass)"
+at_desc_line=" 90: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "90. EXPRTest.at:92: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:92: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&a<10\" -b -f \"dummy\" || true" "EXPRTest.at:92"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&a<10" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:92"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:92: diff -b -B \$abs_srcdir/expr-testsuite/test.dd.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.dd.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stderr" "EXPRTest.at:92"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dd.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:92"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_90
+#AT_START_91
+# 91. EXPRTest.at:93: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:93'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass)"
+at_desc_line=" 91: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "91. EXPRTest.at:93: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:93: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:93"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:93"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:93: diff -b -B \$abs_srcdir/expr-testsuite/test.de.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.de.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.de.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.de.base stderr" "EXPRTest.at:93"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.de.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.de.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:93"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_91
+#AT_START_92
+# 92. EXPRTest.at:93: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:93'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b (pass)"
+at_desc_line=" 92: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "92. EXPRTest.at:93: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:93: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i,f&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:93"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:93"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:93: diff -b -B \$abs_srcdir/expr-testsuite/test.de.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.de.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.de.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.de.base stderr" "EXPRTest.at:93"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.de.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.de.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:93"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_92
+#AT_START_93
+# 93. EXPRTest.at:94: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:94'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass)"
+at_desc_line=" 93: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "93. EXPRTest.at:94: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:94: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:94"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:94"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:94: diff -b -B \$abs_srcdir/expr-testsuite/test.df.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.df.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.df.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.df.base stderr" "EXPRTest.at:94"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.df.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.df.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:94"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_93
+#AT_START_94
+# 94. EXPRTest.at:94: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i&i<2000" -b (pass)
+at_setup_line='EXPRTest.at:94'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b (pass)"
+at_desc_line=" 94: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "94. EXPRTest.at:94: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:94: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i&i<2000\" -b -f \"dummy\" || true" "EXPRTest.at:94"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i&i<2000" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:94"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:94: diff -b -B \$abs_srcdir/expr-testsuite/test.df.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.df.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.df.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.df.base stderr" "EXPRTest.at:94"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.df.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.df.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:94"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_94
+#AT_START_95
+# 95. EXPRTest.at:95: expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<0" -b (pass)
+at_setup_line='EXPRTest.at:95'
+at_desc="expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass)"
+at_desc_line=" 95: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "95. EXPRTest.at:95: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:95: \$abs_builddir/expr-test -w \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b -f \"dummy\" || true" "EXPRTest.at:95"
+( $at_check_trace; $abs_builddir/expr-test -w $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:95"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:95: diff -b -B \$abs_srcdir/expr-testsuite/test.dg.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.dg.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stderr" "EXPRTest.at:95"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:95"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_95
+#AT_START_96
+# 96. EXPRTest.at:95: expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<0" -b (pass)
+at_setup_line='EXPRTest.at:95'
+at_desc="expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b (pass)"
+at_desc_line=" 96: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "96. EXPRTest.at:95: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:95: \$abs_builddir/expr-test -W \$abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k \"i,f,a&i<0\" -b -f \"dummy\" || true" "EXPRTest.at:95"
+( $at_check_trace; $abs_builddir/expr-test -W $abs_srcdir/expr-testsuite/test.d -k "i,f,a&i<0" -b -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:95"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:95: diff -b -B \$abs_srcdir/expr-testsuite/test.dg.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/test.dg.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stderr" "EXPRTest.at:95"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stdout || diff -b -B $abs_srcdir/expr-testsuite/test.dg.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:95"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_96
+#AT_START_97
+# 97. EXPRTest.at:97: expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k i (pass)
+at_setup_line='EXPRTest.at:97'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k i (pass)"
+at_desc_line=" 97: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "97. EXPRTest.at:97: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:97: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k i -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k i -f \"dummy\" || true" "EXPRTest.at:97"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k i -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:97"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:97: diff -b -B \$abs_srcdir/expr-testsuite/data.61a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stderr" "EXPRTest.at:97"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:97"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_97
+#AT_START_98
+# 98. EXPRTest.at:97: expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k i (pass)
+at_setup_line='EXPRTest.at:97'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k i (pass)"
+at_desc_line=" 98: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "98. EXPRTest.at:97: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:97: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k i -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k i -f \"dummy\" || true" "EXPRTest.at:97"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k i -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:97"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:97: diff -b -B \$abs_srcdir/expr-testsuite/data.61a.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61a.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stderr" "EXPRTest.at:97"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61a.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:97"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_98
+#AT_START_99
+# 99. EXPRTest.at:98: expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)
+at_setup_line='EXPRTest.at:98'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)"
+at_desc_line=" 99: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "99. EXPRTest.at:98: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:98: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  -f \"dummy\" || true" "EXPRTest.at:98"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:98"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:98: diff -b -B \$abs_srcdir/expr-testsuite/data.61b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stderr" "EXPRTest.at:98"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:98"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_99
+#AT_START_100
+# 100. EXPRTest.at:98: expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)
+at_setup_line='EXPRTest.at:98'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  (pass)"
+at_desc_line="100: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "100. EXPRTest.at:98: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:98: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  -f \"dummy\" || true" "EXPRTest.at:98"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[0:2][0:2]  -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:98"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:98: diff -b -B \$abs_srcdir/expr-testsuite/data.61b.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61b.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stderr" "EXPRTest.at:98"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61b.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:98"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_100
+#AT_START_101
+# 101. EXPRTest.at:99: expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)
+at_setup_line='EXPRTest.at:99'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)"
+at_desc_line="101: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "101. EXPRTest.at:99: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:99: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  -f \"dummy\" || true" "EXPRTest.at:99"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:99"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:99: diff -b -B \$abs_srcdir/expr-testsuite/data.61c.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61c.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stderr" "EXPRTest.at:99"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:99"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_101
+#AT_START_102
+# 102. EXPRTest.at:99: expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)
+at_setup_line='EXPRTest.at:99'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  (pass)"
+at_desc_line="102: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "102. EXPRTest.at:99: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:99: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  -f \"dummy\" || true" "EXPRTest.at:99"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][0:2]  -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:99"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:99: diff -b -B \$abs_srcdir/expr-testsuite/data.61c.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61c.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stderr" "EXPRTest.at:99"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61c.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:99"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_102
+#AT_START_103
+# 103. EXPRTest.at:100: expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)
+at_setup_line='EXPRTest.at:100'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)"
+at_desc_line="103: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "103. EXPRTest.at:100: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:100: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  -f \"dummy\" || true" "EXPRTest.at:100"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:100"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:100: diff -b -B \$abs_srcdir/expr-testsuite/data.61d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stderr" "EXPRTest.at:100"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:100"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_103
+#AT_START_104
+# 104. EXPRTest.at:100: expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)
+at_setup_line='EXPRTest.at:100'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  (pass)"
+at_desc_line="104: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "104. EXPRTest.at:100: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:100: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  -f \"dummy\" || true" "EXPRTest.at:100"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.61 -k  i[1:2][1:2]  -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:100"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:100: diff -b -B \$abs_srcdir/expr-testsuite/data.61d.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.61d.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stderr" "EXPRTest.at:100"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.61d.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:100"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_104
+#AT_START_105
+# 105. EXPRTest.at:101: expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST)" (pass)
+at_setup_line='EXPRTest.at:101'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" (pass)"
+at_desc_line="105: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "105. EXPRTest.at:101: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:101: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" -f \"dummy\" || true" "EXPRTest.at:101"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:101"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:101: diff -b -B \$abs_srcdir/expr-testsuite/data.z0.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z0.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stderr" "EXPRTest.at:101"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:101"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_105
+#AT_START_106
+# 106. EXPRTest.at:101: expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST)" (pass)
+at_setup_line='EXPRTest.at:101'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" (pass)"
+at_desc_line="106: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "106. EXPRTest.at:101: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:101: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST)\" -f \"dummy\" || true" "EXPRTest.at:101"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:101"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:101: diff -b -B \$abs_srcdir/expr-testsuite/data.z0.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z0.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stderr" "EXPRTest.at:101"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z0.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:101"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_106
+#AT_START_107
+# 107. EXPRTest.at:102: expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k SST (pass)
+at_setup_line='EXPRTest.at:102'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass)"
+at_desc_line="107: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "107. EXPRTest.at:102: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:102: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k SST -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k SST -f \"dummy\" || true" "EXPRTest.at:102"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k SST -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:102"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:102: diff -b -B \$abs_srcdir/expr-testsuite/data.z1.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z1.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stderr" "EXPRTest.at:102"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:102"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_107
+#AT_START_108
+# 108. EXPRTest.at:102: expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k SST (pass)
+at_setup_line='EXPRTest.at:102'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST (pass)"
+at_desc_line="108: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "108. EXPRTest.at:102: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:102: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k SST -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k SST -f \"dummy\" || true" "EXPRTest.at:102"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k SST -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:102"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:102: diff -b -B \$abs_srcdir/expr-testsuite/data.z1.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z1.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stderr" "EXPRTest.at:102"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z1.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:102"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_108
+#AT_START_109
+# 109. EXPRTest.at:104: expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:104'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="109: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "109. EXPRTest.at:104: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:104: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:104"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:104"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:104: diff -b -B \$abs_srcdir/expr-testsuite/data.z2.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z2.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stderr" "EXPRTest.at:104"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:104"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_109
+#AT_START_110
+# 110. EXPRTest.at:104: expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:104'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="110: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "110. EXPRTest.at:104: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:104: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:104"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c0 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:104"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:104: diff -b -B \$abs_srcdir/expr-testsuite/data.z2.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z2.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stderr" "EXPRTest.at:104"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z2.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:104"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_110
+#AT_START_111
+# 111. EXPRTest.at:105: expr-test -b -w $abs_srcdir/expr-testsuite/test.c1 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:105'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="111: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "111. EXPRTest.at:105: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:105: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:105"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c1 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:105"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:105: diff -b -B \$abs_srcdir/expr-testsuite/data.z3.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z3.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stderr" "EXPRTest.at:105"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:105"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_111
+#AT_START_112
+# 112. EXPRTest.at:105: expr-test -b -W $abs_srcdir/expr-testsuite/test.c1 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:105'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="112: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "112. EXPRTest.at:105: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:105: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c1 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:105"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c1 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:105"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:105: diff -b -B \$abs_srcdir/expr-testsuite/data.z3.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z3.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stderr" "EXPRTest.at:105"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z3.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:105"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_112
+#AT_START_113
+# 113. EXPRTest.at:106: expr-test -b -w $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:106'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="113: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "113. EXPRTest.at:106: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:106: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:106"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:106"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:106: diff -b -B \$abs_srcdir/expr-testsuite/data.z4.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z4.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stderr" "EXPRTest.at:106"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:106"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_113
+#AT_START_114
+# 114. EXPRTest.at:106: expr-test -b -W $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:106'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="114: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "114. EXPRTest.at:106: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:106: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:106"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:106"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:106: diff -b -B \$abs_srcdir/expr-testsuite/data.z4.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z4.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stderr" "EXPRTest.at:106"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z4.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:106"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_114
+#AT_START_115
+# 115. EXPRTest.at:107: expr-test -b -w $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160,\"time=1024\")" (pass)
+at_setup_line='EXPRTest.at:107'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass)"
+at_desc_line="115: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "115. EXPRTest.at:107: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:107: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true" "EXPRTest.at:107"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160,\"time=1024\")" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:107"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:107: diff -b -B \$abs_srcdir/expr-testsuite/data.z5.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z5.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stderr" "EXPRTest.at:107"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:107"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_115
+#AT_START_116
+# 116. EXPRTest.at:107: expr-test -b -W $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160,\"time=1024\")" (pass)
+at_setup_line='EXPRTest.at:107'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass)"
+at_desc_line="116: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "116. EXPRTest.at:107: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:107: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c2 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true" "EXPRTest.at:107"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c2 -k "geogrid(SST,61,97,38,160,\"time=1024\")" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:107"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:107: diff -b -B \$abs_srcdir/expr-testsuite/data.z5.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z5.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stderr" "EXPRTest.at:107"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z5.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:107"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_116
+#AT_START_117
+# 117. EXPRTest.at:108: expr-test -b -w $abs_srcdir/expr-testsuite/test.c3 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:108'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="117: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "117. EXPRTest.at:108: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:108: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:108"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c3 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:108"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:108: diff -b -B \$abs_srcdir/expr-testsuite/data.z6.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z6.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stderr" "EXPRTest.at:108"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:108"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_117
+#AT_START_118
+# 118. EXPRTest.at:108: expr-test -b -W $abs_srcdir/expr-testsuite/test.c3 -k "geogrid(SST,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:108'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" (pass)"
+at_desc_line="118: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "118. EXPRTest.at:108: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:108: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c3 -k \"geogrid(SST,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:108"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c3 -k "geogrid(SST,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:108"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:108: diff -b -B \$abs_srcdir/expr-testsuite/data.z6.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z6.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stderr" "EXPRTest.at:108"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z6.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:108"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_118
+#AT_START_119
+# 119. EXPRTest.at:109: expr-test -b -w $abs_srcdir/expr-testsuite/test.c4 -k "geogrid(SST,61,97,38,160,\"time=1024\")" (pass)
+at_setup_line='EXPRTest.at:109'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass)"
+at_desc_line="119: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "119. EXPRTest.at:109: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:109: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true" "EXPRTest.at:109"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c4 -k "geogrid(SST,61,97,38,160,\"time=1024\")" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:109"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:109: diff -b -B \$abs_srcdir/expr-testsuite/data.z7.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z7.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stderr" "EXPRTest.at:109"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:109"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_119
+#AT_START_120
+# 120. EXPRTest.at:109: expr-test -b -W $abs_srcdir/expr-testsuite/test.c4 -k "geogrid(SST,61,97,38,160,\"time=1024\")" (pass)
+at_setup_line='EXPRTest.at:109'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" (pass)"
+at_desc_line="120: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "120. EXPRTest.at:109: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:109: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c4 -k \"geogrid(SST,61,97,38,160,\\\"time=1024\\\")\" -f \"dummy\" || true" "EXPRTest.at:109"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c4 -k "geogrid(SST,61,97,38,160,\"time=1024\")" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:109"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:109: diff -b -B \$abs_srcdir/expr-testsuite/data.z7.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z7.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stderr" "EXPRTest.at:109"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z7.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:109"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_120
+#AT_START_121
+# 121. EXPRTest.at:110: expr-test -b -w $abs_srcdir/expr-testsuite/test.c5 -k "geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:110'
+at_desc="expr-test -b -w \$abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" (pass)"
+at_desc_line="121: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "121. EXPRTest.at:110: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:110: \$abs_builddir/expr-test -b -w \$abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:110"
+( $at_check_trace; $abs_builddir/expr-test -b -w $abs_srcdir/expr-testsuite/test.c5 -k "geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:110"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:110: diff -b -B \$abs_srcdir/expr-testsuite/data.z8.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z8.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stderr" "EXPRTest.at:110"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:110"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_121
+#AT_START_122
+# 122. EXPRTest.at:110: expr-test -b -W $abs_srcdir/expr-testsuite/test.c5 -k "geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)" (pass)
+at_setup_line='EXPRTest.at:110'
+at_desc="expr-test -b -W \$abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" (pass)"
+at_desc_line="122: $at_desc"
+$at_quiet $as_echo_n "$at_desc_line"
+at_xfail=no
+      test "pass" = "xfail" && at_xfail=yes
+echo "#                             -*- compilation -*-" >> "$at_group_log"
+(
+  $as_echo "122. EXPRTest.at:110: testing ..."
+  $at_traceon
+
+
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:110: \$abs_builddir/expr-test -b -W \$abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" -f \"dummy\" || true"
+at_fn_check_prepare_dynamic "$abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c5 -k \"geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)\" -f \"dummy\" || true" "EXPRTest.at:110"
+( $at_check_trace; $abs_builddir/expr-test -b -W $abs_srcdir/expr-testsuite/test.c5 -k "geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)" -f "dummy" || true
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+echo stderr:; tee stderr <"$at_stderr"
+echo stdout:; tee stdout <"$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:110"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+    { set +x
+$as_echo "$at_srcdir/EXPRTest.at:110: diff -b -B \$abs_srcdir/expr-testsuite/data.z8.base stdout || diff -b -B \$abs_srcdir/expr-testsuite/data.z8.base stderr"
+at_fn_check_prepare_dynamic "diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stderr" "EXPRTest.at:110"
+( $at_check_trace; diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stdout || diff -b -B $abs_srcdir/expr-testsuite/data.z8.base stderr
+) >>"$at_stdout" 2>>"$at_stderr"
+at_status=$? at_failed=false
+$at_check_filter
+at_fn_diff_devnull "$at_stderr" || at_failed=:
+echo stdout:; cat "$at_stdout"
+at_fn_check_status 0 $at_status "$at_srcdir/EXPRTest.at:110"
+$at_failed && at_fn_log_failure
+$at_traceon; }
+
+
+      set +x
+  $at_times_p && times >"$at_times_file"
+) 5>&1 2>&1 | eval $at_tee_pipe
+read at_status <"$at_status_file"
+#AT_STOP_122
diff --git a/tests/EXPRTest.at b/tests/EXPRTest.at
new file mode 100644
index 0000000..14db4c2
--- /dev/null
+++ b/tests/EXPRTest.at
@@ -0,0 +1,124 @@
+# Process with autom4te to create an -*- Autotest -*- test suite.
+
+AT_INIT([expr-test])
+# AT_COPYRIGHT([])
+
+# AT_TESTED([expr-test])
+
+# Usage: _EXPR_TEST(<flags>, <dds>, <constraint>, <baseline file>, <xfail?>)
+
+m4_define([_EXPR_TEST], [
+    # AT_BANNER([Test $1 $2 $3])
+    AT_SETUP([expr-test $1 $2 -k $3 ($5)])
+    AT_KEYWORDS([expr])
+
+    # Added || true because expr-test returns 0 (failure) for some of
+    # these tests which is correct for the test - we expect some of
+    # the input to trigger an error response from the parser, et
+    # cetera. That's also why we capture both stdout and stderr -
+    # successful runs are sent to stdout while the errors are sent to
+    # stderr.
+
+    AT_CHECK([$abs_builddir/expr-test $1 $2 -k $3 -f "dummy" || true], [], [stdout], [stderr])
+    AT_CHECK([diff -b -B $4 stdout || diff -b -B $4 stderr], [], [ignore],[],[])
+    AT_XFAIL_IF([test "$5" = "xfail"])
+    AT_CLEANUP
+])
+
+
+m4_define([EXPR_RESPONSE_P], [
+    # AT_BANNER([EXPR response for $1, $2, $4.])
+    # Test the serialize/deserialize methods
+    _EXPR_TEST([-w], [$abs_srcdir/expr-testsuite/$1], [$2], [$abs_srcdir/expr-testsuite/$3.base], $4)
+    # Test the intern_data method (which combines serialize and deserialze)
+    _EXPR_TEST([-W], [$abs_srcdir/expr-testsuite/$1], [$2], [$abs_srcdir/expr-testsuite/$3.base], $4)
+])
+
+# The -b option to expr-test uses the 'series values' feature of the Test
+# classes.
+m4_define([EXPR_RESPONSE_B], [
+    # AT_BANNER([EXPR response for $1, $2, $4.])
+    _EXPR_TEST([-b -w], [$abs_srcdir/expr-testsuite/$1], [$2], [$abs_srcdir/expr-testsuite/$3.base], $4)
+    _EXPR_TEST([-b -W], [$abs_srcdir/expr-testsuite/$1], [$2], [$abs_srcdir/expr-testsuite/$3.base], $4)
+])
+
+EXPR_RESPONSE_P([test.1], [i], [test.1], [pass])
+EXPR_RESPONSE_P([test.1], [i,j], [test.1a], [pass])
+EXPR_RESPONSE_P([test.1], ['i,j&i=j'], [test.1b], [pass])
+EXPR_RESPONSE_P([test.1], ['i&i=j'], [test.1d], [pass])
+EXPR_RESPONSE_P([test.2], [s1], [test.2], [pass])
+EXPR_RESPONSE_P([test.2], [s2], [test.2a], [pass])
+EXPR_RESPONSE_P([test.2], [s2,s3], [test.2b], [pass])
+EXPR_RESPONSE_P([test.2], [s2[[2:2:4]],s3.o], [test.2c], [pass])
+
+EXPR_RESPONSE_P([test.2], [s2[[2:2:4]].m], [test.2d], [pass])
+EXPR_RESPONSE_P([test.2], [s2[[2:2:4]].m,s2[[2:2:4]].l], [test.2e], [pass])
+
+EXPR_RESPONSE_P([test.2a], [s2[[2:4]].m[[0:4]],s2[[2:4]].l[[0:5]]], [test.2f], [pass])
+EXPR_RESPONSE_P([test.3], [i[[1:10]]], [test.3], [pass])
+EXPR_RESPONSE_P([test.4], ['s&s=~"^Silly.*"'], [test.4], [pass])
+
+EXPR_RESPONSE_P([test.e], ['names.s&names.s=~".*: 3"'], [test.ea], [pass])
+EXPR_RESPONSE_P([test.e], ['names.s&names.s=~".*: 5"'], [test.eb], [pass])
+EXPR_RESPONSE_P([test.5], [g[[0:2:4]][[0]][[0]]], [test.5], [pass])
+EXPR_RESPONSE_P([test.5], [g[[0:2:4]][[0:2:4]][[0:2:4]]], [test.5a], [pass])
+EXPR_RESPONSE_P([test.6], [i], [test.6], [pass])
+EXPR_RESPONSE_P([test.6], [i[[1:2]][[2:4]]], [test.6a], [pass])
+EXPR_RESPONSE_P([test.5], [g.val[[0:1]][[0:1]][[0:1]]], [test.5b], [pass])
+EXPR_RESPONSE_P([test.5], [g.length], [test.5c], [pass])
+EXPR_RESPONSE_P([test.5], [g.length,g.width], [test.5d], [pass])
+EXPR_RESPONSE_P([test.2], [j,o], [test.2g], [pass])
+EXPR_RESPONSE_P([test.8], ["data%23i[[0:2:9]][[0:2]]"], [test.8], [pass])
+EXPR_RESPONSE_P([test.7], [x,y,f], [test.7], [pass])
+EXPR_RESPONSE_P([test.8], ["x%23y,y"], [test.8a], [pass])
+EXPR_RESPONSE_P([test.8], ["data%20name,y"], [test.8b], [pass])
+EXPR_RESPONSE_P([test.9], ["Data-Set-2.fakeDim0[[0:3]],Data-Set-2.fakeDim1[[0:3]]"], [test.9], [pass])
+EXPR_RESPONSE_P([test.5], [g[[1:4:9]]], [test.5e], [pass])
+EXPR_RESPONSE_P([test.6], [i[[1:4:9]]], [test.6b], [pass])
+EXPR_RESPONSE_P([test.a], ["" -b], [test.a], [pass])
+EXPR_RESPONSE_P([test.a], ["&i<2000" -b], [test.aa], [pass])
+EXPR_RESPONSE_P([test.a], ["j&i>2000" -b], [test.ab], [pass])
+EXPR_RESPONSE_P([test.a], ["i,j&i<0" -b], [test.ac], [pass])
+EXPR_RESPONSE_P([test.b], ["" -b], [test.b], [pass])
+EXPR_RESPONSE_P([test.b], ["i,f" -b], [test.ba], [pass])
+EXPR_RESPONSE_P([test.b], ["i,f&i<2000" -b], [test.bb], [pass])
+EXPR_RESPONSE_P([test.b], ["i,f&f<0" -b], [test.bc], [pass])
+EXPR_RESPONSE_P([test.b], ["i,j&i<2000" -b], [test.bd], [pass])
+EXPR_RESPONSE_P([test.b], ["&i<0" -b], [test.be], [pass])
+EXPR_RESPONSE_P([test.d], ["" -b], [test.d], [pass])
+EXPR_RESPONSE_P([test.d], ["i,f,a" -b], [test.da], [pass])
+EXPR_RESPONSE_P([test.d], ["i,f,a&i<2000" -b], [test.db], [pass])
+EXPR_RESPONSE_P([test.d], ["i,f,a&f<0" -b], [test.dc], [pass])
+EXPR_RESPONSE_P([test.d], ["i,f,a&a<10" -b], [test.dd], [pass])
+EXPR_RESPONSE_P([test.d], ["i,f&i<2000" -b], [test.de], [pass])
+EXPR_RESPONSE_P([test.d], ["i&i<2000" -b], [test.df], [pass])
+EXPR_RESPONSE_P([test.d], ["i,f,a&i<0" -b], [test.dg], [pass])
+
+EXPR_RESPONSE_B([test.61], [i], [data.61a], [pass])
+EXPR_RESPONSE_B([test.61], [ i[[0:2]][[0:2]] ], [data.61b], [pass])
+EXPR_RESPONSE_B([test.61], [ i[[1:2]][[0:2]] ], [data.61c], [pass])
+EXPR_RESPONSE_B([test.61], [ i[[1:2]][[1:2]] ], [data.61d], [pass])
+EXPR_RESPONSE_B([test.c0], ["geogrid(SST)"], [data.z0], [pass])
+EXPR_RESPONSE_B([test.c0], [SST], [data.z1], [pass])
+
+EXPR_RESPONSE_B([test.c0], ["geogrid(SST,61,97,38,160)"], [data.z2], [pass])
+EXPR_RESPONSE_B([test.c1], ["geogrid(SST,61,97,38,160)"], [data.z3], [pass])
+EXPR_RESPONSE_B([test.c2], ["geogrid(SST,61,97,38,160)"], [data.z4], [pass])
+EXPR_RESPONSE_B([test.c2], ["geogrid(SST,61,97,38,160,\"time=1024\")"], [data.z5], [pass])
+EXPR_RESPONSE_B([test.c3], ["geogrid(SST,61,97,38,160)"], [data.z6], [pass])
+EXPR_RESPONSE_B([test.c4], ["geogrid(SST,61,97,38,160,\"time=1024\")"], [data.z7], [pass])
+EXPR_RESPONSE_B([test.c5], ["geogrid(SST,61,97,38,160),geogrid(AIRT,61,97,38,160)"], [data.z8], [pass])
+
+# EXPR_RESPONSE_B([test.c0], ["geogrid(SST,lat,lon,61,97,38,160)"], [data.z2], [pass])
+# EXPR_RESPONSE_B([test.c1], ["geogrid(SST,lat_reversed,lon,61,97,38,160)"], [data.z3], [pass])
+# EXPR_RESPONSE_B([test.c2], ["geogrid(SST,lat,lon,61,97,38,160)"], [data.z4], [pass])
+# EXPR_RESPONSE_B([test.c2], ["geogrid(SST,lat,lon,61,97,38,160,\"time=1024\")"], [data.z5], [pass])
+# EXPR_RESPONSE_B([test.c3], ["geogrid(SST,lat,lon,61,97,38,160)"], [data.z6], [pass])
+# EXPR_RESPONSE_B([test.c4], ["geogrid(SST,lat,lon,61,97,38,160,\"time=1024\")"], [data.z7], [pass])
+
+# EXPR_RESPONSE_B([test.cc0], ["geoarray(SST)"], [data.zz0], [pass])
+# EXPR_RESPONSE_B([test.cc0], ["geoarray(SST,90,0,-90,359,90,0,-90,359)"], [data.zz1], [pass])
+# EXPR_RESPONSE_B([test.cc0], ["geoarray(SST,45,135,-45,225,90,0,-90,359)"], [data.zz2], [pass])
+# EXPR_RESPONSE_B([test.cc0], ["geoarray(SST,45,-45,-45,45,90,0,-90,359)"], [data.zz2], [pass])
+# EXPR_RESPONSE_B([test.cc0], ["geoarray(SST,45,135,-45,225,90,-180,-90,179)"], [data.zz2], [pass])
+# EXPR_RESPONSE_B([test.cc0], ["geoarray(SST,45,-45,-45,45,90,-180,-90,179)"], [data.zz2], [pass])
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 0000000..72c0f73
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,113 @@
+# Tests
+
+AUTOMAKE_OPTIONS = foreign
+
+# Arrange to build with the backward compatibility mode enabled.
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU
+AM_CXXFLAGS =  
+
+# These are not used by automake but are often useful for certain types of
+# debugging. 
+CXXFLAGS_DEBUG = -g3 -O0 -fno-defer-pop -Wall -W -Wcast-align -Werror
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+
+check_PROGRAMS = das-test dds-test expr-test 
+# noinst_PROGRAMS = io_test
+
+TESTS = DASTest DDSTest EXPRTest
+# EXPRTest
+
+dist_check_SCRIPTS = DASTest DDSTest EXPRTest atconfig atlocal
+
+##CLEANFILES = *.log *.sum
+
+# Build the test drivers. The drivers all use the
+# subclassed types in Test*.cc and the TestTypesFactory.
+
+noinst_LIBRARIES = libtest-types.a
+
+libtest_types_a_SOURCES = $(TESTSRCS) $(TEST_HDR)
+
+# io_test_SOURCES = io_test.cc
+# io_test_LDADD = ../libdap.la
+
+das_test_SOURCES = das-test.cc
+das_test_LDADD =  libtest-types.a ../libdapserver.la ../libdap.la 
+
+dds_test_SOURCES = dds-test.cc
+dds_test_LDADD = libtest-types.a ../libdapserver.la ../libdap.la 
+
+expr_test_SOURCES = expr-test.cc
+expr_test_LDADD = libtest-types.a ../libdapserver.la ../libdapclient.la ../libdap.la
+
+TESTSRCS = TestByte.cc TestInt32.cc TestFloat64.cc TestStr.cc TestUrl.cc \
+	   TestArray.cc TestStructure.cc TestSequence.cc		 \
+	   TestGrid.cc TestUInt32.cc TestInt16.cc TestUInt16.cc		 \
+	   TestFloat32.cc TestCommon.cc TestTypeFactory.cc
+
+TEST_HDR = TestArray.h TestByte.h TestCommon.h TestFloat32.h TestFloat64.h    \
+	TestGrid.h TestInt16.h TestInt32.h TestSequence.h TestStr.h	      \
+	TestStructure.h TestTypeFactory.h TestUInt16.h TestUInt32.h TestUrl.h
+
+DIRS_EXTRA = das-testsuite dds-testsuite expr-testsuite 
+
+# grid-func-testsuite cache-testsuite ais_testsuite rcreader-testsuite 
+# server-testsuite cgi-util-tests
+# ddx-testsuite	  
+
+EXTRA_DIST = DASTest.at  $(DASTESTSUITE) DDSTest.at  $(DDSTESTSUITE) \
+	EXPRTest.at $(EXPRTESTSUITE) atlocal.in $(srcdir)/package.m4 \
+	$(DIRS_EXTRA)
+
+DISTCLEANFILES = *.log DASTest.dir/* DDSTest.dir/* EXPRTest.dir/*
+
+############## Autotest follows #####################
+
+AUTOM4TE = autom4te
+
+DASTESTSUITE = $(srcdir)/DASTest 
+DASTESTSUITEFLAGS =
+DDSTESTSUITE = $(srcdir)/DDSTest 
+DDSTESTSUITEFLAGS =
+EXPRTESTSUITE = $(srcdir)/EXPRTest 
+EXPRTESTSUITEFLAGS =
+
+#check-local: check-das check-dds
+
+#check-das: atconfig atlocal $(DASTESTSUITE)
+#	$(SHELL) $(DASTESTSUITE) $(DASTESTSUITEFLAGS)
+
+#check-dds: atconfig atlocal $(DDSTESTSUITE)
+#	$(SHELL) $(DDSTESTSUITE) $(DDSTESTSUITEFLAGS)
+
+clean-local:
+	test ! -f '$(DASTESTSUITE)' || $(SHELL) $(DASTESTSUITE) --clean
+	test ! -f '$(DDSTESTSUITE)' || $(SHELL) $(DDSTESTSUITE) --clean
+
+distclean-local:
+	-rm atconfig
+
+AUTOTEST = $(AUTOM4TE) --language=autotest
+$(DASTESTSUITE): $(srcdir)/DASTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+$(DDSTESTSUITE): $(srcdir)/DDSTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+$(EXPRTESTSUITE): $(srcdir)/EXPRTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+# The `:;' works around a Bash 3.2 bug when the output is not writable.
+$(srcdir)/package.m4: $(top_srcdir)/configure.ac
+	:;{ \
+	echo '# Signature of the current package.' && \
+	echo 'm4_define([AT_PACKAGE_NAME],      [@PACKAGE_NAME@])' && \
+	echo 'm4_define([AT_PACKAGE_TARNAME],   [@PACKAGE_TARNAME@])' && \
+	echo 'm4_define([AT_PACKAGE_VERSION],   [@PACKAGE_VERSION@])' && \
+	echo 'm4_define([AT_PACKAGE_STRING],    [@PACKAGE_STRING@])' && \
+	echo 'm4_define([AT_PACKAGE_BUGREPORT], [@PACKAGE_BUGREPORT@])'; \
+	} >'$(srcdir)/package.m4'
+
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..6c7e5a6
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,1082 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+# Tests
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+check_PROGRAMS = das-test$(EXEEXT) dds-test$(EXEEXT) \
+	expr-test$(EXEEXT)
+subdir = tests
+DIST_COMMON = README $(dist_check_SCRIPTS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in $(srcdir)/atlocal.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
+	$(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/btowc.m4 \
+	$(top_srcdir)/gl/m4/codeset.m4 \
+	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/fcntl-o.m4 $(top_srcdir)/gl/m4/glibc21.m4 \
+	$(top_srcdir)/gl/m4/gnulib-common.m4 \
+	$(top_srcdir)/gl/m4/gnulib-comp.m4 \
+	$(top_srcdir)/gl/m4/gnulib-tool.m4 \
+	$(top_srcdir)/gl/m4/include_next.m4 \
+	$(top_srcdir)/gl/m4/langinfo_h.m4 \
+	$(top_srcdir)/gl/m4/localcharset.m4 \
+	$(top_srcdir)/gl/m4/locale-fr.m4 \
+	$(top_srcdir)/gl/m4/locale-ja.m4 \
+	$(top_srcdir)/gl/m4/locale-zh.m4 \
+	$(top_srcdir)/gl/m4/longlong.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+	$(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+	$(top_srcdir)/gl/m4/mbstate_t.m4 \
+	$(top_srcdir)/gl/m4/multiarch.m4 \
+	$(top_srcdir)/gl/m4/nl_langinfo.m4 \
+	$(top_srcdir)/gl/m4/regex.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+	$(top_srcdir)/gl/m4/stdbool.m4 $(top_srcdir)/gl/m4/stddef_h.m4 \
+	$(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/stdlib_h.m4 \
+	$(top_srcdir)/gl/m4/unistd_h.m4 \
+	$(top_srcdir)/gl/m4/warn-on-use.m4 \
+	$(top_srcdir)/gl/m4/wchar_h.m4 $(top_srcdir)/gl/m4/wchar_t.m4 \
+	$(top_srcdir)/gl/m4/wcrtomb.m4 $(top_srcdir)/gl/m4/wctype_h.m4 \
+	$(top_srcdir)/gl/m4/wint_t.m4 $(top_srcdir)/conf/acinclude.m4 \
+	$(top_srcdir)/conf/check_zlib.m4 $(top_srcdir)/conf/cppunit.m4 \
+	$(top_srcdir)/conf/libtool.m4 $(top_srcdir)/conf/ltoptions.m4 \
+	$(top_srcdir)/conf/ltsugar.m4 $(top_srcdir)/conf/ltversion.m4 \
+	$(top_srcdir)/conf/lt~obsolete.m4 $(top_srcdir)/conf/pkg.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+	$(top_builddir)/dods-datatypes-config.h \
+	$(top_builddir)/xdr-datatypes-config.h
+CONFIG_CLEAN_FILES = atlocal
+CONFIG_CLEAN_VPATH_FILES =
+LIBRARIES = $(noinst_LIBRARIES)
+ARFLAGS = cru
+libtest_types_a_AR = $(AR) $(ARFLAGS)
+libtest_types_a_LIBADD =
+am__objects_1 = TestByte.$(OBJEXT) TestInt32.$(OBJEXT) \
+	TestFloat64.$(OBJEXT) TestStr.$(OBJEXT) TestUrl.$(OBJEXT) \
+	TestArray.$(OBJEXT) TestStructure.$(OBJEXT) \
+	TestSequence.$(OBJEXT) TestGrid.$(OBJEXT) TestUInt32.$(OBJEXT) \
+	TestInt16.$(OBJEXT) TestUInt16.$(OBJEXT) TestFloat32.$(OBJEXT) \
+	TestCommon.$(OBJEXT) TestTypeFactory.$(OBJEXT)
+am__objects_2 =
+am_libtest_types_a_OBJECTS = $(am__objects_1) $(am__objects_2)
+libtest_types_a_OBJECTS = $(am_libtest_types_a_OBJECTS)
+am_das_test_OBJECTS = das-test.$(OBJEXT)
+das_test_OBJECTS = $(am_das_test_OBJECTS)
+das_test_DEPENDENCIES = libtest-types.a ../libdapserver.la \
+	../libdap.la
+am_dds_test_OBJECTS = dds-test.$(OBJEXT)
+dds_test_OBJECTS = $(am_dds_test_OBJECTS)
+dds_test_DEPENDENCIES = libtest-types.a ../libdapserver.la \
+	../libdap.la
+am_expr_test_OBJECTS = expr-test.$(OBJEXT)
+expr_test_OBJECTS = $(am_expr_test_OBJECTS)
+expr_test_DEPENDENCIES = libtest-types.a ../libdapserver.la \
+	../libdapclient.la ../libdap.la
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/conf/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(libtest_types_a_SOURCES) $(das_test_SOURCES) \
+	$(dds_test_SOURCES) $(expr_test_SOURCES)
+DIST_SOURCES = $(libtest_types_a_SOURCES) $(das_test_SOURCES) \
+	$(dds_test_SOURCES) $(expr_test_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLIENTLIB_AGE = @CLIENTLIB_AGE@
+CLIENTLIB_CURRENT = @CLIENTLIB_CURRENT@
+CLIENTLIB_REVISION = @CLIENTLIB_REVISION@
+CLIENTLIB_VERSION = @CLIENTLIB_VERSION@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
+CPPUNIT_CONFIG = @CPPUNIT_CONFIG@
+CPPUNIT_LIBS = @CPPUNIT_LIBS@
+CURL_CFLAGS = @CURL_CFLAGS@
+CURL_LIBS = @CURL_LIBS@
+CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DAPLIB_AGE = @DAPLIB_AGE@
+DAPLIB_CURRENT = @DAPLIB_CURRENT@
+DAPLIB_REVISION = @DAPLIB_REVISION@
+DAP_PROTOCOL_VERSION = @DAP_PROTOCOL_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVR = @DVR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EVAL = @EVAL@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIBC21 = @GLIBC21@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDAP_VERSION = @LIBDAP_VERSION@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_MAJOR_VERSION = @PACKAGE_MAJOR_VERSION@
+PACKAGE_MINOR_VERSION = @PACKAGE_MINOR_VERSION@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_SUBMINOR_VERSION = @PACKAGE_SUBMINOR_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVERLIB_AGE = @SERVERLIB_AGE@
+SERVERLIB_CURRENT = @SERVERLIB_CURRENT@
+SERVERLIB_REVISION = @SERVERLIB_REVISION@
+SERVERLIB_VERSION = @SERVERLIB_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+XML2_STATIC_LIBS = @XML2_STATIC_LIBS@
+YACC = @YACC@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+curlprivatelibs = @curlprivatelibs@
+curlprivatereq = @curlprivatereq@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xmlprivatelibs = @xmlprivatelibs@
+xmlprivatereq = @xmlprivatereq@
+AUTOMAKE_OPTIONS = foreign
+
+# Arrange to build with the backward compatibility mode enabled.
+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/GNU
+AM_CXXFLAGS = 
+
+# These are not used by automake but are often useful for certain types of
+# debugging. 
+CXXFLAGS_DEBUG = -g3 -O0 -fno-defer-pop -Wall -W -Wcast-align -Werror
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+# noinst_PROGRAMS = io_test
+TESTS = DASTest DDSTest EXPRTest
+# EXPRTest
+dist_check_SCRIPTS = DASTest DDSTest EXPRTest atconfig atlocal
+
+# Build the test drivers. The drivers all use the
+# subclassed types in Test*.cc and the TestTypesFactory.
+noinst_LIBRARIES = libtest-types.a
+libtest_types_a_SOURCES = $(TESTSRCS) $(TEST_HDR)
+
+# io_test_SOURCES = io_test.cc
+# io_test_LDADD = ../libdap.la
+das_test_SOURCES = das-test.cc
+das_test_LDADD = libtest-types.a ../libdapserver.la ../libdap.la 
+dds_test_SOURCES = dds-test.cc
+dds_test_LDADD = libtest-types.a ../libdapserver.la ../libdap.la 
+expr_test_SOURCES = expr-test.cc
+expr_test_LDADD = libtest-types.a ../libdapserver.la ../libdapclient.la ../libdap.la
+TESTSRCS = TestByte.cc TestInt32.cc TestFloat64.cc TestStr.cc TestUrl.cc \
+	   TestArray.cc TestStructure.cc TestSequence.cc		 \
+	   TestGrid.cc TestUInt32.cc TestInt16.cc TestUInt16.cc		 \
+	   TestFloat32.cc TestCommon.cc TestTypeFactory.cc
+
+TEST_HDR = TestArray.h TestByte.h TestCommon.h TestFloat32.h TestFloat64.h    \
+	TestGrid.h TestInt16.h TestInt32.h TestSequence.h TestStr.h	      \
+	TestStructure.h TestTypeFactory.h TestUInt16.h TestUInt32.h TestUrl.h
+
+DIRS_EXTRA = das-testsuite dds-testsuite expr-testsuite 
+
+# grid-func-testsuite cache-testsuite ais_testsuite rcreader-testsuite 
+# server-testsuite cgi-util-tests
+# ddx-testsuite	  
+EXTRA_DIST = DASTest.at  $(DASTESTSUITE) DDSTest.at  $(DDSTESTSUITE) \
+	EXPRTest.at $(EXPRTESTSUITE) atlocal.in $(srcdir)/package.m4 \
+	$(DIRS_EXTRA)
+
+DISTCLEANFILES = *.log DASTest.dir/* DDSTest.dir/* EXPRTest.dir/*
+
+############## Autotest follows #####################
+AUTOM4TE = autom4te
+DASTESTSUITE = $(srcdir)/DASTest 
+DASTESTSUITEFLAGS = 
+DDSTESTSUITE = $(srcdir)/DDSTest 
+DDSTESTSUITEFLAGS = 
+EXPRTESTSUITE = $(srcdir)/EXPRTest 
+EXPRTESTSUITEFLAGS = 
+AUTOTEST = $(AUTOM4TE) --language=autotest
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+atlocal: $(top_builddir)/config.status $(srcdir)/atlocal.in
+	cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
+
+clean-noinstLIBRARIES:
+	-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
+libtest-types.a: $(libtest_types_a_OBJECTS) $(libtest_types_a_DEPENDENCIES) 
+	-rm -f libtest-types.a
+	$(libtest_types_a_AR) libtest-types.a $(libtest_types_a_OBJECTS) $(libtest_types_a_LIBADD)
+	$(RANLIB) libtest-types.a
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+das-test$(EXEEXT): $(das_test_OBJECTS) $(das_test_DEPENDENCIES) 
+	@rm -f das-test$(EXEEXT)
+	$(CXXLINK) $(das_test_OBJECTS) $(das_test_LDADD) $(LIBS)
+dds-test$(EXEEXT): $(dds_test_OBJECTS) $(dds_test_DEPENDENCIES) 
+	@rm -f dds-test$(EXEEXT)
+	$(CXXLINK) $(dds_test_OBJECTS) $(dds_test_LDADD) $(LIBS)
+expr-test$(EXEEXT): $(expr_test_OBJECTS) $(expr_test_DEPENDENCIES) 
+	@rm -f expr-test$(EXEEXT)
+	$(CXXLINK) $(expr_test_OBJECTS) $(expr_test_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestArray.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestByte.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestCommon.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestFloat32.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestFloat64.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestGrid.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestInt16.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestInt32.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestSequence.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestStr.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestStructure.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestTypeFactory.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestUInt16.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestUInt32.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/TestUrl.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/das-test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dds-test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/expr-test.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS:  $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    echo "$$grn$$dashes"; \
+	  else \
+	    echo "$$red$$dashes"; \
+	  fi; \
+	  echo "$$banner"; \
+	  test -z "$$skipped" || echo "$$skipped"; \
+	  test -z "$$report" || echo "$$report"; \
+	  echo "$$dashes$$std"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) \
+	  $(dist_check_SCRIPTS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LIBRARIES)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool clean-local \
+	clean-noinstLIBRARIES mostlyclean-am
+
+distclean: distclean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-local distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+	clean-checkPROGRAMS clean-generic clean-libtool clean-local \
+	clean-noinstLIBRARIES ctags distclean distclean-compile \
+	distclean-generic distclean-libtool distclean-local \
+	distclean-tags distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+	pdf pdf-am ps ps-am tags uninstall uninstall-am
+
+
+#check-local: check-das check-dds
+
+#check-das: atconfig atlocal $(DASTESTSUITE)
+#	$(SHELL) $(DASTESTSUITE) $(DASTESTSUITEFLAGS)
+
+#check-dds: atconfig atlocal $(DDSTESTSUITE)
+#	$(SHELL) $(DDSTESTSUITE) $(DDSTESTSUITEFLAGS)
+
+clean-local:
+	test ! -f '$(DASTESTSUITE)' || $(SHELL) $(DASTESTSUITE) --clean
+	test ! -f '$(DDSTESTSUITE)' || $(SHELL) $(DDSTESTSUITE) --clean
+
+distclean-local:
+	-rm atconfig
+$(DASTESTSUITE): $(srcdir)/DASTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+$(DDSTESTSUITE): $(srcdir)/DDSTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+$(EXPRTESTSUITE): $(srcdir)/EXPRTest.at $(srcdir)/package.m4
+	$(AUTOTEST) -I '$(srcdir)' -o $@.tmp $@.at
+	mv $@.tmp $@
+
+# The `:;' works around a Bash 3.2 bug when the output is not writable.
+$(srcdir)/package.m4: $(top_srcdir)/configure.ac
+	:;{ \
+	echo '# Signature of the current package.' && \
+	echo 'm4_define([AT_PACKAGE_NAME],      [@PACKAGE_NAME@])' && \
+	echo 'm4_define([AT_PACKAGE_TARNAME],   [@PACKAGE_TARNAME@])' && \
+	echo 'm4_define([AT_PACKAGE_VERSION],   [@PACKAGE_VERSION@])' && \
+	echo 'm4_define([AT_PACKAGE_STRING],    [@PACKAGE_STRING@])' && \
+	echo 'm4_define([AT_PACKAGE_BUGREPORT], [@PACKAGE_BUGREPORT@])'; \
+	} >'$(srcdir)/package.m4'
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..2baeb1a
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,19 @@
+
+On some systems 'make check' will report that the script config.guess' could
+not be found. If that happens, create a symbolic link from ../conf/config.guess
+to either this directory or the libdap-* directory (one level up). The check 
+target should now work.
+
+Tests that are known/expected to fail
+
+There are four tests that are know to fail: expr-test.0/test.1.exp,
+test.6.exp and the expr-test.1 versions. These tests check to see if a CE
+with a selection works when applied to a non-relational data type. It does
+not work and that behavior was never defined by DAP 2.0.
+
+Tests expr-test.1/test.xc.exp and test.yc.exp also fail because of the
+situation described in ticket #995 - a nested sequence is not correctly
+processed by the intern_data() methods. This problem will show up in the JGOFS
+handler when ASCII responses are requested, but will not affect other
+Sequence data sets such as the file servers' data.
+
diff --git a/tests/TestArray.cc b/tests/TestArray.cc
new file mode 100644
index 0000000..5b4c18c
--- /dev/null
+++ b/tests/TestArray.cc
@@ -0,0 +1,426 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestArray. See TestByte.cc
+//
+// jhrg 1/12/95
+
+#include "config.h"
+
+#include <cstring>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef WIN32
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+//#define DODS_DEBUG
+
+#include "ce_functions.h"
+#include "debug.h"
+
+#include "TestArray.h"
+#include "TestCommon.h"
+
+
+using std::cerr;
+using std::endl;
+
+extern int test_variable_sleep_interval;
+
+void
+TestArray::_duplicate(const TestArray &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+BaseType *
+TestArray::ptr_duplicate()
+{
+    return new TestArray(*this);
+}
+
+TestArray::TestArray(const string &n, BaseType *v) : Array(n, v),
+        d_series_values(false)
+{
+}
+
+TestArray::TestArray(const string &n, const string &d, BaseType *v)
+    : Array(n, d, v),
+        d_series_values(false)
+{
+}
+
+TestArray::TestArray(const TestArray &rhs) : Array(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestArray::~TestArray()
+{
+}
+
+TestArray &
+TestArray::operator=(const TestArray &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Array &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+/** Special names are ones that start with 'lat' or 'lon'. These indicate
+    that the vector (this is only for vectors) is a vector of latitude or
+    longitude values. */
+bool
+TestArray::name_is_special()
+{
+    return ( name().find("lat") != string::npos
+             || name().find("lon") != string::npos );
+}
+
+void
+TestArray::build_special_values()
+{
+    if (name().find("lat_reversed") != string::npos) {
+        int array_len = length();
+        double *lat_data = new double[array_len];
+        for (int i = 0; i < array_len; ++i) {
+            lat_data[i] = -89 + (180/array_len) * (i+1);
+        }
+        libdap::set_array_using_double(this, lat_data, array_len);
+    } else if (name().find("lat") != string::npos) {
+        int array_len = length();
+        double *lat_data = new double[array_len];
+        for (int i = 0; i < array_len; ++i) {
+            lat_data[i] = 90 - (180/array_len) * (i+1);
+        }
+        libdap::set_array_using_double(this, lat_data, array_len);
+    }
+    else if (name().find("lon") != string::npos) {
+        int array_len = length();
+        double *lon_data = new double[array_len];
+        for (int i = 0; i < array_len; ++i) {
+            lon_data[i] = (360/array_len) * (i+1);
+        }
+        libdap::set_array_using_double(this, lon_data, array_len);
+    }
+    else {
+        throw InternalErr(__FILE__, __LINE__, "Unrecognized name");
+    }
+}
+
+int TestArray::m_offset(int y, Dim_iter X, int x)
+{
+    return y * dimension_size(X, false) + x;
+}
+
+/** Only call this method for a two dimensional array */
+void
+TestArray::constrained_matrix(char *constrained_array)
+{
+    int unconstrained_size = 1;
+    Dim_iter d = dim_begin();
+    while (d != dim_end())
+        unconstrained_size *= dimension_size(d++, false);
+    char *whole_array = new char[unconstrained_size * width()];
+    DBG(cerr << "unconstrained size: " << unconstrained_size << endl);
+
+    int elem_width = var()->width();      // size of an element
+    char *elem_val = new char[elem_width];
+
+    for (int i = 0; i < unconstrained_size; ++i) {
+        var()->read();
+        var()->buf2val((void **) &elem_val);
+
+        memcpy(whole_array + i * elem_width, elem_val, elem_width);
+        var()->set_read_p(false);       // pick up the next value
+    }
+
+    DBG(cerr << "whole_array: ";
+	for (int i = 0; i < unconstrained_size; ++i) {
+	cerr << (int)*(dods_byte*)(whole_array + (i * elem_width)) << ", ";
+    }
+    cerr << endl);
+
+    Dim_iter Y = dim_begin();
+    Dim_iter X = Y+1;
+    char *dest = constrained_array;
+
+    DBG(cerr << "dimension_start(Y): " << dimension_start(Y) << endl);
+    DBG(cerr << "dimension_stop(Y): " << dimension_stop(Y) << endl);
+    DBG(cerr << "dimension_start(X): " << dimension_start(X) << endl);
+    DBG(cerr << "dimension_stop(X): " << dimension_stop(X) << endl);
+
+    int constrained_size = 0;
+    int y = dimension_start(Y);
+    while (y < dimension_stop(Y)+1) {
+
+    	int x = dimension_start(X);
+    	while (x < dimension_stop(X)+1) {
+
+                DBG2(cerr << "whole[" << y << "][" << x << "]: ("
+    		<< m_offset(y, Y, x) << ") "
+    		<< *(dods_byte*)(whole_array + m_offset(y, X, x)*elem_width)
+    		<< endl);
+
+    	    memcpy(dest,
+    		   whole_array + m_offset(y, X, x)*elem_width,
+    		   elem_width);
+
+    	    dest += elem_width;
+    	    x += dimension_stride(X);
+    	    constrained_size++;
+    	}
+
+    	y += dimension_stride(Y);
+    }
+
+    DBG(cerr << "constrained size: " << constrained_size << endl);
+    DBG(cerr << "constrained_array: ";
+        for (int i = 0; i < constrained_size; ++i) {
+    	    cerr << (int)*(dods_byte*)(constrained_array + (i * elem_width)) << ", ";
+        }
+        cerr << endl);
+
+    delete[] whole_array;
+    delete[] elem_val;
+}
+
+// This code calls 'output_values()' because print_val() does not test
+// the value of send_p(). We need to wrap a method around the calls to
+//print_val() to ensure that only values for variables with send_p() set
+// are called. In the serialize/deserialize case, the 'client' DDS only
+// has variables sent by the 'server' but int he intern_data() case, the
+// whole DDS is still present but only variables selected in the CE have
+// values.
+
+unsigned int
+TestArray::print_array(ostream &out, unsigned int index, unsigned int dims,
+                       unsigned int shape[])
+{
+    if (dims == 1) {
+	out << "{" ;
+        for (unsigned i = 0; i < shape[0] - 1; ++i) {
+            dynamic_cast<TestCommon&>(*var(index++)).output_values(out);
+	    out << ", " ;
+        }
+        dynamic_cast<TestCommon&>(*var(index++)).output_values(out);
+	out << "}" ;
+
+        return index;
+    }
+    else {
+	out << "{" ;
+        // Fixed an off-by-one error in the following loop. Since the array
+        // length is shape[dims-1]-1 *and* since we want one less dimension
+        // than that, the correct limit on this loop is shape[dims-2]-1. From
+        // Todd Karakasian.
+        // The saga continues; the loop test should be `i < shape[0]-1'. jhrg
+        // 9/12/96.
+        for (unsigned i = 0; i < shape[0] - 1; ++i) {
+            index = print_array(out, index, dims - 1, shape + 1);
+	    out << "," ;
+        }
+        index = print_array(out, index, dims - 1, shape + 1);
+	out << "}" ;
+
+        return index;
+    }
+}
+
+void
+TestArray::output_values(std::ostream &out)
+{
+    unsigned int *shape = new unsigned int[dimensions(true)];
+    unsigned int index = 0;
+    for (Dim_iter i = dim_begin(); i != dim_end() && index < dimensions(true); ++i)
+        shape[index++] = dimension_size(i, true);
+
+    print_array(out, 0, dimensions(true), shape);
+
+    delete [] shape; shape = 0;
+}
+
+bool
+TestArray::read()
+{
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    unsigned int array_len = length(); // elements in the array
+
+    switch (var()->type()) {
+      case dods_byte_c:
+      case dods_int16_c:
+      case dods_uint16_c:
+      case dods_int32_c:
+      case dods_uint32_c:
+      case dods_float32_c:
+      case dods_float64_c: {
+
+        //char *tmp = new char[width()];
+	vector<char> tmp(width());
+
+        unsigned int elem_wid = var()->width(); // size of an element
+        char *elem_val = 0;       // Null forces buf2val to allocate memory
+
+        if (get_series_values()) {
+            // Special case code for vectors that have specific names.
+            // This is used to test code that works with lat/lon data.
+            if (dimensions() == 1 && name_is_special()) {
+                build_special_values();
+            }
+            else if (dimensions() == 2) {
+                constrained_matrix(&tmp[0]);
+                val2buf(&tmp[0]);
+            }
+            else {
+                for (unsigned i = 0; i < array_len; ++i) {
+                    var()->read();
+                    var()->buf2val((void **)&elem_val); // internal buffer to ELEM_VAL
+                    memcpy(&tmp[0] + i * elem_wid, elem_val, elem_wid);
+                    var()->set_read_p(false); // pick up the next value
+                 }
+                 val2buf(&tmp[0]);
+            }
+        }
+        else {
+            var()->read();
+	    var()->buf2val((void **)&elem_val);
+
+	    for (unsigned i = 0; i < array_len; ++i) {
+	        memcpy(&tmp[0] + i * elem_wid, elem_val, elem_wid);
+            }
+
+            val2buf(&tmp[0]);
+        }
+
+	delete elem_val; elem_val = 0; // alloced in buf2val()
+	// delete[] tmp; tmp = 0;	// alloced above
+
+	break;
+      }
+
+      case dods_str_c:
+      case dods_url_c: {
+        // char *tmp = new char[width()];
+        vector<char> tmp(width());
+        unsigned int elem_wid = var()->width(); // size of an element
+        char *elem_val = 0;       // Null forces buf2val to allocate memory
+
+        if (get_series_values()) {
+                for (unsigned i = 0; i < array_len; ++i) {
+                    var()->read();
+                    var()->buf2val((void **)&elem_val); // internal buffer to ELEM_VAL
+                    memcpy(&tmp[0] + i * elem_wid, elem_val, elem_wid);
+                    var()->set_read_p(false); // pick up the next value
+                 }
+        }
+        else {
+            var()->read();
+            var()->buf2val((void **)&elem_val);
+
+            for (unsigned i = 0; i < array_len; ++i) {
+                memcpy(&tmp[0] + i * elem_wid, elem_val, elem_wid);
+            }
+        }
+
+        val2buf(&tmp[0]);
+
+        delete elem_val; elem_val = 0; // alloced in buf2val()
+        // delete[] tmp; tmp = 0;  // alloced above
+
+        break;
+      }
+
+      case dods_structure_c:
+
+	// Arrays of Structure, ... must load each element into the array
+	// manually. Because these are stored as C++/DODS objects, there is
+	// no need to manipulate blocks of memory by hand as in the above
+	// case.
+        // NB: Strings are handled like Byte, etc. because, even though they
+	// are represented using C++ objects they are *not* represented using
+	// objects defined by DODS, while Structure, etc. are.
+
+	for (unsigned i = 0; i < array_len; ++i) {
+
+	    // Create a new object that is a copy of `var()' (whatever that
+	    // is). The copy will have the value read in by the read() mfunc
+	    // executed before this switch stmt.
+
+	    BaseType *elem = var()->ptr_duplicate();
+
+	    // read values into the new instance.
+
+	    elem->read();
+
+	    // now load the new instance in the array.
+
+	    set_vec(i, elem);
+	}
+
+	break;
+
+      case dods_sequence_c:
+      case dods_grid_c:
+      case dods_array_c:
+      case dods_null_c:
+      default:
+	throw InternalErr(__FILE__, __LINE__, "Bad data type");
+	break;
+    }
+
+    set_read_p(true);
+
+    return true;
+}
+
+void
+TestArray::set_series_values(bool sv)
+{
+    dynamic_cast<TestCommon&>(*var()).set_series_values(sv);
+    d_series_values = sv;
+}
diff --git a/tests/TestArray.h b/tests/TestArray.h
new file mode 100644
index 0000000..55944c2
--- /dev/null
+++ b/tests/TestArray.h
@@ -0,0 +1,74 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface definition for TestArray. See TestByte.h for more information
+//
+// jhrg 1/12/95
+
+#ifndef _testarray_h
+#define _testarray_h 1
+
+#include "Array.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestArray: public Array, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestArray &ts);
+    int m_offset(int y, Dim_iter Y, int x);
+    unsigned int print_array(ostream &out, unsigned int index,
+			     unsigned int dims, unsigned int shape[]);
+
+public:
+    TestArray(const string &n, BaseType *v);
+    TestArray(const string &n, const string &d, BaseType *v);
+    TestArray(const TestArray &rhs);
+
+    virtual ~TestArray();
+
+    TestArray &operator=(const TestArray &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual bool read();
+    virtual bool name_is_special();
+    virtual void build_special_values();
+    virtual void constrained_matrix(char *constrained_array);
+
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool);
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testarray_h
+
diff --git a/tests/TestByte.cc b/tests/TestByte.cc
new file mode 100644
index 0000000..ec6aa8b
--- /dev/null
+++ b/tests/TestByte.cc
@@ -0,0 +1,150 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestByte. See the comments in TestByte.h
+// For each of the `variable classes' (e.g., Byte, ... Array, ... Grid) you
+// *must* define a ctor, dtor, ptr_duplicate and read mfunc. In addition, you
+// must edit the definition of New<class name> so that it creates the correct
+// type of object. for example, edit NewByte() so that it creates and returns
+// a TestByte pointer (see util.cc).
+//
+// jhrg 1/12/95
+//
+// NB: It is no longer true that you must subclass the Byte, ..., Grid
+// classes in order to use the DAP. Those classes are no longer abstract. For
+// many client-side uses, the classes will work just fine as they are. To
+// build a server, it is still necessary to subclass and define a read()
+// method for each of the data type classes. 01/22/03 jhrg
+
+#include "config.h"
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestByte.h"
+#include "debug.h"
+
+// The NewByte `helper function' creates a pointer to the a TestByte and
+// returns that pointer. It takes the same arguments as the class's ctor. If
+// any of the variable classes are subclassed (e.g., to make a new Byte like
+// HDFByte) then the corresponding function here, and in the other class
+// definition files, needs to be changed so that it creates an instance of
+// the new (sub)class. Continuing the earlier example, that would mean that
+// NewByte() would return a HDFByte, not a Byte.
+//
+// It is important that these function's names and return types do not change
+// - they are called by the parser code (for the dds, at least) so if their
+// names changes, that will break.
+//
+// The declarations for these functions (in util.h) should *not* need
+// changing.
+
+extern int test_variable_sleep_interval;
+
+void
+TestByte::_duplicate(const TestByte &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+TestByte::TestByte(const string &n) : Byte(n), d_series_values(false)
+{
+    _buf = 255;
+}
+
+TestByte::TestByte(const string &n, const string &d)
+    : Byte(n, d), d_series_values(false)
+{
+    _buf = 255;
+}
+
+BaseType *
+TestByte::ptr_duplicate()
+{
+    return new TestByte(*this);
+}
+
+TestByte::TestByte(const TestByte &rhs) : Byte(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestByte &
+TestByte::operator=(const TestByte &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Byte &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+#if 1
+void
+TestByte::output_values(std::ostream &out)
+{
+    // value is a method where each return value is a different type so we have
+    // to make calls to it from objects/methods where the type is statically
+    // known.
+    print_val(out, "", false);
+}
+#endif
+
+bool
+TestByte::read()
+{
+    DBG(cerr << "Entering TestByte::read for " << name() << endl);
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+         _buf++;
+    }
+    else {
+        _buf = 255;
+    }
+
+    set_read_p(true);
+
+    DBG(cerr << "In TestByte::read, _buf = " << (int)_buf << endl);
+
+    return true;
+}
diff --git a/tests/TestByte.h b/tests/TestByte.h
new file mode 100644
index 0000000..af6dab3
--- /dev/null
+++ b/tests/TestByte.h
@@ -0,0 +1,79 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// TestByte is a demonstration of subclassing a class in the hierarchy of
+// DODS data types. It does not do much of anything - a real subclass would
+// add specifics for an API or format (e.g., a read mfunc for netcdf, HDF,
+// ...).  The class is used by some of the test code (hence the name) as well
+// as serving as a template for others who need to subclass the hierarchy. 
+//
+// Since the class Byte is an abstract class (as are all the other
+// `variable type' classes), the hierarchy *must* be subclassed in order to
+// be used.
+//
+// jhrg 1/12/95
+//
+// NB: It is no longer true that Byte, ..., Grid are abstract classes. They
+// are now concrete ad do not necessarily need to be subclassed. 01/22/03 jhrg
+
+#ifndef _testbyte_h
+#define _testbyte_h 1
+
+#include "Byte.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestByte: public Byte, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestByte &ts);
+
+public:
+    TestByte(const string &n);
+    TestByte(const string &n, const string &d);
+    TestByte(const TestByte &rhs);
+
+    virtual ~TestByte() {}
+
+    TestByte &operator=(const TestByte &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual bool read();
+#if 1
+    virtual void output_values(std::ostream &out);
+#endif
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testbyte_h
+
diff --git a/tests/TestCommon.cc b/tests/TestCommon.cc
new file mode 100644
index 0000000..4f683b1
--- /dev/null
+++ b/tests/TestCommon.cc
@@ -0,0 +1,24 @@
+#include "TestCommon.h"
+#include "InternalErr.h"
+
+using namespace libdap ;
+
+TestCommon::TestCommon()
+{
+}
+
+TestCommon::~TestCommon()
+{
+}
+
+void
+TestCommon::set_series_values(bool)
+{
+    throw InternalErr(__FILE__, __LINE__, "Unimplemented");
+}
+
+bool
+TestCommon::get_series_values()
+{
+    throw InternalErr(__FILE__, __LINE__, "Unimplemented");
+}
diff --git a/tests/TestCommon.h b/tests/TestCommon.h
new file mode 100644
index 0000000..a798909
--- /dev/null
+++ b/tests/TestCommon.h
@@ -0,0 +1,68 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// An interface to new common methods for the Test*.cc/h classes.
+
+#ifndef _test_common_h
+#define _test_common_h 1
+
+#include <stdio.h>
+#include <iostream>
+
+/** Get the value of the series_value property. If true, the TestByte, ...,
+    classes should produce values that vary in a fashion similar to the DTS.
+    If false, they should exhibit the old behavior where the values are static.
+    For arrays, grids and structures the 'series_value' doesn't mean much, but
+    for sequences it's a big deal since those are constrained by value in
+    addition to by position. */
+class TestCommon {
+public:
+    TestCommon();
+    virtual ~TestCommon();
+
+    /** Write out values first testing send_p() to ensure the variable has
+        data. This method is to be used when the intern_data() method is used
+        to read data into variables after the CE is evaluated. In most cases
+        variables will be used on either the server- or client-side but not
+        both. However, in some cases the same variables are used on both
+        sides. The intern_data() method is then used to read data into the
+        variables (usually serialize() is used to read the data int a
+        variable and send it to a client, then deserialize() is used to read
+        those values from a network. The intern_data() method combines those
+        operations.
+
+        @note This method is used to test the result of calling
+        intern_data(). The print_val() method does not know to check the
+        send_p() flag and thus is not useful for testing intern_data()
+
+        @param out Where to write the values */
+    virtual void output_values(std::ostream &out) = 0;
+
+    virtual void set_series_values(bool);
+    virtual bool get_series_values();
+};
+
+#endif // _test_common_h
+
diff --git a/tests/TestFloat32.cc b/tests/TestFloat32.cc
new file mode 100644
index 0000000..f472de6
--- /dev/null
+++ b/tests/TestFloat32.cc
@@ -0,0 +1,134 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestFloat32. See TestByte.cc
+//
+// 3/22/99 jhrg
+
+
+#include "config.h"
+
+#include <math.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestFloat32.h"
+#include "debug.h"
+
+extern int test_variable_sleep_interval;
+
+#if ( defined(__sun__) && ( HOST_SOLARIS < 10 ))
+double trunc(double x)
+{
+       return x < 0 ? -floor(-x) : floor(x);
+}
+#endif
+
+void
+TestFloat32::_duplicate(const TestFloat32 &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+TestFloat32::TestFloat32(const string &n) : Float32(n), d_series_values(false)
+{
+    _buf = 0.0;
+}
+
+TestFloat32::TestFloat32(const string &n, const string &d)
+    : Float32(n, d), d_series_values(false)
+{
+    _buf = 0.0;
+}
+
+TestFloat32::TestFloat32(const TestFloat32 &rhs) : Float32(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestFloat32 &
+TestFloat32::operator=(const TestFloat32 &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Float32 &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+BaseType *
+TestFloat32::ptr_duplicate()
+{
+    return new TestFloat32(*this); // Copy ctor calls duplicate to do the work
+}
+ 
+void 
+TestFloat32::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestFloat32::read()
+{
+    DBG(cerr << "Entering TestFloat32::read for " << name() << endl);
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+        _buf += 10.0;
+        _buf = (float)(trunc(10000 * sin(trunc(_buf))) / 100);
+	/*
+	_buf -= 0.11 ;
+	*/
+    }
+    else {
+        _buf = (float)99.999;
+    }
+    
+    set_read_p(true);
+
+    DBG(cerr << "In TestFloat32::read, _buf = " << _buf << endl);
+    
+    return true;
+}
diff --git a/tests/TestFloat32.h b/tests/TestFloat32.h
new file mode 100644
index 0000000..ce97e40
--- /dev/null
+++ b/tests/TestFloat32.h
@@ -0,0 +1,70 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for TestFloat32 type. See TestByte.h
+//
+// 3/22/99 jhrg
+
+#ifndef _testfloat32_h
+#define _testfloat32_h 1
+
+
+#include "Float32.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestFloat32: public Float32, public TestCommon {
+    bool d_series_values;
+    
+    void _duplicate(const TestFloat32 &ts);
+
+public:
+    TestFloat32(const string &n);
+    TestFloat32(const string &n, const string &d);
+    TestFloat32(const TestFloat32 &rhs);
+
+    virtual ~TestFloat32() {}
+
+    TestFloat32 &operator=(const TestFloat32 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif //_testfloat32_h
+
diff --git a/tests/TestFloat64.cc b/tests/TestFloat64.cc
new file mode 100644
index 0000000..b252704
--- /dev/null
+++ b/tests/TestFloat64.cc
@@ -0,0 +1,128 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestFloat64. See TestByte.cc
+//
+// jhrg 1/12/95
+
+
+#include "config.h"
+
+#include <math.h>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestFloat64.h"
+
+extern int test_variable_sleep_interval;
+
+#if ( defined(__sun__) && ( HOST_SOLARIS < 10 ))
+double trunc(double x)
+{
+       return x < 0 ? -floor(-x) : floor(x);
+}
+#endif
+
+void
+TestFloat64::_duplicate(const TestFloat64 &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+TestFloat64::TestFloat64(const string &n) : Float64(n), d_series_values(false)
+{
+    _buf = 0.0;
+}
+
+TestFloat64::TestFloat64(const string &n, const string &d)
+    : Float64(n, d), d_series_values(false)
+{
+    _buf = 0.0;
+}
+
+TestFloat64::TestFloat64(const TestFloat64 &rhs) : Float64(rhs) , TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestFloat64 &
+TestFloat64::operator=(const TestFloat64 &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Float64 &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+BaseType *
+TestFloat64::ptr_duplicate()
+{
+    return new TestFloat64(*this); // Copy ctor calls duplicate to do the work
+}
+
+void 
+TestFloat64::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestFloat64::read()
+{
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+        _buf += 10.0;
+        _buf = (float)(trunc(10000 * cos(trunc(_buf))) / 100);
+    }
+    else {
+        _buf = 99.999;
+    }
+    
+    set_read_p(true);
+
+    return true;
+}
+
diff --git a/tests/TestFloat64.h b/tests/TestFloat64.h
new file mode 100644
index 0000000..115e634
--- /dev/null
+++ b/tests/TestFloat64.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for TestFloat64 type. See TestByte.h
+//
+// jhrg 1/12/95
+
+#ifndef _testfloat64_h
+#define _testfloat64_h 1
+
+
+#include "Float64.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestFloat64: public Float64, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestFloat64 &ts);
+
+public:
+    TestFloat64(const string &n);
+    TestFloat64(const string &n, const string &d);
+    TestFloat64(const TestFloat64 &rhs);
+
+    virtual ~TestFloat64() {}
+
+    TestFloat64 &operator=(const TestFloat64 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testfloat64_h
+
diff --git a/tests/TestGrid.cc b/tests/TestGrid.cc
new file mode 100644
index 0000000..c3737df
--- /dev/null
+++ b/tests/TestGrid.cc
@@ -0,0 +1,166 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// implementation for TestGrid. See TestByte.
+//
+// jhrg 1/13/95
+
+#include "TestGrid.h"
+#include "TestCommon.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestGrid::_duplicate(const TestGrid &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+BaseType *
+TestGrid::ptr_duplicate()
+{
+    return new TestGrid(*this);
+}
+
+TestGrid::TestGrid(const TestGrid &rhs) : Grid(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+void 
+TestGrid::output_values(std::ostream &out)
+{
+    // value_written controls comma printing
+    bool value_written = false;
+    bool pyg = projection_yields_grid();
+    if (pyg)
+        out << "{  Array: " ;
+    else //if (components(true) > 1)
+        out << "{ " ;
+
+    if (array_var()->send_p()) {
+        array_var()->print_val(out, "", false);
+        value_written = true;
+    }
+        
+    if (pyg) {
+        out << "  Maps: " ;
+        // No comma needed if the 'Maps:' separator is written out
+        value_written = false;
+    }
+
+    Map_citer i = map_begin();
+    // Write the first (and maybe only) value.
+    while(i != map_end() && !value_written) {
+        if ((*i)->send_p()) {
+            (*i++)->print_val(out, "", false);
+            value_written = true;
+        }
+        else {
+            ++i;
+        }
+    }
+    // Each subsequent value will be preceded by a comma
+    while(i != map_end()) {
+        if ((*i)->send_p()) {
+            out << ", ";
+            (*i++)->print_val(out, "", false);
+        }
+        else {
+            ++i;
+        }
+    }
+
+    //if (pyg || components(true) > 1)
+        out << " }" ;
+}
+
+TestGrid &
+TestGrid::operator=(const TestGrid &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Grid &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+
+TestGrid::TestGrid(const string &n) : Grid(n), d_series_values(false)
+{
+}
+
+TestGrid::TestGrid(const string &n, const string &d)
+    : Grid(n, d), d_series_values(false)
+{
+}
+
+TestGrid::~TestGrid()
+{
+}
+
+bool
+TestGrid::read()
+{
+    if (read_p())
+	return true;
+
+    get_array()->read();
+
+    for (Map_iter i = map_begin(); i != map_end(); i++)
+    {
+	if (!(*i)->read())
+	{
+	    return false;
+	}
+    }
+
+    set_read_p(true);
+
+    return true;
+}
+
+void
+TestGrid::set_series_values(bool sv)
+{
+    Map_iter i = map_begin();
+    while (i != map_end()) {
+        dynamic_cast<TestCommon&>(*(*i)).set_series_values(sv);
+        ++i;
+    }
+    
+    dynamic_cast<TestCommon&>(*array_var()).set_series_values(sv);
+    
+    d_series_values = sv;
+}
diff --git a/tests/TestGrid.h b/tests/TestGrid.h
new file mode 100644
index 0000000..19d1a68
--- /dev/null
+++ b/tests/TestGrid.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface to the TestGrid ctor class. See TestByte.h
+//
+// jhrg 1/13/95
+
+#ifndef _testgrid_h
+#define _testgrid_h 1
+
+
+#include "Grid.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestGrid: public Grid, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestGrid &ts);
+
+public:
+    TestGrid(const string &n);
+    TestGrid(const string &n, const string &d);
+    TestGrid(const TestGrid &rhs);
+
+    virtual ~TestGrid();
+    
+    TestGrid &operator=(const TestGrid &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool);
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testgrid_h
+
diff --git a/tests/TestInt16.cc b/tests/TestInt16.cc
new file mode 100644
index 0000000..f9fabe2
--- /dev/null
+++ b/tests/TestInt16.cc
@@ -0,0 +1,118 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestInt16. See TestByte.cc
+//
+// 3/22/99 jhrg
+
+
+#include "config.h"
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestInt16.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestInt16::_duplicate(const TestInt16 &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+TestInt16::TestInt16(const string &n) : Int16(n), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestInt16::TestInt16(const string &n, const string &d)
+    : Int16(n, d), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestInt16::TestInt16(const TestInt16 &rhs) : Int16(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestInt16 &
+TestInt16::operator=(const TestInt16 &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Int16 &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+
+BaseType *
+TestInt16::ptr_duplicate()
+{
+    return new TestInt16(*this);
+}
+
+void 
+TestInt16::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestInt16::read()
+{
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+       _buf = (short)(16 * _buf);
+    }
+    else {
+        _buf = 32000;
+    }
+
+    set_read_p(true);
+    
+    return true;
+}
diff --git a/tests/TestInt16.h b/tests/TestInt16.h
new file mode 100644
index 0000000..c035425
--- /dev/null
+++ b/tests/TestInt16.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// TestInt16 interface. See TestByte.h for more info.
+//
+// 3/22/99 jhrg
+
+#ifndef _testint16_h
+#define _testint16_h 1
+
+
+#include "Int16.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestInt16: public Int16, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestInt16 &ts);
+
+public:
+    TestInt16(const string &n);
+    TestInt16(const string &n, const string &d);
+    TestInt16(const TestInt16 &rhs);
+
+    virtual ~TestInt16() {}
+
+    TestInt16 &operator=(const TestInt16 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testint16_h
+
diff --git a/tests/TestInt32.cc b/tests/TestInt32.cc
new file mode 100644
index 0000000..1a3251d
--- /dev/null
+++ b/tests/TestInt32.cc
@@ -0,0 +1,125 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestInt32. See TestByte.cc
+//
+// jhrg 1/12/95
+
+
+#include "config.h"
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+//#define DODS_DEBUG 
+
+#include "TestInt32.h"
+#include "debug.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestInt32::_duplicate(const TestInt32 &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+TestInt32::TestInt32(const string &n) : Int32(n), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestInt32::TestInt32(const string &n, const string &)
+    : Int32(n), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestInt32::TestInt32(const TestInt32 &rhs) : Int32(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestInt32 &
+TestInt32::operator=(const TestInt32 &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Int32 &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+BaseType *
+TestInt32::ptr_duplicate()
+{
+    return new TestInt32(*this);
+}
+
+void 
+TestInt32::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestInt32::read()
+{
+    DBG(cerr << "Entering TestInt32::read for " << name() << endl);
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+        _buf = 32 * _buf;
+        if (!_buf)
+            _buf = 32;
+    }
+    else {
+        _buf = 123456789;
+    }
+
+    set_read_p(true);
+
+    DBG(cerr << "In TestInt32::read, _buf = " << _buf << endl);
+    
+    return true;
+}
diff --git a/tests/TestInt32.h b/tests/TestInt32.h
new file mode 100644
index 0000000..f26e334
--- /dev/null
+++ b/tests/TestInt32.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// TestInt32 interface. See TestByte.h for more info.
+//
+// jhrg 1/12/95
+
+#ifndef _testint32_h
+#define _testint32_h 1
+
+
+#include "Int32.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestInt32: public Int32, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestInt32 &ts);
+
+public:
+    TestInt32(const string &n);
+    TestInt32(const string &n, const string &d);
+    TestInt32(const TestInt32 &rhs);
+
+    virtual ~TestInt32() {}
+
+    TestInt32 &operator=(const TestInt32 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    virtual void set_series_values(bool sv) { d_series_values = sv; }
+    virtual bool get_series_values() { return d_series_values; }
+};
+
+#endif //_testint32_h
+
diff --git a/tests/TestSequence.cc b/tests/TestSequence.cc
new file mode 100644
index 0000000..aeb2324
--- /dev/null
+++ b/tests/TestSequence.cc
@@ -0,0 +1,153 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the class TestStructure. See TestByte.cc
+//
+// jhrg 1/12/95
+//
+// Note that the test code here to read values from a data file works only
+// for single level sequences - that is, it does *not* work for sequences
+// that contain other sequences. jhrg 2/2/98 
+
+#include "TestSequence.h"
+#include "TestCommon.h"
+
+#include "config.h"
+#include "debug.h"
+
+void
+TestSequence::_duplicate(const TestSequence &ts)
+{
+    d_current = ts.d_current;
+    d_len = ts.d_len;
+    d_series_values = ts.d_series_values;
+}
+
+BaseType *
+TestSequence::ptr_duplicate()
+{
+    return new TestSequence(*this);
+}
+
+TestSequence::TestSequence(const string &n) : Sequence(n), d_len(4),
+	d_current(0), d_series_values(false)
+{
+}
+
+TestSequence::TestSequence(const string &n, const string &d)
+    : Sequence(n, d), d_len(4), d_current(0), d_series_values(false)
+{
+}
+
+TestSequence::TestSequence(const TestSequence &rhs) : Sequence(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestSequence::~TestSequence()
+{
+}
+
+TestSequence &
+TestSequence::operator=(const TestSequence &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Sequence &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+void
+TestSequence::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+// Read values from text files. Sequence instances are stored on separate
+// lines. Line can be no more than 255 characters long.
+
+bool 
+TestSequence::read()
+{
+    DBG(cerr << "Entering TestSequence::read for " << name() << endl);
+    
+    if (read_p())
+        return true;
+        
+    DBG(cerr << "current: " << d_current << ", length: " << d_len << endl);
+    // When we get to the end of a Sequence, reset the row number counter so
+    // that, in case this is an inner sequence, the next instance will be read
+    // and the "Trying to back up in a Sequence" error won't be generated.
+    if (++d_current > d_len) {
+	DBG(cerr << "Leaving TestSequence::read for " << name()
+	         << " because d_current(" << d_current
+		 << ") > d_len(" << d_len << ")" << endl);
+        d_current = 0;                  // reset
+        set_unsent_data(false);
+        reset_row_number();
+        return false;                   // No more values
+    }
+        
+    Vars_iter i = var_begin();
+    while (i != var_end()) {
+        if ((*i)->send_p() || (*i)->is_in_selection()) {
+            DBG(cerr << "Calling " << (*i)->name() << "->read()" << endl);
+            (*i)->read();
+        }
+        ++i;
+    }
+    
+    set_unsent_data(true);
+    DBG(cerr << "Leaving TestSequence::read for " << name() << endl);
+    return true;
+}
+
+void
+TestSequence::set_series_values(bool sv)
+{
+    Vars_iter i = var_begin();
+    while (i != var_end()) {
+        dynamic_cast<TestCommon&>(*(*i)).set_series_values(sv);
+        ++i;
+    }
+    
+    d_series_values = sv;
+}
+
+int
+TestSequence::length()
+{
+    return 5;
+}
diff --git a/tests/TestSequence.h b/tests/TestSequence.h
new file mode 100644
index 0000000..8cbb462
--- /dev/null
+++ b/tests/TestSequence.h
@@ -0,0 +1,72 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the class TestSequence. See TestByte.h
+//
+// jhrg 1/12/95
+
+#ifndef _testsequence_h
+#define _testsequence_h 1
+
+#include "Sequence.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestSequence: public Sequence, public TestCommon {
+private:
+    int d_len;
+    int d_current;
+    bool d_series_values;
+    
+    void _duplicate(const TestSequence &ts);
+
+public:
+    TestSequence(const string &n);
+    TestSequence(const string &n, const string &d);
+    TestSequence(const TestSequence &rhs);
+
+    virtual ~TestSequence();
+ 
+    TestSequence &operator=(const TestSequence &rhs);
+    virtual BaseType *ptr_duplicate();
+
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool);
+    bool get_series_values() { return d_series_values; }
+
+    virtual int length();
+};
+
+#endif // _testsequence_h
diff --git a/tests/TestStr.cc b/tests/TestStr.cc
new file mode 100644
index 0000000..15ac15a
--- /dev/null
+++ b/tests/TestStr.cc
@@ -0,0 +1,117 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestStr. See TestByte.cc
+//
+// jhrg 1/12/95
+
+
+#include "config.h"
+
+#include <string>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestStr.h"
+#include "util.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestStr::_duplicate(const TestStr &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+
+TestStr::TestStr(const string &n) : Str(n), d_series_values(false)
+{
+}
+
+TestStr::TestStr(const string &n, const string &d)
+    : Str(n, d), d_series_values(false)
+{
+}
+
+TestStr::TestStr(const TestStr &rhs) : Str(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestStr &
+TestStr::operator=(const TestStr &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Str &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+BaseType *
+TestStr::ptr_duplicate()
+{
+    return new TestStr(*this);
+}
+
+void 
+TestStr::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestStr::read()
+{
+    static int count = 0;
+    
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    string dods_str_test = "Silly test string: " + long_to_string(++count);
+    (void) val2buf(&dods_str_test);
+
+    set_read_p(true);
+
+    return true;
+}
diff --git a/tests/TestStr.h b/tests/TestStr.h
new file mode 100644
index 0000000..cb99601
--- /dev/null
+++ b/tests/TestStr.h
@@ -0,0 +1,72 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1997,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for TestStr type. See TestByte.h
+//
+// jhrg 1/12/95
+
+#ifndef _teststr_h
+#define _teststr_h 1
+
+
+#include <string>
+
+#include "dods-limits.h"
+#include "Str.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestStr: public Str, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestStr &ts);
+
+public:
+    TestStr(const string &n);
+    TestStr(const string &n, const string &d);
+    TestStr(const TestStr &rhs);
+
+    virtual ~TestStr() {}
+
+    TestStr &operator=(const TestStr &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif //_teststr_h
+
diff --git a/tests/TestStructure.cc b/tests/TestStructure.cc
new file mode 100644
index 0000000..4b0fa22
--- /dev/null
+++ b/tests/TestStructure.cc
@@ -0,0 +1,150 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for the class TestStructure. See TestByte.cc
+//
+// jhrg 1/12/95
+
+#define DODS_DEBUG
+
+#include "config.h"
+#include "TestStructure.h"
+#include "debug.h"
+
+void
+TestStructure::_duplicate(const TestStructure &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+BaseType *
+TestStructure::ptr_duplicate()
+{
+    return new TestStructure(*this);
+}
+
+TestStructure::TestStructure(const TestStructure &rhs) : Structure(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestStructure &
+TestStructure::operator=(const TestStructure &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Structure &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+TestStructure::TestStructure(const string &n) : Structure(n),
+        d_series_values(false)
+{
+}
+
+TestStructure::TestStructure(const string &n, const string &d)
+    : Structure(n, d), d_series_values(false)
+{
+}
+
+TestStructure::~TestStructure()
+{
+}
+
+void
+TestStructure::output_values(std::ostream &out)
+{
+    out << "{ " ;
+
+    bool value_written = false;
+    Vars_citer i = var_begin();
+
+    // Write the first (and maybe only) value.
+    while(i != var_end() && ! value_written) {
+        if ((*i)->send_p()) {
+            (*i++)->print_val(out, "", false);
+            value_written = true;
+        }
+        else {
+            ++i;
+        }
+    }
+    // Each subsequent value will be preceded by a comma
+    while(i != var_end()) {
+        if ((*i)->send_p()) {
+            out << ", ";
+            (*i++)->print_val(out, "", false);
+        }
+        else {
+            ++i;
+        }
+    }
+
+    out << " }" ;
+}
+
+// For this `Test' class, run the read mfunc for each of variables which
+// comprise the structure.
+
+bool
+TestStructure::read()
+{
+    if (read_p())
+	return true;
+
+    for (Vars_iter i = var_begin(); i != var_end(); i++)
+    {
+	if (!(*i)->read())
+	{
+	    return false;
+	}
+    }
+
+    set_read_p(true);
+
+    return true;
+}
+
+void
+TestStructure::set_series_values(bool sv)
+{
+    Vars_iter i = var_begin();
+    while (i != var_end()) {
+        dynamic_cast<TestCommon&>(*(*i)).set_series_values(sv);
+        ++i;
+    }
+
+    d_series_values = sv;
+}
diff --git a/tests/TestStructure.h b/tests/TestStructure.h
new file mode 100644
index 0000000..18ba4c8
--- /dev/null
+++ b/tests/TestStructure.h
@@ -0,0 +1,67 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for the class TestStructure. See TestByte.h
+//
+// jhrg 1/12/95
+
+#ifndef _teststructure_h
+#define _teststructure_h 1
+
+#include "Structure.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestStructure: public Structure, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestStructure &ts);
+
+public:
+    TestStructure(const string &n);
+    TestStructure(const string &n, const string &d);
+    TestStructure(const TestStructure &rhs);
+
+    virtual ~TestStructure();
+
+    TestStructure &operator=(const TestStructure &rhs);
+
+    virtual BaseType *ptr_duplicate();
+
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool);
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _teststructure_h
diff --git a/tests/TestTypeFactory.cc b/tests/TestTypeFactory.cc
new file mode 100644
index 0000000..c9cf15a
--- /dev/null
+++ b/tests/TestTypeFactory.cc
@@ -0,0 +1,126 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+
+#include <string>
+
+#include "TestByte.h"
+#include "TestInt16.h"
+#include "TestUInt16.h"
+#include "TestInt32.h"
+#include "TestUInt32.h"
+#include "TestFloat32.h"
+#include "TestFloat64.h"
+#include "TestStr.h"
+#include "TestUrl.h"
+#include "TestArray.h"
+#include "TestStructure.h"
+#include "TestSequence.h"
+#include "TestGrid.h"
+
+#include "BaseTypeFactory.h"
+#include "TestTypeFactory.h"
+
+#include "debug.h"
+
+Byte *
+TestTypeFactory::NewByte(const string &n ) const 
+{ 
+    return new TestByte(n);
+}
+
+Int16 *
+TestTypeFactory::NewInt16(const string &n ) const 
+{ 
+    return new TestInt16(n); 
+}
+
+UInt16 *
+TestTypeFactory::NewUInt16(const string &n ) const 
+{ 
+    return new TestUInt16(n);
+}
+
+Int32 *
+TestTypeFactory::NewInt32(const string &n ) const 
+{ 
+    DBG(cerr << "Inside TestTypeFactory::NewInt32" << endl);
+    return new TestInt32(n);
+}
+
+UInt32 *
+TestTypeFactory::NewUInt32(const string &n ) const 
+{ 
+    return new TestUInt32(n);
+}
+
+Float32 *
+TestTypeFactory::NewFloat32(const string &n ) const 
+{ 
+    return new TestFloat32(n);
+}
+
+Float64 *
+TestTypeFactory::NewFloat64(const string &n ) const 
+{ 
+    return new TestFloat64(n);
+}
+
+Str *
+TestTypeFactory::NewStr(const string &n ) const 
+{ 
+    return new TestStr(n);
+}
+
+Url *
+TestTypeFactory::NewUrl(const string &n ) const 
+{ 
+    return new TestUrl(n);
+}
+
+Array *
+TestTypeFactory::NewArray(const string &n , BaseType *v) const 
+{ 
+    return new TestArray(n, v);
+}
+
+Structure *
+TestTypeFactory::NewStructure(const string &n ) const 
+{ 
+    return new TestStructure(n);
+}
+
+Sequence *
+TestTypeFactory::NewSequence(const string &n ) const 
+{
+    DBG(cerr << "Inside TestTypeFactory::NewSequence" << endl);
+    return new TestSequence(n);
+}
+
+Grid *
+TestTypeFactory::NewGrid(const string &n ) const 
+{ 
+    return new TestGrid(n);
+}
diff --git a/tests/TestTypeFactory.h b/tests/TestTypeFactory.h
new file mode 100644
index 0000000..c40a923
--- /dev/null
+++ b/tests/TestTypeFactory.h
@@ -0,0 +1,73 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#ifndef test_type_factory_h
+#define test_type_factory_h
+
+#include <string>
+
+#include "BaseTypeFactory.h"
+
+class TestByte;
+class TestInt16;
+class TestUInt16;
+class TestInt32;
+class TestUInt32;
+class TestFloat32;
+class TestFloat64;
+class TestStr;
+class TestUrl;
+class TestArray;
+class TestStructure;
+class TestSequence;
+class TestGrid;
+
+using namespace libdap ;
+
+/** A factory for the TestByte, ..., TestGrid types.
+    @author James Gallagher */
+class TestTypeFactory : public BaseTypeFactory {
+public:
+    TestTypeFactory() {} 
+    virtual ~TestTypeFactory() {}
+
+    virtual Byte *NewByte(const string &n = "") const;
+    virtual Int16 *NewInt16(const string &n = "") const;
+    virtual UInt16 *NewUInt16(const string &n = "") const;
+    virtual Int32 *NewInt32(const string &n = "") const;
+    virtual UInt32 *NewUInt32(const string &n = "") const;
+    virtual Float32 *NewFloat32(const string &n = "") const;
+    virtual Float64 *NewFloat64(const string &n = "") const;
+
+    virtual Str *NewStr(const string &n = "") const;
+    virtual Url *NewUrl(const string &n = "") const;
+
+    virtual Array *NewArray(const string &n = "", BaseType *v = 0) const;
+    virtual Structure *NewStructure(const string &n = "") const;
+    virtual Sequence *NewSequence(const string &n = "") const;
+    virtual Grid *NewGrid(const string &n = "") const;
+};
+
+#endif // test_type_factory_h
diff --git a/tests/TestUInt16.cc b/tests/TestUInt16.cc
new file mode 100644
index 0000000..b9cb0f7
--- /dev/null
+++ b/tests/TestUInt16.cc
@@ -0,0 +1,119 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestUInt16. See TestByte.cc
+//
+// 3/22/99 jhrg
+
+
+#include "config.h"
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestUInt16.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestUInt16::_duplicate(const TestUInt16 &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+
+TestUInt16::TestUInt16(const string &n) : UInt16(n), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestUInt16::TestUInt16(const string &n, const string &d)
+    : UInt16(n, d), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestUInt16::TestUInt16(const TestUInt16 &rhs) : UInt16(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestUInt16 &
+TestUInt16::operator=(const TestUInt16 &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<UInt16 &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+
+BaseType *
+TestUInt16::ptr_duplicate()
+{
+    return new TestUInt16(*this);
+}
+
+void 
+TestUInt16::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestUInt16::read()
+{
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+        _buf = (short)(16 * _buf);
+    }
+    else {
+        _buf = 64000;
+    }
+    
+    set_read_p(true);
+    
+    return true;
+}
diff --git a/tests/TestUInt16.h b/tests/TestUInt16.h
new file mode 100644
index 0000000..1a10d6e
--- /dev/null
+++ b/tests/TestUInt16.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// TestUInt16 interface. See TestByte.h for more info.
+//
+// 3/22/99 jhrg
+
+#ifndef _testuint16_h
+#define _testuint16_h 1
+
+
+#include "UInt16.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestUInt16: public UInt16, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestUInt16 &ts);
+
+public:
+    TestUInt16(const string &n);
+    TestUInt16(const string &n, const string &d);
+    TestUInt16(const TestUInt16 &rhs);
+
+    virtual ~TestUInt16() {}
+
+    TestUInt16 &operator=(const TestUInt16 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testuint16_h
+
diff --git a/tests/TestUInt32.cc b/tests/TestUInt32.cc
new file mode 100644
index 0000000..5026a6f
--- /dev/null
+++ b/tests/TestUInt32.cc
@@ -0,0 +1,119 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestUInt32. See TestByte.cc
+//
+// jhrg 10/27/96
+
+
+#include "config.h"
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestUInt32.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestUInt32::_duplicate(const TestUInt32 &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+
+TestUInt32::TestUInt32(const string &n) : UInt32(n), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestUInt32::TestUInt32(const string &n, const string &d)
+    : UInt32(n, d), d_series_values(false)
+{
+    _buf = 1;
+}
+
+TestUInt32::TestUInt32(const TestUInt32 &rhs) : UInt32(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestUInt32 &
+TestUInt32::operator=(const TestUInt32 &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<UInt32 &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+
+BaseType *
+TestUInt32::ptr_duplicate()
+{
+    return new TestUInt32(*this);
+}
+
+void 
+TestUInt32::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestUInt32::read()
+{
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    if (get_series_values()) {
+        _buf = 32 * _buf;
+    }
+    else {
+        _buf = 0xf0000000;		// about 4 billion
+    }
+
+    set_read_p(true);
+    
+    return true;
+}
diff --git a/tests/TestUInt32.h b/tests/TestUInt32.h
new file mode 100644
index 0000000..00102d7
--- /dev/null
+++ b/tests/TestUInt32.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1996,1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// TestUInt32 interface. See TestByte.h for more info.
+//
+// jhrg 10/27/96
+
+#ifndef _testuint32_h
+#define _testuint32_h 1
+
+
+#include "UInt32.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestUInt32: public UInt32, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestUInt32 &ts);
+
+public:
+    TestUInt32(const string &n);
+    TestUInt32(const string &n, const string &d);
+    TestUInt32(const TestUInt32 &rhs);
+
+    virtual ~TestUInt32() {}
+
+    TestUInt32 &operator=(const TestUInt32 &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testuint32_h
+
diff --git a/tests/TestUrl.cc b/tests/TestUrl.cc
new file mode 100644
index 0000000..ce00a99
--- /dev/null
+++ b/tests/TestUrl.cc
@@ -0,0 +1,114 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Implementation for TestUrl. See TestByte.cc
+//
+// jhrg 1/12/95
+
+
+#include "config.h"
+
+#include <string>
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include "TestUrl.h"
+
+extern int test_variable_sleep_interval;
+
+void
+TestUrl::_duplicate(const TestUrl &ts)
+{
+    d_series_values = ts.d_series_values;
+}
+
+TestUrl::TestUrl(const string &n) : Url(n), d_series_values(false)
+{
+}
+
+TestUrl::TestUrl(const string &n, const string &d)
+    : Url(n), d_series_values(false)
+{
+}
+
+TestUrl::TestUrl(const TestUrl &rhs) : Url(rhs), TestCommon(rhs)
+{
+    _duplicate(rhs);
+}
+
+TestUrl &
+TestUrl::operator=(const TestUrl &rhs)
+{
+    if (this == &rhs)
+	return *this;
+
+    dynamic_cast<Url &>(*this) = rhs; // run Constructor=
+
+    _duplicate(rhs);
+
+    return *this;
+}
+
+BaseType *
+TestUrl::ptr_duplicate()
+{
+    return new TestUrl(*this);
+}
+
+void 
+TestUrl::output_values(std::ostream &out)
+{
+    print_val(out, "", false);
+}
+
+bool
+TestUrl::read()
+{
+    if (read_p())
+	return true;
+
+    if (test_variable_sleep_interval > 0)
+	sleep(test_variable_sleep_interval);
+
+    string url_test="http://dcz.gso.uri.edu/avhrr-archive/archive.html";
+
+    val2buf(&url_test);
+
+    set_read_p(true);
+
+    return true;
+}
diff --git a/tests/TestUrl.h b/tests/TestUrl.h
new file mode 100644
index 0000000..4c088d1
--- /dev/null
+++ b/tests/TestUrl.h
@@ -0,0 +1,69 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Interface for TestUrl type. See TestByte.h
+//
+// jhrg 1/12/95
+
+#ifndef _testurl_h
+#define _testurl_h 1
+
+
+#include "Url.h"
+#include "TestCommon.h"
+
+using namespace libdap ;
+
+class TestUrl: public Url, public TestCommon {
+    bool d_series_values;
+    void _duplicate(const TestUrl &ts);
+
+public:
+    TestUrl(const string &n);
+    TestUrl(const string &n, const string &d);
+    TestUrl(const TestUrl &rhs);
+
+    virtual ~TestUrl() {}
+
+    TestUrl &operator=(const TestUrl &rhs);
+
+    virtual BaseType *ptr_duplicate();
+    
+    virtual bool read();
+    
+    virtual void output_values(std::ostream &out);
+
+    void set_series_values(bool sv) { d_series_values = sv; }
+    bool get_series_values() { return d_series_values; }
+};
+
+#endif // _testurl_h
+
diff --git a/tests/atconfig b/tests/atconfig
new file mode 100644
index 0000000..bb29e98
--- /dev/null
+++ b/tests/atconfig
@@ -0,0 +1,20 @@
+# Configurable variable values for building test suites.
+# Generated by ./config.status.
+# Copyright (C) 2009 Free Software Foundation, Inc.
+
+# The test suite will define top_srcdir=/../.. etc.
+at_testdir='tests'
+abs_builddir='/Users/ndp/OPeNDAP/Projects/Hyrax/swdev/hyrax-1.7.0/src/libdap/tests'
+at_srcdir='.'
+abs_srcdir='/Users/ndp/OPeNDAP/Projects/Hyrax/swdev/hyrax-1.7.0/src/libdap/tests'
+at_top_srcdir='..'
+abs_top_srcdir='/Users/ndp/OPeNDAP/Projects/Hyrax/swdev/hyrax-1.7.0/src/libdap'
+at_top_build_prefix='../'
+abs_top_builddir='/Users/ndp/OPeNDAP/Projects/Hyrax/swdev/hyrax-1.7.0/src/libdap'
+
+# Backward compatibility with Autotest <= 2.59b:
+at_top_builddir=$at_top_build_prefix
+
+AUTOTEST_PATH='.'
+
+SHELL=${CONFIG_SHELL-'/bin/sh'}
diff --git a/tests/atlocal b/tests/atlocal
new file mode 100644
index 0000000..fa30917
--- /dev/null
+++ b/tests/atlocal
@@ -0,0 +1,5 @@
+# 
+# Empty file. Use this to customize shell variables, et c., passed to the 
+# autotest-generated script.
+# 
+# : ${path_to_exec=`pwd`}
diff --git a/tests/atlocal.in b/tests/atlocal.in
new file mode 100644
index 0000000..f5e34c8
--- /dev/null
+++ b/tests/atlocal.in
@@ -0,0 +1,5 @@
+# 
+# Empty file. Use this to customize shell variables, et c., passed to the 
+# autotest-generated script.
+# 
+# : ${path_to_exec=`pwd`}
\ No newline at end of file
diff --git a/tests/das-test.cc b/tests/das-test.cc
new file mode 100644
index 0000000..ede4475
--- /dev/null
+++ b/tests/das-test.cc
@@ -0,0 +1,378 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Test the DAS class.
+// Read attributes from one or more files, printing the resulting table to
+// stdout. If a file is named `-' read from stdin for that file. The option
+// `-d' causes new/delete run-time debugging to be turned on.
+//
+// jhrg 7/25/94
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: das-test.cc 22703 2010-05-11 18:10:01Z jimg $"};
+
+#include <cstdlib>
+#include <string>
+#include <GetOpt.h>
+
+#define YYSTYPE char *
+
+#include "DAS.h"
+#include "das.tab.hh"
+#include "Error.h"
+
+using namespace libdap ;
+
+void plain_driver(DAS &das, bool deref_alias);
+void load_attr_table(AttrTable at);
+void load_attr_table_ptr(AttrTable *atp);
+void parser_driver(DAS &das, bool deref_alias, bool as_xml);
+void test_scanner();
+
+int daslex();
+
+extern int dasdebug;
+const char *prompt = "das-test: ";
+const char *version = "version 1.19";
+
+using namespace std;
+
+void
+usage(string name)
+{
+    fprintf( stderr, "usage: %s %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n",
+		     name.c_str(),
+		     "[-v] [-s] [-d] [-c] [-p] [rx] {< in-file > out-file}",
+		     "s: Test the DAS scanner.",
+		     "p: Scan and parse from <in-file>; print to <out-file>.",
+		     "c: Test building the DAS from C++ code.",
+		     "v: Print the version of das-test and exit.",
+		     "d: Print parser debugging information.",
+		     "r: Print the DAS with aliases deReferenced.",
+		     "x: Print as xml.") ;
+}
+
+int main(int argc, char *argv[])
+{
+
+    GetOpt getopt (argc, argv, "scpvdrx");
+    int option_char;
+    bool parser_test = false;
+    bool scanner_test = false;
+    bool code_test = false;
+    bool deref_alias = false;
+    bool as_xml = false;
+    while ((option_char = getopt ()) != EOF)
+	switch (option_char)
+	  {
+	    case 'p':
+	      parser_test = true;
+	      break;
+	    case 's':
+	      scanner_test = true;
+	      break;
+	    case 'c':
+	      code_test = true;
+	      break;
+	    case 'v':
+	      fprintf( stderr, "%s: %s\n", argv[0], version ) ;
+	      return 0;
+	    case 'd':
+	      dasdebug = 1;
+	      break;
+	    case 'r':
+	      deref_alias = true;
+	      break;
+	    case 'x':
+	        as_xml = true;
+	        break;
+	    case '?':
+	    default:
+	      usage(argv[0]);
+              return 1;
+	  }
+
+    DAS das;
+
+    if (!parser_test && !scanner_test && !code_test) {
+	usage(argv[0]);
+	return 1;
+    }
+
+    try {
+      if (parser_test)
+	parser_driver(das, deref_alias, as_xml);
+
+      if (scanner_test)
+	test_scanner();
+
+      if (code_test)
+	plain_driver(das, deref_alias);
+    }
+    catch (Error &e) {
+	cerr << "Caught Error object:" << endl;
+	cerr << e.get_error_message() << endl;
+	return 1;
+    }
+
+    return 0;
+}
+
+void
+test_scanner()
+{
+    int tok;
+
+    fprintf( stdout, "%s", prompt ) ; // first prompt
+    fflush( stdout ) ;
+    while ((tok = daslex())) {
+	switch (tok) {
+	  case SCAN_ATTR:
+	    fprintf( stdout, "ATTR\n" ) ;
+	    break;
+	  case SCAN_ALIAS:
+	    fprintf( stdout, "ALIAS\n" ) ;
+	    break;
+	  case SCAN_WORD:
+	    fprintf( stdout, "WORD=%s\n", daslval ) ;
+	    break;
+
+	  case SCAN_BYTE:
+	    fprintf( stdout, "BYTE\n" ) ;
+	    break;
+	  case SCAN_INT16:
+	    fprintf( stdout, "INT16\n" ) ;
+	    break;
+	  case SCAN_UINT16:
+	    fprintf( stdout, "UINT16\n" ) ;
+	    break;
+	  case SCAN_INT32:
+	    fprintf( stdout, "INT32\n" ) ;
+	    break;
+	  case SCAN_UINT32:
+	    fprintf( stdout, "UINT32\n" ) ;
+	    break;
+	  case SCAN_FLOAT32:
+	    fprintf( stdout, "FLOAT32\n" ) ;
+	    break;
+	  case SCAN_FLOAT64:
+	    fprintf( stdout, "FLOAT64\n" ) ;
+	    break;
+	  case SCAN_STRING:
+	    fprintf( stdout, "STRING\n" ) ;
+	    break;
+          case SCAN_URL:
+            fprintf( stdout, "URL\n" ) ;
+            break;
+
+          case SCAN_XML:
+            fprintf( stdout, "OtherXML\n" ) ;
+            break;
+
+	  case '{':
+	    fprintf( stdout, "Left Brace\n" ) ;
+	    break;
+	  case '}':
+	    fprintf( stdout, "Right Brace\n" ) ;
+	    break;
+	  case ';':
+	    fprintf( stdout, "Semicolon\n" ) ;
+	    break;
+	  case ',':
+	    fprintf( stdout, "Comma\n" ) ;
+	    break;
+
+	  default:
+	    fprintf( stdout, "Error: Unrecognized input\n" ) ;
+	}
+	fprintf( stdout, "%s", prompt ) ; // print prompt after output
+	fflush( stdout ) ;
+    }
+}
+
+
+void
+parser_driver(DAS &das, bool deref_alias, bool as_xml)
+{
+    das.parse();
+
+    if (as_xml) {
+        das.get_top_level_attributes()->print_xml(stdout, "    ");
+    }
+    else
+        das.print(stdout, deref_alias);
+}
+
+// Given a DAS, add some stuff to it.
+
+void
+plain_driver(DAS &das, bool deref_alias)
+{
+    AttrTable *atp;
+    AttrTable *dummy;
+
+    string name = "test";
+    atp = new AttrTable;
+    load_attr_table_ptr(atp);
+    dummy = das.get_table(name);
+    das.add_table(name, atp);
+
+    name = "test2";
+    atp = new AttrTable;
+    load_attr_table_ptr(atp);
+    das.add_table(name, atp);
+
+    das.print(stdout, deref_alias);
+}
+
+// stuff an AttrTable full of values. Also, print it out.
+
+void
+load_attr_table(AttrTable at)
+{
+    at.append_attr("month", "String", "Feb");
+    at.append_attr("month", "String", "Feb");
+
+    at.append_attr("month_a", "String", "Jan");
+    at.append_attr("month_a", "String", "Feb");
+    at.append_attr("month_a", "String", "Mar");
+
+    at.append_attr("Date", "Int32", "12345");
+    at.append_attr("day", "Int32", "01");
+    at.append_attr("Time", "Float64", "3.1415");
+
+    fprintf( stdout, "Using the iterator:\n" ) ;
+    for (AttrTable::Attr_iter p2 = at.attr_begin(); p2 != at.attr_end(); p2++)
+    {
+		fprintf( stdout, "%s %s ", at.get_name(p2).c_str(),
+			at.get_type(p2).c_str() ) ;
+		for (unsigned i = 0; i < at.get_attr_num(p2); ++i)
+			fprintf( stdout, "%s ", at.get_attr(p2, i).c_str() ) ;
+		fprintf( stdout, "\n" ) ;
+    }
+
+    string name = "month";
+    fprintf( stdout, "Using String: %s %s %s\n",
+		     at.get_type(name).c_str(),
+		     at.get_attr(name, 0).c_str(),
+		     at.get_attr(name, 1).c_str()) ;
+    fprintf( stdout, "Using char *: %s %s %s\n",
+		     at.get_type("month").c_str(),
+		     at.get_attr("month", 0).c_str(),
+		     at.get_attr("month", 1).c_str() ) ;
+
+    at.del_attr("month");
+
+    fprintf( stdout, "After deletion:\n" ) ;
+    for (AttrTable::Attr_iter p3 = at.attr_begin(); p3 != at.attr_end(); p3++)
+    {
+		fprintf( stdout, "%s %s ", at.get_name(p3).c_str(),
+			at.get_type(p3).c_str() ) ;
+		for (unsigned i = 0; i < at.get_attr_num(p3); ++i)
+			fprintf( stdout, "%s ", at.get_attr(p3, i).c_str() ) ;
+		fprintf( stdout, "\n" ) ;
+    }
+
+    at.print(stdout);
+
+    fprintf( stdout, "After print:\n" ) ;
+    for (AttrTable::Attr_iter p4 = at.attr_begin(); p4 != at.attr_end(); p4++)
+    {
+	fprintf( stdout, "%s %s ", at.get_name(p4).c_str(),
+		at.get_type(p4).c_str() ) ;
+	for (unsigned i = 0; i < at.get_attr_num(p4); ++i)
+	     fprintf( stdout, "%s ", at.get_attr(p4, i).c_str() ) ;
+	fprintf( stdout, "\n" ) ;
+    }
+}
+
+// OK, now try it with a dymanic AttrTable
+
+void
+load_attr_table_ptr(AttrTable *at)
+{
+    at->append_attr("month", "String", "Feb");
+    at->append_attr("month", "String", "Feb");
+
+    at->append_attr("month_a", "String", "Jan");
+    at->append_attr("month_a", "String", "Feb");
+    at->append_attr("month_a", "String", "Mar");
+
+    at->append_attr("Date", "Int32", "12345");
+    at->append_attr("day", "Int32", "01");
+    at->append_attr("Time", "Float64", "3.1415");
+
+    fprintf( stdout, "Using the iterator:\n" ) ;
+    for (AttrTable::Attr_iter p2 = at->attr_begin(); p2 != at->attr_end(); p2++)
+    {
+		fprintf( stdout, "%s %s ", at->get_name(p2).c_str(),
+			at->get_type(p2).c_str() ) ;
+		for (unsigned i = 0; i < at->get_attr_num(p2); ++i)
+			fprintf( stdout, "%s ", at->get_attr(p2, i).c_str() ) ;
+		fprintf( stdout, "\n" ) ;
+    }
+
+    string name = "month";
+    fprintf( stdout, "Using String: %s %s %s\n",
+		     at->get_type(name).c_str(),
+		     at->get_attr(name, 0).c_str(),
+		     at->get_attr(name, 1).c_str() ) ;
+    fprintf( stdout, "Using char *: %s %s %s\n",
+		     at->get_type("month").c_str(),
+		     at->get_attr("month", 0).c_str(),
+		     at->get_attr("month", 1).c_str() ) ;
+
+    at->del_attr("month");
+
+    fprintf( stdout, "After deletion:\n" ) ;
+    for (AttrTable::Attr_iter p3 = at->attr_begin(); p3 != at->attr_end(); p3++)
+    {
+		fprintf( stdout, "%s %s ", at->get_name(p3).c_str(),
+			at->get_type(p3).c_str() ) ;
+		for (unsigned i = 0; i < at->get_attr_num(p3); ++i)
+			fprintf( stdout, "%s ", at->get_attr(p3, i).c_str() ) ;
+		fprintf( stdout, "\n" ) ;
+    }
+
+    at->print(stdout);
+
+    fprintf( stdout, "After print:\n" ) ;
+    for (AttrTable::Attr_iter p4 = at->attr_begin(); p4 !=at->attr_end(); p4++)
+    {
+		fprintf( stdout, "%s %s ", at->get_name(p4).c_str(),
+			at->get_type(p4).c_str() ) ;
+		for (unsigned i = 0; i < at->get_attr_num(p4); ++i)
+			fprintf( stdout, "%s ", at->get_attr(p4, i).c_str() ) ;
+		fprintf( stdout, "\n" ) ;
+    }
+}
+
diff --git a/tests/das-testsuite/bad_value_test.1.das b/tests/das-testsuite/bad_value_test.1.das
new file mode 100644
index 0000000..a2de533
--- /dev/null
+++ b/tests/das-testsuite/bad_value_test.1.das
@@ -0,0 +1,12 @@
+Attributes {
+    bad_values {
+	Byte x 257;
+	Int16 y 60000;
+	UInt16 z 70000;
+	Int32 a 2147483648;
+	UInt32 b 4294967296;
+
+	Float32 c 3.5E+38;
+	Float64 d 1.8E+308;
+    }
+}
diff --git a/tests/das-testsuite/bad_value_test.1.das.base b/tests/das-testsuite/bad_value_test.1.das.base
new file mode 100644
index 0000000..bc27c9a
--- /dev/null
+++ b/tests/das-testsuite/bad_value_test.1.das.base
@@ -0,0 +1,20 @@
+Attributes {
+    bad_values {
+        bad_values_dods_errors {
+            Byte x 257;
+            String x_explanation "`257' is not a Byte value.";
+            Int16 y 60000;
+            String y_explanation "`60000' is not an Int16 value.";
+            UInt16 z 70000;
+            String z_explanation "`70000' is not an UInt16 value.";
+            Int32 a 2147483648;
+            String a_explanation "`2147483648' is not an Int32 value.";
+            UInt32 b 4294967296;
+            String b_explanation "`4294967296' is not an UInt32 value.";
+            Float32 c 3.5E+38;
+            String c_explanation "`3.5E+38' is not a Float32 value.";
+            Float64 d 1.8E+308;
+            String d_explanation "`1.8E+308' is not a Float64 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/das.das b/tests/das-testsuite/das.das
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/das.das.base b/tests/das-testsuite/das.das.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/special.test.das b/tests/das-testsuite/special.test.das
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/special.test.das.base b/tests/das-testsuite/special.test.das.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/special.test.hdf.das b/tests/das-testsuite/special.test.hdf.das
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/special.test.hdf.das.base b/tests/das-testsuite/special.test.hdf.das.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/test.1.das b/tests/das-testsuite/test.1.das
new file mode 100644
index 0000000..32c9c4d
--- /dev/null
+++ b/tests/das-testsuite/test.1.das
@@ -0,0 +1,6 @@
+Attributes{
+    DODS_GLOBAL {
+	String About "This is used to test find_ancillary_das()";
+    }
+}
+
diff --git a/tests/das-testsuite/test.1.das.base b/tests/das-testsuite/test.1.das.base
new file mode 100644
index 0000000..a2e14c3
--- /dev/null
+++ b/tests/das-testsuite/test.1.das.base
@@ -0,0 +1,5 @@
+Attributes {
+    DODS_GLOBAL {
+        String About "This is used to test find_ancillary_das()";
+    }
+}
diff --git a/tests/das-testsuite/test.1.gz b/tests/das-testsuite/test.1.gz
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/test.11.das b/tests/das-testsuite/test.11.das
new file mode 100644
index 0000000..94bb19e
--- /dev/null
+++ b/tests/das-testsuite/test.11.das
@@ -0,0 +1,15 @@
+
+# -*- Perl -*-
+# test all sorts of numbers (do they all parse correctly?)
+
+Attributes {
+    test {
+	String names this, is, a, vector, of, strings;
+	Byte b 1, 0, 127, 255;
+	Int32 int_vec 1, 2, 2147483647; # nearly the bigest int32 allowed
+	Float64 float_vec 1.0, -1.0, +1.0, 0.2, -0.2, +0.2, .3, -.3, +.3,
+	                  -3.1415, -3.1415e-99, -3.1415e+99, +3.1415e-99,
+	                  -3., +2., 4.; # big float vector
+        Url where http://bozo.place.com/home.html;
+    }
+}
diff --git a/tests/das-testsuite/test.11.das.base b/tests/das-testsuite/test.11.das.base
new file mode 100644
index 0000000..c370f61
--- /dev/null
+++ b/tests/das-testsuite/test.11.das.base
@@ -0,0 +1,9 @@
+Attributes {
+    test {
+        String names "this", "is", "a", "vector", "of", "strings";
+        Byte b 1, 0, 127, 255;
+        Int32 int_vec 1, 2, 2147483647;
+        Float64 float_vec 1.0, -1.0, +1.0, 0.2, -0.2, +0.2, .3, -.3, +.3, -3.1415, -3.1415e-99, -3.1415e+99, +3.1415e-99, -3., +2., 4.;
+        Url where http://bozo.place.com/home.html;
+    }
+}
diff --git a/tests/das-testsuite/test.12.das b/tests/das-testsuite/test.12.das
new file mode 100644
index 0000000..830c23b
--- /dev/null
+++ b/tests/das-testsuite/test.12.das
@@ -0,0 +1,8 @@
+
+# test for bad floating point values
+
+Attributes {
+    var1 {
+        Float64 f1 3.0.0;
+    }
+}
diff --git a/tests/das-testsuite/test.12.das.base b/tests/das-testsuite/test.12.das.base
new file mode 100644
index 0000000..6408611
--- /dev/null
+++ b/tests/das-testsuite/test.12.das.base
@@ -0,0 +1,8 @@
+Attributes {
+    var1 {
+        var1_dods_errors {
+            Float64 f1 3.0.0;
+            String f1_explanation "`3.0.0' is not a Float64 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.13.das b/tests/das-testsuite/test.13.das
new file mode 100644
index 0000000..4f6d891
--- /dev/null
+++ b/tests/das-testsuite/test.13.das
@@ -0,0 +1,8 @@
+
+# more float testing
+
+Attributes {
+    var1 {
+        Float64 f1 -3..0;
+    }
+}
diff --git a/tests/das-testsuite/test.13.das.base b/tests/das-testsuite/test.13.das.base
new file mode 100644
index 0000000..7100705
--- /dev/null
+++ b/tests/das-testsuite/test.13.das.base
@@ -0,0 +1,8 @@
+Attributes {
+    var1 {
+        var1_dods_errors {
+            Float64 f1 -3..0;
+            String f1_explanation "`-3..0' is not a Float64 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.14.das b/tests/das-testsuite/test.14.das
new file mode 100644
index 0000000..0dd134d
--- /dev/null
+++ b/tests/das-testsuite/test.14.das
@@ -0,0 +1,8 @@
+
+# still more ... This should work
+
+Attributes {
+    var1 {
+        Float64 f1 3;
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.14.das.base b/tests/das-testsuite/test.14.das.base
new file mode 100644
index 0000000..679394c
--- /dev/null
+++ b/tests/das-testsuite/test.14.das.base
@@ -0,0 +1,5 @@
+Attributes {
+    var1 {
+        Float64 f1 3;
+    }
+}
diff --git a/tests/das-testsuite/test.15.das b/tests/das-testsuite/test.15.das
new file mode 100644
index 0000000..336ec02
--- /dev/null
+++ b/tests/das-testsuite/test.15.das
@@ -0,0 +1,8 @@
+
+# floats as ints; should not work
+
+Attributes {
+    var1 {
+        Int32 i1 3.0;
+    }
+}
diff --git a/tests/das-testsuite/test.15.das.base b/tests/das-testsuite/test.15.das.base
new file mode 100644
index 0000000..bbf1002
--- /dev/null
+++ b/tests/das-testsuite/test.15.das.base
@@ -0,0 +1,8 @@
+Attributes {
+    var1 {
+        var1_dods_errors {
+            Int32 i1 3.0;
+            String i1_explanation "`3.0' is not an Int32 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.16.das b/tests/das-testsuite/test.16.das
new file mode 100644
index 0000000..14bf10c
--- /dev/null
+++ b/tests/das-testsuite/test.16.das
@@ -0,0 +1,13 @@
+
+# Test variable redefinition error
+
+Attributes {
+    var1 {
+        Int32 i 1;
+	Float64 i 10.8; # this is an error since `i' is already an Int32
+	Float64 j 100.98;
+    }
+    var2 {
+	 Float64 i 1.8; # not an error; different variable
+    }
+}
diff --git a/tests/das-testsuite/test.16.das.base b/tests/das-testsuite/test.16.das.base
new file mode 100644
index 0000000..7eb080f
--- /dev/null
+++ b/tests/das-testsuite/test.16.das.base
@@ -0,0 +1,3 @@
+Caught Error object:
+Error parsing the text on line 7
+An attribute called `i' already exists but is of a different type
diff --git a/tests/das-testsuite/test.17.das b/tests/das-testsuite/test.17.das
new file mode 100644
index 0000000..4fcc8dc
--- /dev/null
+++ b/tests/das-testsuite/test.17.das
@@ -0,0 +1,13 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Byte b "this is not a byte";
+	byte c -256;
+	byte d 255;		# This on is OK; 4/5/96 NO, see dods-limits.h
+	byte e 2550;
+	byte f 2.55;
+    }
+}
diff --git a/tests/das-testsuite/test.17.das.base b/tests/das-testsuite/test.17.das.base
new file mode 100644
index 0000000..44314c5
--- /dev/null
+++ b/tests/das-testsuite/test.17.das.base
@@ -0,0 +1,15 @@
+Attributes {
+    test {
+        test_dods_errors {
+            Byte b "this is not a byte";
+            String b_explanation "`"this is not a byte"' is not a Byte value.";
+            Byte c -256;
+            String c_explanation "`-256' is not a Byte value.";
+            Byte e 2550;
+            String e_explanation "`2550' is not a Byte value.";
+            Byte f 2.55;
+            String f_explanation "`2.55' is not a Byte value.";
+        }
+        Byte d 255;
+    }
+}
diff --git a/tests/das-testsuite/test.18.das b/tests/das-testsuite/test.18.das
new file mode 100644
index 0000000..99cf481
--- /dev/null
+++ b/tests/das-testsuite/test.18.das
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float32 f 2.55;
+	Int16 x 6535;
+    }
+}
diff --git a/tests/das-testsuite/test.18.das.base b/tests/das-testsuite/test.18.das.base
new file mode 100644
index 0000000..e4109dd
--- /dev/null
+++ b/tests/das-testsuite/test.18.das.base
@@ -0,0 +1,6 @@
+Attributes {
+    test {
+        Float32 f 2.55;
+        Int16 x 6535;
+    }
+}
diff --git a/tests/das-testsuite/test.19.das b/tests/das-testsuite/test.19.das
new file mode 100644
index 0000000..b732fce
--- /dev/null
+++ b/tests/das-testsuite/test.19.das
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float64 f 2.55E-300;
+	Float32 g 2.55E-300;
+    }
+}
diff --git a/tests/das-testsuite/test.19.das.base b/tests/das-testsuite/test.19.das.base
new file mode 100644
index 0000000..1595f3e
--- /dev/null
+++ b/tests/das-testsuite/test.19.das.base
@@ -0,0 +1,9 @@
+Attributes {
+    test {
+        Float64 f 2.55E-300;
+        test_dods_errors {
+            Float32 g 2.55E-300;
+            String g_explanation "`2.55E-300' is not a Float32 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.1a.das b/tests/das-testsuite/test.1a.das
new file mode 100644
index 0000000..01f7a42
--- /dev/null
+++ b/tests/das-testsuite/test.1a.das
@@ -0,0 +1,54 @@
+
+
+#  -*- C++ -*-
+#
+#    This is a test of the das scanner and parser software. This file tests
+#    comments, attribute lists with missing parts, and multiple attribute
+#    lists (they should all coalesce into one attribute table.
+
+attributes {# weird
+    var1 {#test
+    	string name bob;	# bob is the only name allowed
+	string type human;	# for people ... 
+	int32 age 19;
+    }
+    var2 {
+	string name joe;
+	string type dog;   
+	int32 age 8;
+    }
+}   
+
+# This is a C++ type comment.
+# The scanner and parser should handle a text file with several
+# attribute-definintion sections.
+
+Attributes {
+    var3 {
+    	int32 size 8;
+	string color red;
+	string type art;
+    }
+    var4 {
+    }
+}
+
+ATTRIBUTES {
+    var5 {
+    	string height 5.0in.;
+	string units inches;
+	float64 max 5.0;
+    }
+}
+
+attributes {
+}
+
+attributes {
+    var5 {
+	string weight 100lbs;
+	string color red;
+    }
+}
+#
+# EOF must be at the end of this line (not on the line after)
\ No newline at end of file
diff --git a/tests/das-testsuite/test.1a.das.base b/tests/das-testsuite/test.1a.das.base
new file mode 100644
index 0000000..b066085
--- /dev/null
+++ b/tests/das-testsuite/test.1a.das.base
@@ -0,0 +1,26 @@
+Attributes {
+    var1 {
+        String name "bob";
+        String type "human";
+        Int32 age 19;
+    }
+    var2 {
+        String name "joe";
+        String type "dog";
+        Int32 age 8;
+    }
+    var3 {
+        Int32 size 8;
+        String color "red";
+        String type "art";
+    }
+    var4 {
+    }
+    var5 {
+        String height "5.0in.";
+        String units "inches";
+        Float64 max 5.0;
+        String weight "100lbs";
+        String color "red";
+    }
+}
diff --git a/tests/das-testsuite/test.2.das b/tests/das-testsuite/test.2.das
new file mode 100644
index 0000000..6f3158b
--- /dev/null
+++ b/tests/das-testsuite/test.2.das
@@ -0,0 +1,8 @@
+attributes {
+    a {
+	string b c;
+	string d 4;
+    }
+}
+
+# single letter ID's and EOF w/o a preceding return
diff --git a/tests/das-testsuite/test.2.das.base b/tests/das-testsuite/test.2.das.base
new file mode 100644
index 0000000..32d8dcf
--- /dev/null
+++ b/tests/das-testsuite/test.2.das.base
@@ -0,0 +1,6 @@
+Attributes {
+    a {
+        String b "c";
+        String d "4";
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.20.das b/tests/das-testsuite/test.20.das
new file mode 100644
index 0000000..5e41993
--- /dev/null
+++ b/tests/das-testsuite/test.20.das
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Int32 x 70000;
+	Int16 y 80000;
+    }
+}
diff --git a/tests/das-testsuite/test.20.das.base b/tests/das-testsuite/test.20.das.base
new file mode 100644
index 0000000..1b7a81a
--- /dev/null
+++ b/tests/das-testsuite/test.20.das.base
@@ -0,0 +1,9 @@
+Attributes {
+    test {
+        Int32 x 70000;
+        test_dods_errors {
+            Int16 y 80000;
+            String y_explanation "`80000' is not an Int16 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.21.das b/tests/das-testsuite/test.21.das
new file mode 100644
index 0000000..da6c8d2
--- /dev/null
+++ b/tests/das-testsuite/test.21.das
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float64 f 2.55E300;
+	Float32 g 2.55E300;
+    }
+}
diff --git a/tests/das-testsuite/test.21.das.base b/tests/das-testsuite/test.21.das.base
new file mode 100644
index 0000000..417c70b
--- /dev/null
+++ b/tests/das-testsuite/test.21.das.base
@@ -0,0 +1,9 @@
+Attributes {
+    test {
+        Float64 f 2.55E300;
+        test_dods_errors {
+            Float32 g 2.55E300;
+            String g_explanation "`2.55E300' is not a Float32 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.22.das b/tests/das-testsuite/test.22.das
new file mode 100644
index 0000000..7ba6c8d
--- /dev/null
+++ b/tests/das-testsuite/test.22.das
@@ -0,0 +1,9 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float64 f 2.55E400;
+    }
+}
diff --git a/tests/das-testsuite/test.22.das.base b/tests/das-testsuite/test.22.das.base
new file mode 100644
index 0000000..22da1d3
--- /dev/null
+++ b/tests/das-testsuite/test.22.das.base
@@ -0,0 +1,8 @@
+Attributes {
+    test {
+        test_dods_errors {
+            Float64 f 2.55E400;
+            String f_explanation "`2.55E400' is not a Float64 value.";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.23.das b/tests/das-testsuite/test.23.das
new file mode 100644
index 0000000..4146e5f
--- /dev/null
+++ b/tests/das-testsuite/test.23.das
@@ -0,0 +1,13 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+    }
+    
+    # Alias `var2' to the existing `var1'.
+    Alias var2 var1;
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.23.das.base b/tests/das-testsuite/test.23.das.base
new file mode 100644
index 0000000..b52482f
--- /dev/null
+++ b/tests/das-testsuite/test.23.das.base
@@ -0,0 +1,7 @@
+Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+    }
+    Alias var2 var1;
+}
diff --git a/tests/das-testsuite/test.24.das b/tests/das-testsuite/test.24.das
new file mode 100644
index 0000000..a535fa8
--- /dev/null
+++ b/tests/das-testsuite/test.24.das
@@ -0,0 +1,17 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+    
+    # Alias `var2' to the existing `var1.component'.
+    Alias component2 var1.component1;
+}
diff --git a/tests/das-testsuite/test.24.das.base b/tests/das-testsuite/test.24.das.base
new file mode 100644
index 0000000..b86511d
--- /dev/null
+++ b/tests/das-testsuite/test.24.das.base
@@ -0,0 +1,11 @@
+Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name "A part of the whole";
+        }
+    }
+    Alias component2 component1;
+}
diff --git a/tests/das-testsuite/test.25.das b/tests/das-testsuite/test.25.das
new file mode 100644
index 0000000..5b4cc45
--- /dev/null
+++ b/tests/das-testsuite/test.25.das
@@ -0,0 +1,17 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+    
+    # Alias `name' to the existing `var1.component1.name'.
+    Alias name var1.component1.name;
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.25.das.base b/tests/das-testsuite/test.25.das.base
new file mode 100644
index 0000000..2269c28
--- /dev/null
+++ b/tests/das-testsuite/test.25.das.base
@@ -0,0 +1,4 @@
+Caught Error object:
+Error parsing the text on line 16
+A value cannot be aliased to the top level of the DAS;
+Only containers may be present at that level of the DAS.
\ No newline at end of file
diff --git a/tests/das-testsuite/test.26.das b/tests/das-testsuite/test.26.das
new file mode 100644
index 0000000..63da382
--- /dev/null
+++ b/tests/das-testsuite/test.26.das
@@ -0,0 +1,15 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	alias z x;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.26.das.base b/tests/das-testsuite/test.26.das.base
new file mode 100644
index 0000000..2c48323
--- /dev/null
+++ b/tests/das-testsuite/test.26.das.base
@@ -0,0 +1,11 @@
+Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        Alias z x;
+        component1 {
+            Float64 g 6.02e23;
+            String name "A part of the whole";
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.27.das b/tests/das-testsuite/test.27.das
new file mode 100644
index 0000000..81be287
--- /dev/null
+++ b/tests/das-testsuite/test.27.das
@@ -0,0 +1,15 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+	Alias new_name component1;
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.27.das.base b/tests/das-testsuite/test.27.das.base
new file mode 100644
index 0000000..081f540
--- /dev/null
+++ b/tests/das-testsuite/test.27.das.base
@@ -0,0 +1,11 @@
+Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name "A part of the whole";
+        }
+        Alias new_name component1;
+    }
+}
diff --git a/tests/das-testsuite/test.28.das b/tests/das-testsuite/test.28.das
new file mode 100644
index 0000000..3c227c9
--- /dev/null
+++ b/tests/das-testsuite/test.28.das
@@ -0,0 +1,16 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+	
+	Alias z component1.g;
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.28.das.base b/tests/das-testsuite/test.28.das.base
new file mode 100644
index 0000000..b9a4194
--- /dev/null
+++ b/tests/das-testsuite/test.28.das.base
@@ -0,0 +1,11 @@
+Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name "A part of the whole";
+        }
+        Alias z component1.g;
+    }
+}
diff --git a/tests/das-testsuite/test.29.das b/tests/das-testsuite/test.29.das
new file mode 100644
index 0000000..d0e4071
--- /dev/null
+++ b/tests/das-testsuite/test.29.das
@@ -0,0 +1,16 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+    # This should fail since var1.comp does not exist.
+    alias var2 var1.comp;
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.29.das.base b/tests/das-testsuite/test.29.das.base
new file mode 100644
index 0000000..a7e400b
--- /dev/null
+++ b/tests/das-testsuite/test.29.das.base
@@ -0,0 +1,3 @@
+Caught Error object:
+Error parsing the text on line 15
+Could not find the attribute `var1.comp' in the attribute object.
diff --git a/tests/das-testsuite/test.3.Z b/tests/das-testsuite/test.3.Z
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/test.3.Z.das b/tests/das-testsuite/test.3.Z.das
new file mode 100644
index 0000000..e69de29
diff --git a/tests/das-testsuite/test.3.Z.das.base b/tests/das-testsuite/test.3.Z.das.base
new file mode 100644
index 0000000..bbcf63d
--- /dev/null
+++ b/tests/das-testsuite/test.3.Z.das.base
@@ -0,0 +1,4 @@
+Caught Error object:
+Error parsing the text on line 1
+The attribute object returned from the dataset was null
+Check that the URL is correct.
diff --git a/tests/das-testsuite/test.3.das b/tests/das-testsuite/test.3.das
new file mode 100644
index 0000000..294a21b
--- /dev/null
+++ b/tests/das-testsuite/test.3.das
@@ -0,0 +1,12 @@
+
+#  Test Quotes.
+
+Attributes {
+    var1 {
+	string comment "One thing about these long comments is that they
+might cause problems with memory - overwrites, ...";
+	string comment2 "This quote tests a \"quote within a quote\", he said";
+	string quote1 "\"";		# tricky
+	string quote2 "\7 seven";
+    }
+}
diff --git a/tests/das-testsuite/test.3.das.base b/tests/das-testsuite/test.3.das.base
new file mode 100644
index 0000000..d7ec9e6
--- /dev/null
+++ b/tests/das-testsuite/test.3.das.base
@@ -0,0 +1,9 @@
+Attributes {
+    var1 {
+        String comment "One thing about these long comments is that they
+might cause problems with memory - overwrites, ...";
+        String comment2 "This quote tests a \"quote within a quote\", he said";
+        String quote1 "\"";
+        String quote2 "\7 seven";
+    }
+}
diff --git a/tests/das-testsuite/test.30.das b/tests/das-testsuite/test.30.das
new file mode 100644
index 0000000..5b4bdfa
--- /dev/null
+++ b/tests/das-testsuite/test.30.das
@@ -0,0 +1,17 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+	
+	# This should fail.
+	Alias z comp.g;
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.30.das.base b/tests/das-testsuite/test.30.das.base
new file mode 100644
index 0000000..bba2b45
--- /dev/null
+++ b/tests/das-testsuite/test.30.das.base
@@ -0,0 +1,3 @@
+Caught Error object:
+Error parsing the text on line 15
+Could not find the attribute `comp.g' in the attribute object.
diff --git a/tests/das-testsuite/test.31.das b/tests/das-testsuite/test.31.das
new file mode 100644
index 0000000..9ff5bb5
--- /dev/null
+++ b/tests/das-testsuite/test.31.das
@@ -0,0 +1,20 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	    inner_component {
+		String tag "xyz123";
+		URL my_url "http://dcz.dods.org/";
+	    }
+	}
+	
+	Alias url_info var1.component1.inner_component;
+    }
+}
diff --git a/tests/das-testsuite/test.31.das.base b/tests/das-testsuite/test.31.das.base
new file mode 100644
index 0000000..2ca02d2
--- /dev/null
+++ b/tests/das-testsuite/test.31.das.base
@@ -0,0 +1,15 @@
+Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name "A part of the whole";
+            inner_component {
+                String tag "xyz123";
+                Url my_url "http://dcz.dods.org/";
+            }
+        }
+        Alias url_info inner_component;
+    }
+}
diff --git a/tests/das-testsuite/test.32.das b/tests/das-testsuite/test.32.das
new file mode 100644
index 0000000..710a48c
--- /dev/null
+++ b/tests/das-testsuite/test.32.das
@@ -0,0 +1,10 @@
+# -*- perl -*-
+#
+
+Attributes {
+    var1 {
+	 Float64 g 6.02e23;
+	 Float64 h NaN;
+	 Float32 i NaN;
+    }
+}
diff --git a/tests/das-testsuite/test.32.das.base b/tests/das-testsuite/test.32.das.base
new file mode 100644
index 0000000..8a4aea9
--- /dev/null
+++ b/tests/das-testsuite/test.32.das.base
@@ -0,0 +1,7 @@
+Attributes {
+    var1 {
+        Float64 g 6.02e23;
+        Float64 h NaN;
+        Float32 i NaN;
+    }
+}
diff --git a/tests/das-testsuite/test.33.das b/tests/das-testsuite/test.33.das
new file mode 100644
index 0000000..7a6b6f7
--- /dev/null
+++ b/tests/das-testsuite/test.33.das
@@ -0,0 +1,10 @@
+# -*- perl -*-
+#
+
+Attributes {
+    var1 {
+	 Float64 Float64 6.02e23;
+	 String Url "http://www.google.com/";
+	 Url String "http://huh.com/";
+    }
+}
diff --git a/tests/das-testsuite/test.33.das.base b/tests/das-testsuite/test.33.das.base
new file mode 100644
index 0000000..94477d2
--- /dev/null
+++ b/tests/das-testsuite/test.33.das.base
@@ -0,0 +1,7 @@
+Attributes {
+    var1 {
+        Float64 Float64 6.02e23;
+        String Url "http://www.google.com/";
+        Url String "http://huh.com/";
+    }
+}
diff --git a/tests/das-testsuite/test.34.das b/tests/das-testsuite/test.34.das
new file mode 100644
index 0000000..fdeb15d
--- /dev/null
+++ b/tests/das-testsuite/test.34.das
@@ -0,0 +1,10 @@
+Attributes {
+    var1 {
+        Int32 y#z 15;
+        component1 {
+	    inner%20component {
+	        String tag "xyz123";
+	    }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.34.das.base b/tests/das-testsuite/test.34.das.base
new file mode 100644
index 0000000..6bc6919
--- /dev/null
+++ b/tests/das-testsuite/test.34.das.base
@@ -0,0 +1,10 @@
+Attributes {
+    var1 {
+        Int32 y%23z 15;
+        component1 {
+            inner%20component {
+                String tag "xyz123";
+            }
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.35.das b/tests/das-testsuite/test.35.das
new file mode 100644
index 0000000..51c7aae
--- /dev/null
+++ b/tests/das-testsuite/test.35.das
@@ -0,0 +1,9 @@
+Attributes {
+    var1 {
+        %25component1 {
+	    inner%20%25component {
+	        String %25tag "xyz123";
+	    }
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/das-testsuite/test.35.das.base b/tests/das-testsuite/test.35.das.base
new file mode 100644
index 0000000..ed6b6b4
--- /dev/null
+++ b/tests/das-testsuite/test.35.das.base
@@ -0,0 +1,9 @@
+Attributes {
+    var1 {
+        %25component1 {
+            inner%20%25component {
+                String %25tag "xyz123";
+            }
+        }
+    }
+}
diff --git a/tests/das-testsuite/test.4.das b/tests/das-testsuite/test.4.das
new file mode 100644
index 0000000..e3b3e92
--- /dev/null
+++ b/tests/das-testsuite/test.4.das
@@ -0,0 +1,8 @@
+# This should work (now, it used to generate an error because `attributes'
+# is a reserved word.
+attributes {
+    a {
+	string b c;
+	int32 attributes 4;
+    }
+}
diff --git a/tests/das-testsuite/test.4.das.base b/tests/das-testsuite/test.4.das.base
new file mode 100644
index 0000000..398c0a4
--- /dev/null
+++ b/tests/das-testsuite/test.4.das.base
@@ -0,0 +1,6 @@
+Attributes {
+    a {
+        String b "c";
+        Int32 attributes 4;
+    }
+}
diff --git a/tests/das-testsuite/test.5.das b/tests/das-testsuite/test.5.das
new file mode 100644
index 0000000..04648c4
--- /dev/null
+++ b/tests/das-testsuite/test.5.das
@@ -0,0 +1,9 @@
+# Test unterminated quote
+
+attributes {
+    var10 {
+	string attr woof;
+	string quote "this quote has no end;
+    }
+}
+
diff --git a/tests/das-testsuite/test.5.das.base b/tests/das-testsuite/test.5.das.base
new file mode 100644
index 0000000..6956b8d
--- /dev/null
+++ b/tests/das-testsuite/test.5.das.base
@@ -0,0 +1,2 @@
+Caught Error object:
+Error scanning DAS object text: Unterminated quote (starts on line 6)
diff --git a/tests/das-testsuite/test.6.das b/tests/das-testsuite/test.6.das
new file mode 100644
index 0000000..2004581
--- /dev/null
+++ b/tests/das-testsuite/test.6.das
@@ -0,0 +1,10 @@
+
+#  Test unterminated comments. Old test, should fail miserably
+
+attributes {
+    var_11 {
+	string slota val1;
+	string slotb val2; /* a bad comment
+    }
+}
+
diff --git a/tests/das-testsuite/test.6.das.base b/tests/das-testsuite/test.6.das.base
new file mode 100644
index 0000000..9574dfa
--- /dev/null
+++ b/tests/das-testsuite/test.6.das.base
@@ -0,0 +1,4 @@
+Caught Error object:
+Error parsing the text on line 7 at or near: a
+Expected an attribute type (Byte, Int16, UInt16, Int32, UInt32, Float32,
+Float64, String or Url) followed by a name and value.
diff --git a/tests/das-testsuite/test.7.das b/tests/das-testsuite/test.7.das
new file mode 100644
index 0000000..8fab860
--- /dev/null
+++ b/tests/das-testsuite/test.7.das
@@ -0,0 +1,12 @@
+# -*- C++ -*-
+
+#  Test missing type specifier.
+
+Attributes {
+    aa {
+	int32 i 10;
+	float64 f 12.9;
+	string test test;
+	test2 my_test;
+    }
+}
diff --git a/tests/das-testsuite/test.7.das.base b/tests/das-testsuite/test.7.das.base
new file mode 100644
index 0000000..d2442b2
--- /dev/null
+++ b/tests/das-testsuite/test.7.das.base
@@ -0,0 +1,4 @@
+Caught Error object:
+Error parsing the text on line 10 at or near: my_test
+Expected an attribute type (Byte, Int16, UInt16, Int32, UInt32, Float32,
+Float64, String or Url) followed by a name and value.
diff --git a/tests/das-testsuite/test.8.das b/tests/das-testsuite/test.8.das
new file mode 100644
index 0000000..813eacf
--- /dev/null
+++ b/tests/das-testsuite/test.8.das
@@ -0,0 +1,9 @@
+#  -*- C++ -*-
+
+# Test attribute vectors.
+
+Attributes {
+    var0 {
+	String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+    }
+}
diff --git a/tests/das-testsuite/test.8.das.base b/tests/das-testsuite/test.8.das.base
new file mode 100644
index 0000000..2c47367
--- /dev/null
+++ b/tests/das-testsuite/test.8.das.base
@@ -0,0 +1,5 @@
+Attributes {
+    var0 {
+        String month "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Nov", "Dec";
+    }
+}
diff --git a/tests/das-testsuite/test.9.das b/tests/das-testsuite/test.9.das
new file mode 100644
index 0000000..66b87ee
--- /dev/null
+++ b/tests/das-testsuite/test.9.das
@@ -0,0 +1,18 @@
+
+#  -*- C++ -*-
+#
+# Test attribute vectors.
+
+Attributes {
+    var1 {
+	String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+    }
+    var2 {
+	String day Monday, Tuesday, Wed;
+	String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+	String name bob;
+	Int32 num 10;
+	String irrational 3.1415, 2.718, 1.414;
+	Float64 irrational_numbers 3.1415, 2.718, 1.414;
+    }
+}
diff --git a/tests/das-testsuite/test.9.das.base b/tests/das-testsuite/test.9.das.base
new file mode 100644
index 0000000..668d3c8
--- /dev/null
+++ b/tests/das-testsuite/test.9.das.base
@@ -0,0 +1,13 @@
+Attributes {
+    var1 {
+        String month "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Nov", "Dec";
+    }
+    var2 {
+        String day "Monday", "Tuesday", "Wed";
+        String month "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Nov", "Dec";
+        String name "bob";
+        Int32 num 10;
+        String irrational "3.1415", "2.718", "1.414";
+        Float64 irrational_numbers 3.1415, 2.718, 1.414;
+    }
+}
diff --git a/tests/dds-test.cc b/tests/dds-test.cc
new file mode 100644
index 0000000..522add3
--- /dev/null
+++ b/tests/dds-test.cc
@@ -0,0 +1,297 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Test the DDS scanner, parser and DDS class.
+//
+// jhrg 8/29/94
+
+#include "config.h"
+
+static char rcsid[] not_used = {"$Id: dds-test.cc 22703 2010-05-11 18:10:01Z jimg $"};
+
+#include <GetOpt.h>
+
+#include "parser.h"
+#include "dds.tab.hh"
+#include "BaseType.h"
+#include "Int32.h"
+#include "DDS.h"
+#include "util.h"
+#include "Error.h"
+
+using namespace libdap ;
+
+void test_scanner();
+void test_parser();
+void test_class();
+
+int ddslex();
+int ddsparse(DDS &);
+
+extern YYSTYPE ddslval;
+extern int ddsdebug;
+const char *prompt = "dds-test: ";
+
+void
+usage(string name)
+{
+    fprintf( stderr, "usage: %s %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n",
+		     name.c_str(),
+		     "[s] [pd] [c]",
+		     "s: Test the scanner.",
+		     "p: Test the parser; reads from stdin and prints the",
+		     "   internal structure to stdout.",
+		     "d: Turn on parser debugging. (only for the hard core.)",
+		     "c: Test the C++ code for manipulating DDS objects.",
+		     "   Reads from stdin, parses and writes the modified DDS",
+		     "   to stdout." ) ;
+}
+
+int
+main(int argc, char *argv[])
+{
+    GetOpt getopt (argc, argv, "spdc");
+    int option_char;
+    int scanner_test = 0, parser_test = 0, class_test = 0;
+
+    // process options
+
+    while ((option_char = getopt ()) != EOF)
+	switch (option_char)
+	  {
+	    case 'd':
+	      ddsdebug = 1;
+	      break;
+	    case 's':
+	      scanner_test = 1;
+	      break;
+	    case 'p':
+	      parser_test = 1;
+	      break;
+	    case 'c':
+	      class_test = 1;
+	      break;
+	    case '?':
+	    default:
+	      usage(argv[0]);
+	      return 1;
+	  }
+
+    if (!scanner_test && !parser_test && !class_test) {
+	usage(argv[0]);
+	return 1;
+    }
+
+    try {
+      if (scanner_test) {
+	test_scanner();
+      }
+
+      if (parser_test) {
+	test_parser();
+      }
+
+      if (class_test) {
+	test_class();
+      }
+    }
+    catch (Error &e) {
+      cerr << e.get_error_message() << endl;
+    }
+}
+
+void
+test_scanner(void)
+{
+    int tok;
+
+    cout << prompt << flush; // first prompt
+
+    while ((tok = ddslex())) {
+	switch (tok) {
+	  case SCAN_DATASET:
+	    cout << "DATASET" << endl;
+	    break;
+	  case SCAN_LIST:
+	    cout << "LIST" << endl;
+	    break;
+	  case SCAN_SEQUENCE:
+	    cout << "SEQUENCE" << endl;
+	    break;
+	  case SCAN_STRUCTURE:
+	    cout << "STRUCTURE" << endl;
+	    break;
+	  case SCAN_FUNCTION:
+	    cout << "FUNCTION" << endl;
+	    break;
+	  case SCAN_GRID:
+	    cout << "GRID" << endl;
+	    break;
+	  case SCAN_BYTE:
+	    cout << "BYTE" << endl;
+	    break;
+	  case SCAN_INT16:
+	    cout << "INT16" << endl;
+	    break;
+	  case SCAN_UINT16:
+	    cout << "UINT16" << endl;
+	    break;
+	  case SCAN_INT32:
+	    cout << "INT32" << endl;
+	    break;
+	  case SCAN_UINT32:
+	    cout << "UINT32" << endl;
+	    break;
+	  case SCAN_FLOAT32:
+	    cout << "FLOAT32" << endl;
+	    break;
+	  case SCAN_FLOAT64:
+	    cout << "FLOAT64" << endl;
+	    break;
+	  case SCAN_STRING:
+	    cout << "STRING" << endl;
+	    break;
+	  case SCAN_URL:
+	    cout << "Url" << endl;
+	    break;
+	  case SCAN_WORD:
+	    cout << "WORD: " << ddslval.word << endl;
+	    break;
+	  case '{':
+	    cout << "Left Brace" << endl;
+	    break;
+	  case '}':
+	    cout << "Right Brace" << endl;
+	    break;
+	  case '[':
+	    cout << "Left Bracket" << endl;
+	    break;
+	  case ']':
+	    cout << "Right Bracket" << endl;
+	    break;
+	  case ';':
+	    cout << "Semicolon" << endl;
+	    break;
+	  case ':':
+	    cout << "Colon" << endl;
+	    break;
+	  case '=':
+	    cout << "Assignment" << endl;
+	    break;
+	  default:
+	    cout << "Error: Unrecognized input" << endl;
+	}
+    cout << prompt << flush;  // print prompt after output
+    }
+}
+
+void
+test_parser(void)
+{
+    BaseTypeFactory *factory = new BaseTypeFactory;
+    DDS table(factory);
+    table.parse();
+
+    if (table.check_semantics())
+	cout << "DDS past semantic check" << endl ;
+    else
+	cout << "DDS failed semantic check" << endl ;
+
+    if (table.check_semantics(true))
+	cout << "DDS past full semantic check" << endl ;
+    else
+	cout << "DDS failed full semantic check" << endl ;
+
+    table.print( cout );
+
+    delete factory; factory = 0;
+}
+
+void
+test_class(void)
+{
+    BaseTypeFactory *factory = new BaseTypeFactory;
+    DDS table(factory);
+    table.parse();
+
+    if (table.check_semantics())
+	cout << "DDS past semantic check" << endl ;
+    else
+	cout << "DDS filed semantic check" << endl ;
+
+    if (table.check_semantics(true))
+	cout << "DDS past full semantic check" << endl ;
+    else
+	cout << "DDS filed full semantic check" << endl ;
+
+    table.print( cout );
+
+    DDS table2 = table;		// test copy ctor;
+    table2.print( cout );
+
+    BaseTypeFactory *factory2 = new BaseTypeFactory;
+    DDS table3(factory2);
+    table3 = table;		// test operator=
+
+    cout << "Dataset name: " << table.get_dataset_name() << endl ;
+
+    string name = "goofy";
+    table.add_var(table.get_factory()->NewInt32(name)); // table dtor should delete this object
+
+    table.print( cout );
+
+    BaseType *btp = table.var(name);
+
+    btp->print_decl(cout, "", true); // print out goofy w/semicolon
+
+    table.del_var(name);
+
+    table.print( cout );
+
+    table.add_var(table.get_factory()->NewInt32("goofy"));
+
+    table.print( cout );
+
+    btp = table.var("goofy");
+
+    btp->print_decl(cout, "", true); // print out goofy w/semicolon
+
+    table.del_var("goofy");
+
+    table.print( cout );
+
+    for (DDS::Vars_iter p = table.var_begin(); p != table.var_end(); p++)
+	(*p)->print_decl(cout, "", true);	// print them all w/semicolons
+
+    delete factory; factory = 0;
+    delete factory2; factory2 = 0;
+}
+
diff --git a/tests/dds-testsuite/3B42.980909.5.HDF.das.dds b/tests/dds-testsuite/3B42.980909.5.HDF.das.dds
new file mode 100644
index 0000000..36ecd48
--- /dev/null
+++ b/tests/dds-testsuite/3B42.980909.5.HDF.das.dds
@@ -0,0 +1,626 @@
+Attributes {
+    HDF_GLOBAL {
+    }
+    CoreMetadata {
+        OrbitNumber {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeBeginningDate {
+            String Value 1998/09/09;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeBeginningTime {
+            String Value 00:00:00;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeEndingDate {
+            String Value 1998/09/10;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeEndingTime {
+            String Value 00:00:00;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GranulePointer {
+            String Value "3B42.980909.5.HDF";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ShortName {
+            String Value "Surface Rain from Geostationary Satellites C";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SizeMBECSDataGranule {
+            Float64 Value 0.220007;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LongitudeOfMaximumLatitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SpatialCoverageType {
+            String Value "Horizontal";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EllipsoidName {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EquatorialRadius {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DenominatorFlatteningRatio {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitalModelName {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SemiMajorAxis {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MeanAnomaly {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RightAscensionNode {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ArgumentOfPerigee {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        Eccentricity {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        Inclination {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EpochTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EpochDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EpochMillisec {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        WestBoundingCoordinate {
+            Int32 Value -180;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EastBoundingCoordinate {
+            Int32 Value 180;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NorthBoundingCoordinate {
+            Int32 Value 40;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SouthBoundingCoordinate {
+            Int32 Value -40;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterLatitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterLongitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadiusValue {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LatitudeResolution {
+            String Value "1deg";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LongitudeResolution {
+            String Value "1deg";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GeographicCoordinateUnits {
+            String Value "Decimal Degrees";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        TemporalRangeType {
+            String Value "Continuous Range";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        QualityAssuranceParameterName {
+            String Value "ScienceQualityFlag";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        QualityAssuranceParameterValue {
+            String Value "NOT BEING INVESTIGATED";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ReprocessingActual {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        BrowsePointer {
+            String Value "3B42_BR.980909.5.BRO";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ScienceContact {
+            String Value "George Huffman";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MeanMotion {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitAdjustFlag {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AttitudeModeFlag {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SolarBetaAngleAtBeginningOfGranule {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SolarBetaAngleAtEndOfGranule {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SensorAlignment {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SensorAlignmentChannelOffsets {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ScanPathModel {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ScanPathModelParam {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EphemerisFileID {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+    }
+    ArchiveMetadata {
+        DataGaps {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NumberOfDataGaps {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AlgorithmVersion {
+            String Value "4.51";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ProductVersion {
+            Int32 Value 5;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ToolkitVersion {
+            String Value "5.6";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CalibrationCoefficientVersion {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MissingData {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        PercentOfBadOrMissingPixels {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MaximumValidValueofChannel {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MinimumValidValueofChannel {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MinMaxUnits {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitSize {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarWavelength {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MinimumReflectivityThreshold {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AlgorithmID {
+            String Value "3B42m2";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DataAccuracy {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        InputFiles {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DateOfGenerationOfInputFiles {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DataCenterSourceOfInputFiles {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GenerationDate {
+            String Value 2000-02-09T11:00:04.000Z;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DayNight {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SolarChannelGains {
+            String Value "(-9999.9,-9999.9,-9999.9,-9999.9)";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        TMIRolloverCoef {
+            String Value "(-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9)";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstScanUTCDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstScanUTCTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstScanUTCMilliseconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstSCSecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstSCSubsecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastScanUTCDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastScanUTCTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastScanUTCmilliseconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastSCSecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastSCSubsecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCFSeconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCFSubseconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCFflag {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LeapSecondsFlag {
+            String Value Data_Location, "Error processing EOS attributes", "Error processing EOS attributes";
+            String PGE "Error processing EOS attributes";
+            String Mandatory FALSE;
+        }
+        RadarSiteName {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarCity {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarState {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarCountry {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NumberOfVOS {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridOriginLatitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridOriginLongitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridOriginAltitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSpacingX {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSpacingY {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSpacingZ {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSizeX {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSizeY {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSizeZ {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DZCal {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GVL1C_Scale {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        Alpha {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RuntimeOptions {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AnomalyFlag {
+            String Value "NOT EMPTY";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SoftwareVersion {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DatabaseVersion {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        TotalQualityCode {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LongitudeOnEquator {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCDateOnEquator {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCTimeOnEquator {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCMillisecsOnEquator {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterScanUTCDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterScanUTCTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterScanUTCMillisec {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        FirstScanLat {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        FirstScanLon {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LastScanLat {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LastScanLon {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NumberOfRainScans {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+    }
+    percipitate_dim_0 {
+        String name "scan";
+    }
+    percipitate_dim_1 {
+        String name "longitude";
+    }
+    percipitate_dim_2 {
+        String name "latitude";
+    }
+    relError_dim_0 {
+        String name "scan";
+    }
+    relError_dim_1 {
+        String name "longitude";
+    }
+    relError_dim_2 {
+        String name "latitude";
+    }
+}
diff --git a/tests/dds-testsuite/3B42.980909.5.HDF.das.dds.base b/tests/dds-testsuite/3B42.980909.5.HDF.das.dds.base
new file mode 100644
index 0000000..b769c81
--- /dev/null
+++ b/tests/dds-testsuite/3B42.980909.5.HDF.das.dds.base
@@ -0,0 +1,3 @@
+Error parsing the text on line 1 at or near: Attributes
+The descriptor object returned from the dataset was null.
+Check that the URL is correct.
diff --git a/tests/dds-testsuite/3B42.980909.5.HDF.dds b/tests/dds-testsuite/3B42.980909.5.HDF.dds
new file mode 100644
index 0000000..259a06a
--- /dev/null
+++ b/tests/dds-testsuite/3B42.980909.5.HDF.dds
@@ -0,0 +1,8 @@
+Dataset {
+    Structure {
+        Structure {
+            Float32 percipitate[scan = 1][longitude = 360][latitude = 80];
+            Float32 relError[scan = 1][longitude = 360][latitude = 80];
+        } PlanetaryGrid;
+    } DATA_GRANULE;
+} 3B42.980909.5.HDF;
diff --git a/tests/dds-testsuite/3B42.980909.5.HDF.dds.base b/tests/dds-testsuite/3B42.980909.5.HDF.dds.base
new file mode 100644
index 0000000..e989526
--- /dev/null
+++ b/tests/dds-testsuite/3B42.980909.5.HDF.dds.base
@@ -0,0 +1,10 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Structure {
+            Float32 percipitate[scan = 1][longitude = 360][latitude = 80];
+            Float32 relError[scan = 1][longitude = 360][latitude = 80];
+        } PlanetaryGrid;
+    } DATA_GRANULE;
+} 3B42.980909.5.HDF;
diff --git a/tests/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds b/tests/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds
new file mode 100644
index 0000000..5e05236
--- /dev/null
+++ b/tests/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds
@@ -0,0 +1,39 @@
+Attributes {
+    HDF_GLOBAL {
+    }
+    CoreMetadata {
+        OrbitNumber {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeBeginningDate {
+            String Value 1998/09/09;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+#        TMIRolloverCoef {
+#            String Value "(-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9)";
+#            String Data_Location PGE;
+#            String Mandatory FALSE;
+#        }
+    }
+    percipitate_dim_0 {
+        String name "scan";
+    }
+    percipitate_dim_1 {
+        String name "longitude";
+    }
+    percipitate_dim_2 {
+        String name "latitude";
+    }
+    relError_dim_0 {
+        String name "scan";
+    }
+    relError_dim_1 {
+        String name "longitude";
+    }
+    relError_dim_2 {
+        String name "latitude";
+    }
+}
diff --git a/tests/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base b/tests/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base
new file mode 100644
index 0000000..682f3ea
--- /dev/null
+++ b/tests/dds-testsuite/3B42.980909.5.hacked.HDF.das.dds.base
@@ -0,0 +1,3 @@
+Error parsing the text on line 1 at or near: Attributes
+The descriptor object returned from the dataset was null.
+Check that the URL is correct.
\ No newline at end of file
diff --git a/tests/dds-testsuite/AsciiOutputTest1.dds b/tests/dds-testsuite/AsciiOutputTest1.dds
new file mode 100644
index 0000000..fa8652b
--- /dev/null
+++ b/tests/dds-testsuite/AsciiOutputTest1.dds
@@ -0,0 +1,33 @@
+# Used for the AsciiOutput unit tests.
+
+dataset {
+    Int32 a;
+
+    Structure {
+        Int32 b;
+        Float64 c;
+        String d;
+    } e;
+ 
+    Structure {
+        Int32 b;
+        Float64 c;
+        String d;
+    } f;
+
+    Grid {
+      array:
+        Byte xy[x=12][y=12];
+      maps:
+        Float64 x[12];
+	Float64 y[12];
+    } g;
+
+    Sequence {
+        Int16 j;
+	Sequence {
+	    Int16 i;
+        } h;
+    } k;
+
+} ascii_output_test;
diff --git a/tests/dds-testsuite/AsciiOutputTest1.dds.base b/tests/dds-testsuite/AsciiOutputTest1.dds.base
new file mode 100644
index 0000000..4a3a1de
--- /dev/null
+++ b/tests/dds-testsuite/AsciiOutputTest1.dds.base
@@ -0,0 +1,28 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 a;
+    Structure {
+        Int32 b;
+        Float64 c;
+        String d;
+    } e;
+    Structure {
+        Int32 b;
+        Float64 c;
+        String d;
+    } f;
+    Grid {
+      Array:
+        Byte xy[x = 12][y = 12];
+      Maps:
+        Float64 x[12];
+        Float64 y[12];
+    } g;
+    Sequence {
+        Int16 j;
+        Sequence {
+            Int16 i;
+        } h;
+    } k;
+} ascii_output_test;
diff --git a/tests/dds-testsuite/S2000415.HDF.das.dds b/tests/dds-testsuite/S2000415.HDF.das.dds
new file mode 100644
index 0000000..f51918e
--- /dev/null
+++ b/tests/dds-testsuite/S2000415.HDF.das.dds
@@ -0,0 +1,316 @@
+Attributes {
+    HDF_GLOBAL {
+        String Producer_Agency "NASA\\000";
+        String Producer_Institution "JPL\\000";
+        String Sensor_Name "NSCAT\\000";
+        String Project_ID "NSCAT\\000";
+        String SIS_ID "597-512-24/1996-07-01\\000";
+        String Build_ID "3.2.1/1996-11-05\\000";
+        String ADEOS_Data_Package_ID "S2\\000";
+        String ADEOS_Data_Package_Type "S\\000";
+        String Product_Creation_Time "1996-318T01:35:16.000\\000";
+        String Data_Type "L2\\000";
+        String Data_Status "COMPLETE\\000";
+        Int32 First_Rev_Number 415;
+        String First_Rev_Eq_Crossing_Time "1996-259T04:01:28.226\\000";
+        Float32 First_Rev_Eq_Crossing_Lon 279.983;
+        String First_Data_Time "1996-259T03:43:48.945\\000";
+        String Last_Data_Time "1996-259T05:09:48.997\\000";
+        Int32 Num_Expected_Output_Records 458;
+        Int32 Num_Actual_Output_Records 458;
+        String Ambig_Removal_Method "Baseline used\\000";
+        String HDF_Build_ID "JPL D-xxxxx 12/15/94\\000";
+        String HDF_SIS_ID "JPL D-12060 12/15/94\\000";
+        String HDF_Conversion_Organization "JPL PO.DAAC\\000";
+        String HDF_Conversion_Time "1996-320T17:32:34       ";
+        String Data_Format_Type "HDF\\000";
+    }
+    WVC_Lat {
+        String long_name "latitude";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Int16 valid_range -9000, 7771;
+    }
+    WVC_Lat_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Lat_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    WVC_Lon {
+        String long_name "longitude";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Uint16 valid_range 0, 31242;
+    }
+    WVC_Lon_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Lon_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Sigma0 {
+        String long_name "The total number of sigma-0 measurements";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 19;
+    }
+    Num_Sigma0_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Sigma0_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_12 {
+        String long_name "The total number of sigma-0s received from beam 1 or 2";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_12_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_12_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_34 {
+        String long_name "The total number of sigma-0s received from beam 3 or 4";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_34_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_34_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_56 {
+        String long_name "The total number of sigma-0s received from beam 5 or 6";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_56_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_56_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_78 {
+        String long_name "The total number of sigma-0s received from beam 7 or 8";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_78_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_78_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    WVC_Quality_Flag {
+        String long_name "WVC Quality Flag";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 3;
+    }
+    WVC_Quality_Flag_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Quality_Flag_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Mean_Wind {
+        String long_name "Mean Wind Speed";
+        String units "m/s";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2374;
+    }
+    Mean_Wind_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Mean_Wind_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Wind_Speed {
+        String long_name "Wind speed associated with a WVC";
+        String units "m/s";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2571;
+    }
+    Wind_Speed_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Wind_Speed_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Wind_Speed_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Wind_Dir {
+        String long_name "Wind direction solution associated with a WVC";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 35997;
+    }
+    Wind_Dir_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Wind_Dir_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Wind_Dir_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Error_Speed {
+        String long_name "Uncertainty estimated for the wind speed value";
+        String units "m/s";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2410;
+    }
+    Error_Speed_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Error_Speed_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Error_Speed_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Error_Dir {
+        String long_name "Uncertainty estimated for the wind direction value";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2435;
+    }
+    Error_Dir_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Error_Dir_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Error_Dir_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    MLE_Likelihood {
+        String long_name "Relative likelihood that a given win vector solution is correct";
+        Float64 scale_factor 0.1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Int16 valid_range -32768, 2825;
+    }
+    MLE_Likelihood_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    MLE_Likelihood_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    MLE_Likelihood_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Num_Ambigs {
+        String long_name "Number of ambiguous wind vectors reported for a given cell";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 4;
+    }
+    Num_Ambigs_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Ambigs_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+}
diff --git a/tests/dds-testsuite/S2000415.HDF.das.dds.base b/tests/dds-testsuite/S2000415.HDF.das.dds.base
new file mode 100644
index 0000000..b769c81
--- /dev/null
+++ b/tests/dds-testsuite/S2000415.HDF.das.dds.base
@@ -0,0 +1,3 @@
+Error parsing the text on line 1 at or near: Attributes
+The descriptor object returned from the dataset was null.
+Check that the URL is correct.
diff --git a/tests/dds-testsuite/S2000415.HDF.dds b/tests/dds-testsuite/S2000415.HDF.dds
new file mode 100644
index 0000000..6eeadc8
--- /dev/null
+++ b/tests/dds-testsuite/S2000415.HDF.dds
@@ -0,0 +1,35 @@
+Dataset {
+    Structure {
+        Int16 WVC_Lat[row = 458][WVC = 24];
+        UInt16 WVC_Lon[row = 458][WVC = 24];
+        Byte Num_Sigma0[row = 458][WVC = 24];
+        Byte Num_Beam_12[row = 458][WVC = 24];
+        Byte Num_Beam_34[row = 458][WVC = 24];
+        Byte Num_Beam_56[row = 458][WVC = 24];
+        Byte Num_Beam_78[row = 458][WVC = 24];
+        Byte WVC_Quality_Flag[row = 458][WVC = 24];
+        UInt16 Mean_Wind[row = 458][WVC = 24];
+        UInt16 Wind_Speed[row = 458][WVC = 24][position = 4];
+        UInt16 Wind_Dir[row = 458][WVC = 24][position = 4];
+        UInt16 Error_Speed[row = 458][WVC = 24][position = 4];
+        UInt16 Error_Dir[row = 458][WVC = 24][position = 4];
+        Int16 MLE_Likelihood[row = 458][WVC = 24][position = 4];
+        Byte Num_Ambigs[row = 458][WVC = 24];
+        Sequence {
+            Structure {
+                Int16 begin__0;
+            } begin;
+        } SwathIndex;
+        Sequence {
+            Structure {
+                String Mean_Time__0;
+            } Mean_Time;
+            Structure {
+                UInt32 Low_Wind_Speed_Flag__0;
+            } Low_Wind_Speed_Flag;
+            Structure {
+                UInt32 High_Wind_Speed_Flag__0;
+            } High_Wind_Speed_Flag;
+        } NSCAT%20L2;
+    } NSCAT%20Rev%2020;
+} S2000415.HDF;
diff --git a/tests/dds-testsuite/S2000415.HDF.dds.base b/tests/dds-testsuite/S2000415.HDF.dds.base
new file mode 100644
index 0000000..30ade82
--- /dev/null
+++ b/tests/dds-testsuite/S2000415.HDF.dds.base
@@ -0,0 +1,37 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int16 WVC_Lat[row = 458][WVC = 24];
+        UInt16 WVC_Lon[row = 458][WVC = 24];
+        Byte Num_Sigma0[row = 458][WVC = 24];
+        Byte Num_Beam_12[row = 458][WVC = 24];
+        Byte Num_Beam_34[row = 458][WVC = 24];
+        Byte Num_Beam_56[row = 458][WVC = 24];
+        Byte Num_Beam_78[row = 458][WVC = 24];
+        Byte WVC_Quality_Flag[row = 458][WVC = 24];
+        UInt16 Mean_Wind[row = 458][WVC = 24];
+        UInt16 Wind_Speed[row = 458][WVC = 24][position = 4];
+        UInt16 Wind_Dir[row = 458][WVC = 24][position = 4];
+        UInt16 Error_Speed[row = 458][WVC = 24][position = 4];
+        UInt16 Error_Dir[row = 458][WVC = 24][position = 4];
+        Int16 MLE_Likelihood[row = 458][WVC = 24][position = 4];
+        Byte Num_Ambigs[row = 458][WVC = 24];
+        Sequence {
+            Structure {
+                Int16 begin__0;
+            } begin;
+        } SwathIndex;
+        Sequence {
+            Structure {
+                String Mean_Time__0;
+            } Mean_Time;
+            Structure {
+                UInt32 Low_Wind_Speed_Flag__0;
+            } Low_Wind_Speed_Flag;
+            Structure {
+                UInt32 High_Wind_Speed_Flag__0;
+            } High_Wind_Speed_Flag;
+        } NSCAT%20L2;
+    } NSCAT%20Rev%2020;
+} S2000415.HDF;
diff --git a/tests/dds-testsuite/fnoc1.nc.das.dds b/tests/dds-testsuite/fnoc1.nc.das.dds
new file mode 100644
index 0000000..0407143
--- /dev/null
+++ b/tests/dds-testsuite/fnoc1.nc.das.dds
@@ -0,0 +1,32 @@
+Attributes {
+    u {
+        String units "meter per second";
+        String long_name "Vector wind eastward component";
+        String missing_value "-32767";
+        String scale_factor "0.005";
+        String DODS_Name "UWind";
+    }
+    v {
+        String units "meter per second";
+        String long_name "Vector wind northward component";
+        String missing_value "-32767";
+        String scale_factor "0.005";
+        String DODS_Name "VWind";
+    }
+    lat {
+        String units "degree North";
+    }
+    lon {
+        String units "degree East";
+    }
+    time {
+        String units "hours from base_time";
+    }
+    NC_GLOBAL {
+        String base_time "88- 10-00:00:00";
+        String title " FNOC UV wind components from 1988- 10 to 1988- 13.";
+    }
+    DODS_EXTRA {
+        String Unlimited_Dimension "time_a";
+    }
+}
diff --git a/tests/dds-testsuite/fnoc1.nc.das.dds.base b/tests/dds-testsuite/fnoc1.nc.das.dds.base
new file mode 100644
index 0000000..b769c81
--- /dev/null
+++ b/tests/dds-testsuite/fnoc1.nc.das.dds.base
@@ -0,0 +1,3 @@
+Error parsing the text on line 1 at or near: Attributes
+The descriptor object returned from the dataset was null.
+Check that the URL is correct.
diff --git a/tests/dds-testsuite/fnoc1.nc.dds b/tests/dds-testsuite/fnoc1.nc.dds
new file mode 100644
index 0000000..8c41e1b
--- /dev/null
+++ b/tests/dds-testsuite/fnoc1.nc.dds
@@ -0,0 +1,7 @@
+Dataset {
+    Int16 u[time_a = 16][lat = 17][lon = 21];
+    Int16 v[time_a = 16][lat = 17][lon = 21];
+    Float32 lat[lat = 17];
+    Float32 lon[lon = 21];
+    Float32 time[time = 16];
+} fnoc1.nc;
diff --git a/tests/dds-testsuite/fnoc1.nc.dds.base b/tests/dds-testsuite/fnoc1.nc.dds.base
new file mode 100644
index 0000000..62f5524
--- /dev/null
+++ b/tests/dds-testsuite/fnoc1.nc.dds.base
@@ -0,0 +1,9 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int16 u[time_a = 16][lat = 17][lon = 21];
+    Int16 v[time_a = 16][lat = 17][lon = 21];
+    Float32 lat[lat = 17];
+    Float32 lon[lon = 21];
+    Float32 time[time = 16];
+} fnoc1.nc;
diff --git a/tests/dds-testsuite/test.1.dds b/tests/dds-testsuite/test.1.dds
new file mode 100644
index 0000000..465ac61
--- /dev/null
+++ b/tests/dds-testsuite/test.1.dds
@@ -0,0 +1,7 @@
+dataset {
+    Byte b;
+    int32 i;
+    int32 j;
+} data1;
+
+
diff --git a/tests/dds-testsuite/test.1.dds.base b/tests/dds-testsuite/test.1.dds.base
new file mode 100644
index 0000000..d927fad
--- /dev/null
+++ b/tests/dds-testsuite/test.1.dds.base
@@ -0,0 +1,7 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Byte b;
+    Int32 i;
+    Int32 j;
+} data1;
diff --git a/tests/dds-testsuite/test.10.dds b/tests/dds-testsuite/test.10.dds
new file mode 100644
index 0000000..db4c7eb
--- /dev/null
+++ b/tests/dds-testsuite/test.10.dds
@@ -0,0 +1,45 @@
+# -*- C++ -*-
+
+dataset {
+    structure {
+	Int32 i;
+	int32 j;
+    } test;
+
+    sequence {
+	int32 i;
+	int32 j[10];
+    } test2;
+
+    grid {
+      array:
+	float64 f[10][10];
+      maps:
+	int32 g[10];
+	int32 h[10];
+    } test4;
+
+    Sequence {
+	String name;
+	Int32 age;
+    } person;
+
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+
+    Grid {
+      Array:
+	float64 g[10][10][10];
+      Maps:
+	float64 lat[10];
+	float64 lon[10];
+	float64 weirdness[10];
+    } strange;
+
+} data6;
diff --git a/tests/dds-testsuite/test.10.dds.base b/tests/dds-testsuite/test.10.dds.base
new file mode 100644
index 0000000..f7f4a74
--- /dev/null
+++ b/tests/dds-testsuite/test.10.dds.base
@@ -0,0 +1,39 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 i;
+        Int32 j;
+    } test;
+    Sequence {
+        Int32 i;
+        Int32 j[10];
+    } test2;
+    Grid {
+      Array:
+        Float64 f[10][10];
+      Maps:
+        Int32 g[10];
+        Int32 h[10];
+    } test4;
+    Sequence {
+        String name;
+        Int32 age;
+    } person;
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f[10];
+        } data;
+    } exp;
+    Grid {
+      Array:
+        Float64 g[10][10][10];
+      Maps:
+        Float64 lat[10];
+        Float64 lon[10];
+        Float64 weirdness[10];
+    } strange;
+} data6;
diff --git a/tests/dds-testsuite/test.11.dds b/tests/dds-testsuite/test.11.dds
new file mode 100644
index 0000000..9b863cf
--- /dev/null
+++ b/tests/dds-testsuite/test.11.dds
@@ -0,0 +1,37 @@
+# -*- C++ -*-
+
+# Test identifier length
+
+dataset {
+    structure {
+	int32 long_one;
+	int32 long_two;
+	int32 long_three;
+	int32 long_four;
+	int32 long_five;
+	int32 long_six;
+	float64 long_one_float;
+	float64 long_two_float;
+	float64 long_three_float;
+    } long_names_one;
+    
+    structure {
+	int32 long_one_float1;
+	int32 long_two_float1;
+	int32 long_three_float3;
+	int32 long_four;
+	int32 long_five;
+	int32 long_six;
+	float64 long_one_float;
+	float64 long_two_float;
+	float64 long_three_float;
+    } long_names_one_and_a_half;
+ 
+    structure {
+	int32 a_very_long_name_given_what_it_accomplishes;
+	int32 another_name_nearly_as_pointless;
+    } long_names_two;
+
+    
+} long_identifier_test_data_set;
+
diff --git a/tests/dds-testsuite/test.11.dds.base b/tests/dds-testsuite/test.11.dds.base
new file mode 100644
index 0000000..39231c5
--- /dev/null
+++ b/tests/dds-testsuite/test.11.dds.base
@@ -0,0 +1,30 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 long_one;
+        Int32 long_two;
+        Int32 long_three;
+        Int32 long_four;
+        Int32 long_five;
+        Int32 long_six;
+        Float64 long_one_float;
+        Float64 long_two_float;
+        Float64 long_three_float;
+    } long_names_one;
+    Structure {
+        Int32 long_one_float1;
+        Int32 long_two_float1;
+        Int32 long_three_float3;
+        Int32 long_four;
+        Int32 long_five;
+        Int32 long_six;
+        Float64 long_one_float;
+        Float64 long_two_float;
+        Float64 long_three_float;
+    } long_names_one_and_a_half;
+    Structure {
+        Int32 a_very_long_name_given_what_it_accomplishes;
+        Int32 another_name_nearly_as_pointless;
+    } long_names_two;
+} long_identifier_test_data_set;
diff --git a/tests/dds-testsuite/test.12.dds b/tests/dds-testsuite/test.12.dds
new file mode 100644
index 0000000..131dfb6
--- /dev/null
+++ b/tests/dds-testsuite/test.12.dds
@@ -0,0 +1,6 @@
+# test arrays with named dimensions.
+
+dataset {
+    int32 i;
+    float64 f[latitude=20][ longitude = 10 ];
+} data5;
diff --git a/tests/dds-testsuite/test.12.dds.base b/tests/dds-testsuite/test.12.dds.base
new file mode 100644
index 0000000..2d69135
--- /dev/null
+++ b/tests/dds-testsuite/test.12.dds.base
@@ -0,0 +1,6 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i;
+    Float64 f[latitude = 20][longitude = 10];
+} data5;
diff --git a/tests/dds-testsuite/test.13.dds b/tests/dds-testsuite/test.13.dds
new file mode 100644
index 0000000..bd400aa
--- /dev/null
+++ b/tests/dds-testsuite/test.13.dds
@@ -0,0 +1,6 @@
+# test problems with named dimensions.
+
+dataset {
+    int32 i;
+    float64 f[ longitude 10 ];
+} data5;
diff --git a/tests/dds-testsuite/test.13.dds.base b/tests/dds-testsuite/test.13.dds.base
new file mode 100644
index 0000000..65ad326
--- /dev/null
+++ b/tests/dds-testsuite/test.13.dds.base
@@ -0,0 +1,3 @@
+Error parsing the text on line 5 at or near: 10
+In the dataset descriptor object:
+Expected an array subscript.
diff --git a/tests/dds-testsuite/test.14.dds b/tests/dds-testsuite/test.14.dds
new file mode 100644
index 0000000..4ceac1d
--- /dev/null
+++ b/tests/dds-testsuite/test.14.dds
@@ -0,0 +1,4 @@
+# test null dataset
+
+dataset {
+} data5;
diff --git a/tests/dds-testsuite/test.14.dds.base b/tests/dds-testsuite/test.14.dds.base
new file mode 100644
index 0000000..49377fc
--- /dev/null
+++ b/tests/dds-testsuite/test.14.dds.base
@@ -0,0 +1,4 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+} data5;
diff --git a/tests/dds-testsuite/test.15.dds b/tests/dds-testsuite/test.15.dds
new file mode 100644
index 0000000..31fa2f5
--- /dev/null
+++ b/tests/dds-testsuite/test.15.dds
@@ -0,0 +1,8 @@
+#
+# Test new datatypes (int16, uint16, float32)
+
+Dataset {
+    int16 x;
+    uint16 y;
+    float32 f;
+} data5;
diff --git a/tests/dds-testsuite/test.15.dds.base b/tests/dds-testsuite/test.15.dds.base
new file mode 100644
index 0000000..dbb1f69
--- /dev/null
+++ b/tests/dds-testsuite/test.15.dds.base
@@ -0,0 +1,7 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int16 x;
+    UInt16 y;
+    Float32 f;
+} data5;
diff --git a/tests/dds-testsuite/test.16.dds b/tests/dds-testsuite/test.16.dds
new file mode 100644
index 0000000..61a360f
--- /dev/null
+++ b/tests/dds-testsuite/test.16.dds
@@ -0,0 +1,21 @@
+#
+# Test dots (.) in variable names.
+
+Dataset {
+    Int32 i.x[10];
+    Int32 j.x[20];
+    Byte b.x;
+    String name.x;
+    Structure {
+        Float64 f;
+	Float64 g;
+	Float64 h.x;
+    } x;
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Maps:
+        Float64 steps[100];
+	String colors[7];
+    } oddTemp.y;
+} data2;
diff --git a/tests/dds-testsuite/test.16.dds.base b/tests/dds-testsuite/test.16.dds.base
new file mode 100644
index 0000000..104fee5
--- /dev/null
+++ b/tests/dds-testsuite/test.16.dds.base
@@ -0,0 +1,20 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i.x[10];
+    Int32 j.x[20];
+    Byte b.x;
+    String name.x;
+    Structure {
+        Float64 f;
+        Float64 g;
+        Float64 h.x;
+    } x;
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Maps:
+        Float64 steps[100];
+        String colors[7];
+    } oddTemp.y;
+} data2;
diff --git a/tests/dds-testsuite/test.17.dds b/tests/dds-testsuite/test.17.dds
new file mode 100644
index 0000000..ef53e89
--- /dev/null
+++ b/tests/dds-testsuite/test.17.dds
@@ -0,0 +1,12 @@
+#
+# Test error messages; When `Maps' is misspelled.
+
+Dataset {
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Map:
+        Float64 steps[100];
+	String colors[7];
+    } oddTemp;
+} data2;
diff --git a/tests/dds-testsuite/test.17.dds.base b/tests/dds-testsuite/test.17.dds.base
new file mode 100644
index 0000000..2c6fd3c
--- /dev/null
+++ b/tests/dds-testsuite/test.17.dds.base
@@ -0,0 +1,5 @@
+Error parsing the text on line 8 at or near: Map
+In the dataset descriptor object: Expected a variable declaration
+(e.g., Int32 i;). Make sure that the variable name is not the name
+of a datatype and that the Array: and Maps: sections of a Grid are
+labeled properly.
diff --git a/tests/dds-testsuite/test.18.dds b/tests/dds-testsuite/test.18.dds
new file mode 100644
index 0000000..ca4e7a4
--- /dev/null
+++ b/tests/dds-testsuite/test.18.dds
@@ -0,0 +1,12 @@
+#
+# Test dataset filenames that are numbers.
+
+Dataset {
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Maps:
+        Float64 steps[100];
+	String colors[7];
+    } oddTemp;
+} 123;
diff --git a/tests/dds-testsuite/test.18.dds.base b/tests/dds-testsuite/test.18.dds.base
new file mode 100644
index 0000000..e3139e1
--- /dev/null
+++ b/tests/dds-testsuite/test.18.dds.base
@@ -0,0 +1,11 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Maps:
+        Float64 steps[100];
+        String colors[7];
+    } oddTemp;
+} 123;
diff --git a/tests/dds-testsuite/test.19.dds b/tests/dds-testsuite/test.19.dds
new file mode 100644
index 0000000..b87cca0
--- /dev/null
+++ b/tests/dds-testsuite/test.19.dds
@@ -0,0 +1,14 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+   Int32 b#c[10];
+   Float64 c#d;
+   Grid {
+     Array:
+       Byte Image#data[512];
+     Maps:
+       String colors[512];
+   } huh;
+} test.19;
diff --git a/tests/dds-testsuite/test.19.dds.base b/tests/dds-testsuite/test.19.dds.base
new file mode 100644
index 0000000..c63b020
--- /dev/null
+++ b/tests/dds-testsuite/test.19.dds.base
@@ -0,0 +1,13 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 a;
+    Int32 b%23c[10];
+    Float64 c%23d;
+    Grid {
+      Array:
+        Byte Image%23data[512];
+      Maps:
+        String colors[512];
+    } huh;
+} test.19;
diff --git a/tests/dds-testsuite/test.19b.das.dds b/tests/dds-testsuite/test.19b.das.dds
new file mode 100644
index 0000000..ac61f06
--- /dev/null
+++ b/tests/dds-testsuite/test.19b.das.dds
@@ -0,0 +1,33 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    NC_GLOBAL {
+        String long_name "Attribute merge test";
+        Int32 primes 2, 3, 5, 7, 11;
+    }
+
+    a {
+    }
+
+    b#c {
+        String long_name "b pound c";
+    }
+
+    c%20d {
+        String long_name "c d with a WWW escape sequence";
+	sub {
+	    String about "Attributes inside attributes";
+	    Float64 pi 3.1415;
+        }
+    }
+
+    huh {
+        String long_name "The Grid huh";
+	colors {
+	    String long_name "The color map vector";
+        }
+	Image#data {
+	}
+    }
+}
diff --git a/tests/dds-testsuite/test.19b.das.dds.base b/tests/dds-testsuite/test.19b.das.dds.base
new file mode 100644
index 0000000..371c190
--- /dev/null
+++ b/tests/dds-testsuite/test.19b.das.dds.base
@@ -0,0 +1,3 @@
+Error parsing the text on line 4 at or near: Attributes
+The descriptor object returned from the dataset was null.
+Check that the URL is correct.
diff --git a/tests/dds-testsuite/test.19b.dds b/tests/dds-testsuite/test.19b.dds
new file mode 100644
index 0000000..6d05cf7
--- /dev/null
+++ b/tests/dds-testsuite/test.19b.dds
@@ -0,0 +1,14 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+   Int32 b#c[10];
+   Float64 c%20d;
+   Grid {
+     Array:
+       Byte Image#data[512];
+     Maps:
+       String colors[512];
+   } huh;
+} test.19;
diff --git a/tests/dds-testsuite/test.19b.dds.base b/tests/dds-testsuite/test.19b.dds.base
new file mode 100644
index 0000000..5bb7ad7
--- /dev/null
+++ b/tests/dds-testsuite/test.19b.dds.base
@@ -0,0 +1,13 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 a;
+    Int32 b%23c[10];
+    Float64 c%20d;
+    Grid {
+      Array:
+        Byte Image%23data[512];
+      Maps:
+        String colors[512];
+    } huh;
+} test.19;
diff --git a/tests/dds-testsuite/test.2.dds b/tests/dds-testsuite/test.2.dds
new file mode 100644
index 0000000..f262371
--- /dev/null
+++ b/tests/dds-testsuite/test.2.dds
@@ -0,0 +1,4 @@
+Dataset {
+    Int32 i[10];
+    Int32 j[20];
+} data2;
diff --git a/tests/dds-testsuite/test.2.dds.base b/tests/dds-testsuite/test.2.dds.base
new file mode 100644
index 0000000..afe081c
--- /dev/null
+++ b/tests/dds-testsuite/test.2.dds.base
@@ -0,0 +1,6 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i[10];
+    Int32 j[20];
+} data2;
\ No newline at end of file
diff --git a/tests/dds-testsuite/test.20.dds b/tests/dds-testsuite/test.20.dds
new file mode 100644
index 0000000..c02f7bb
--- /dev/null
+++ b/tests/dds-testsuite/test.20.dds
@@ -0,0 +1,12 @@
+#
+# Test identifiers with '*' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+   Grid {
+     Array:
+       Byte Image#data[size*10=512];
+     Maps:
+       String colors[size*10=512];
+   } huh;
+} test.20;
diff --git a/tests/dds-testsuite/test.20.dds.base b/tests/dds-testsuite/test.20.dds.base
new file mode 100644
index 0000000..0122f3d
--- /dev/null
+++ b/tests/dds-testsuite/test.20.dds.base
@@ -0,0 +1,11 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 a;
+    Grid {
+      Array:
+        Byte Image%23data[size*10 = 512];
+      Maps:
+        String colors[size*10 = 512];
+    } huh;
+} test.20;
diff --git a/tests/dds-testsuite/test.3.dds b/tests/dds-testsuite/test.3.dds
new file mode 100644
index 0000000..11491a7
--- /dev/null
+++ b/tests/dds-testsuite/test.3.dds
@@ -0,0 +1,4 @@
+Dataset {
+    Int32 i[10];
+    Float64 f[20];
+} data3;
diff --git a/tests/dds-testsuite/test.3.dds.base b/tests/dds-testsuite/test.3.dds.base
new file mode 100644
index 0000000..095fe2f
--- /dev/null
+++ b/tests/dds-testsuite/test.3.dds.base
@@ -0,0 +1,6 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i[10];
+    Float64 f[20];
+} data3;
diff --git a/tests/dds-testsuite/test.4.dds b/tests/dds-testsuite/test.4.dds
new file mode 100644
index 0000000..0f69969
--- /dev/null
+++ b/tests/dds-testsuite/test.4.dds
@@ -0,0 +1,6 @@
+dataset {
+    int32 i;
+    byte b;
+    String s;
+    url u;
+} data4;
diff --git a/tests/dds-testsuite/test.4.dds.base b/tests/dds-testsuite/test.4.dds.base
new file mode 100644
index 0000000..1f687c6
--- /dev/null
+++ b/tests/dds-testsuite/test.4.dds.base
@@ -0,0 +1,8 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i;
+    Byte b;
+    String s;
+    Url u;
+} data4;
diff --git a/tests/dds-testsuite/test.6.dds b/tests/dds-testsuite/test.6.dds
new file mode 100644
index 0000000..1b9285d
--- /dev/null
+++ b/tests/dds-testsuite/test.6.dds
@@ -0,0 +1,6 @@
+dataset {
+    Structure {
+	Int32 j;
+	Int32 i;
+    } exp;
+} data6;
diff --git a/tests/dds-testsuite/test.6.dds.base b/tests/dds-testsuite/test.6.dds.base
new file mode 100644
index 0000000..3ceea75
--- /dev/null
+++ b/tests/dds-testsuite/test.6.dds.base
@@ -0,0 +1,8 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 i;
+    } exp;
+} data6;
diff --git a/tests/dds-testsuite/test.7.dds b/tests/dds-testsuite/test.7.dds
new file mode 100644
index 0000000..325934a
--- /dev/null
+++ b/tests/dds-testsuite/test.7.dds
@@ -0,0 +1,10 @@
+dataset {
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+} data6;
diff --git a/tests/dds-testsuite/test.7.dds.base b/tests/dds-testsuite/test.7.dds.base
new file mode 100644
index 0000000..41505c8
--- /dev/null
+++ b/tests/dds-testsuite/test.7.dds.base
@@ -0,0 +1,12 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f[10];
+        } data;
+    } exp;
+} data6;
diff --git a/tests/dds-testsuite/test.8.dds b/tests/dds-testsuite/test.8.dds
new file mode 100644
index 0000000..a19c747
--- /dev/null
+++ b/tests/dds-testsuite/test.8.dds
@@ -0,0 +1,14 @@
+dataset {
+    Sequence {
+	String name;
+	Int32 age;
+    } person;
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+} data6;
diff --git a/tests/dds-testsuite/test.8.dds.base b/tests/dds-testsuite/test.8.dds.base
new file mode 100644
index 0000000..74d407e
--- /dev/null
+++ b/tests/dds-testsuite/test.8.dds.base
@@ -0,0 +1,16 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Sequence {
+        String name;
+        Int32 age;
+    } person;
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f[10];
+        } data;
+    } exp;
+} data6;
diff --git a/tests/dds-testsuite/test.9.dds b/tests/dds-testsuite/test.9.dds
new file mode 100644
index 0000000..335d15f
--- /dev/null
+++ b/tests/dds-testsuite/test.9.dds
@@ -0,0 +1,22 @@
+dataset {
+    Sequence {
+	String name;
+	Int32 age;
+    } person;
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+    Grid {
+      Array:
+	float64 g[10][10][10];
+      Maps:
+	float64 lat[10];
+	float64 lon[10];
+	float64 weirdness[10];
+    } strange;
+} data6;
diff --git a/tests/dds-testsuite/test.9.dds.base b/tests/dds-testsuite/test.9.dds.base
new file mode 100644
index 0000000..dae2057
--- /dev/null
+++ b/tests/dds-testsuite/test.9.dds.base
@@ -0,0 +1,24 @@
+DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Sequence {
+        String name;
+        Int32 age;
+    } person;
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f[10];
+        } data;
+    } exp;
+    Grid {
+      Array:
+        Float64 g[10][10][10];
+      Maps:
+        Float64 lat[10];
+        Float64 lon[10];
+        Float64 weirdness[10];
+    } strange;
+} data6;
\ No newline at end of file
diff --git a/tests/expr-test.cc b/tests/expr-test.cc
new file mode 100644
index 0000000..cfc1ef8
--- /dev/null
+++ b/tests/expr-test.cc
@@ -0,0 +1,660 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1995-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Test the CE scanner and parser.
+//
+// jhrg 9/12/95
+
+#include "config.h"
+
+#define DODS_DEBUG
+
+static char rcsid[] not_used =
+    { "$Id: expr-test.cc 24082 2011-02-08 18:44:27Z jimg $" };
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef WIN32
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <errno.h>
+
+
+#include <iostream>
+#include <fstream>
+#include <string>
+
+#include "GetOpt.h"
+
+#include "BaseType.h"
+#include "DDS.h"
+#include "DataDDS.h"
+#include "ConstraintEvaluator.h"
+#include "XDRFileUnMarshaller.h"
+#include "XDRStreamUnMarshaller.h"
+#include "XDRStreamMarshaller.h"
+#if 0
+#include "DODSFilter.h"
+#endif
+#include "ResponseBuilder.h"
+#include "Response.h"
+#include "Connect.h"
+#include "Error.h"
+
+#include "TestSequence.h"
+#include "TestCommon.h"
+#include "TestTypeFactory.h"
+
+#include "parser.h"
+#include "expr.h"
+#include "ce_expr.tab.hh"
+#include "util.h"
+#if 0
+#include "fdiostream.h"
+#endif
+#include "debug.h"
+
+using namespace std;
+
+int test_variable_sleep_interval = 0;   // Used in Test* classes for testing
+                                      // timeouts.
+
+#define CRLF "\r\n"             // Change this here and in mime_util.cc
+#define DODS_DDS_PRX "dods_dds"
+#define YY_BUFFER_STATE (void *)
+
+void test_scanner(const string & str);
+void test_scanner(bool show_prompt);
+void test_parser(ConstraintEvaluator & eval, DDS & table,
+                 const string & dds_name, string constraint);
+bool read_table(DDS & table, const string & name, bool print);
+void evaluate_dds(DDS & table, bool print_constrained, bool xml_syntax);
+void constrained_trans(const string & dds_name, const bool constraint_expr,
+                       const string & ce, const bool series_values);
+void intern_data_test(const string & dds_name, const bool constraint_expr,
+                 const string & ce, const bool series_values);
+
+int ce_exprlex();               // exprlex() uses the global ce_exprlval
+int ce_exprparse(void *arg);
+void ce_exprrestart(FILE * in);
+
+// Glue routines declared in expr.lex
+void ce_expr_switch_to_buffer(void *new_buffer);
+void ce_expr_delete_buffer(void *buffer);
+void *ce_expr_string(const char *yy_str);
+
+extern int ce_exprdebug;
+
+static int keep_temps = 0;      // MT-safe; test code.
+
+const string version = "version 1.12";
+const string prompt = "expr-test: ";
+const string options = "sS:bdecvp:w:W:f:k:vx?";
+const string usage = "\
+\nexpr-test [-s [-S string] -d -c -v [-p dds-file]\
+\n[-e expr] [-w|-W dds-file] [-f data-file] [-k expr]]\
+\nTest the expression evaluation software.\
+\nOptions:\
+\n  -s: Feed the input stream directly into the expression scanner, does\
+\n      not parse.\
+\n  -S: <string> Scan the string as if it was standard input.\
+\n  -d: Turn on expression parser debugging.\
+\n  -c: Print the constrained DDS (the one that will be returned\
+\n      prepended to a data transmission. Must also supply -p and -e \
+\n  -v: Verbose output\
+\n  -V: Print the version of expr-test\
+\n  -p: DDS-file: Read the DDS from DDS-file and create a DDS object,\
+\n      then prompt for an expression and parse that expression, given\
+\n      the DDS object.\
+\n  -e: Evaluate the constraint expression. Must be used with -p.\
+\n  -w: Do the whole enchilada. You don't need to supply -p, -e, ...\
+\n      This prompts for the constraint expression and the optional\
+\n      data file name. NOTE: The CE parser Error objects do not print\
+\n      with this option.\
+\n  -W: Similar to -w but uses the new (11/2007) intern_data() methods\
+\n      in place of the serialize()/deserialize() combination.\
+\n  -b: Use periodic/cyclic/changing values. For testing Sequence CEs.\
+\n  -f: A file to use for data. Currently only used by -w for sequences.\
+\n  -k: A constraint expression to use with the data. Works with -p,\
+\n      -e, -t and -w\
+\n  -x: Print declarations using the XML syntax. Does not work with the\
+\n      data printouts.\
+\n  -?: Print usage information";
+
+int main(int argc, char *argv[])
+{
+    GetOpt getopt(argc, argv, options.c_str());
+
+    int option_char;
+    bool scanner_test = false, parser_test = false, evaluate_test = false;
+    bool print_constrained = false;
+    bool whole_enchalada = false, constraint_expr = false;
+    bool whole_intern_enchalada = false;
+    bool scan_string = false;
+    bool verbose = false;
+    bool series_values = false;
+    bool xml_syntax = false;
+    string dds_file_name;
+    string dataset = "";
+    string constraint = "";
+    TestTypeFactory ttf;
+    DDS table(&ttf);
+    ConstraintEvaluator eval;
+
+    // process options
+
+    while ((option_char = getopt()) != EOF)
+        switch (option_char) {
+        case 'b':
+            series_values = true;
+            break;
+        case 'd':
+            ce_exprdebug = true;
+            break;
+        case 's':
+            scanner_test = true;
+            break;
+        case 'S':
+            scanner_test = true;
+            scan_string = true;
+            constraint = getopt.optarg;
+            break;
+        case 'p':
+            parser_test = true;
+            dds_file_name = getopt.optarg;
+            break;
+        case 'e':
+            evaluate_test = true;
+            break;
+        case 'c':
+            print_constrained = true;
+            break;
+        case 'w':
+            whole_enchalada = true;
+            dds_file_name = getopt.optarg;
+            break;
+        case 'W':
+            whole_intern_enchalada = true;
+            dds_file_name = getopt.optarg;
+            break;
+        case 'k':
+            constraint_expr = true;
+            constraint = getopt.optarg;
+            break;
+        case 'f':
+            dataset = getopt.optarg;
+            break;
+        case 'v':
+            verbose = true;
+            break;
+        case 'V':
+            cerr << argv[0] << ": " <<  version << endl;
+            exit(0);
+        case 'x':
+        	xml_syntax = true;
+        	break;
+        case '?':
+        default:
+            cerr << usage << endl;
+            exit(1);
+            break;
+        }
+
+    try {
+        if (!scanner_test && !parser_test && !evaluate_test
+            && !whole_enchalada && !whole_intern_enchalada) {
+            cerr << usage << endl;
+            exit(1);
+        }
+        // run selected tests
+
+        if (scanner_test) {
+            if (scan_string)
+                test_scanner(constraint);
+            else
+                test_scanner(true);
+
+            exit(0);
+        }
+
+        if (parser_test) {
+            test_parser(eval, table, dds_file_name, constraint);
+        }
+
+        if (evaluate_test) {
+            evaluate_dds(table, print_constrained, xml_syntax);
+        }
+
+        if (whole_enchalada) {
+            constrained_trans(dds_file_name, constraint_expr, constraint,
+                              series_values);
+        }
+        if (whole_intern_enchalada) {
+            intern_data_test(dds_file_name, constraint_expr, constraint,
+                             series_values);
+        }
+    }
+    catch(Error & e) {
+        cerr <<e.get_error_message() << endl;
+        exit(1);
+    }
+    catch(exception & e) {
+        cerr << "Caught exception: " << e.what() << endl;
+        exit(1);
+    }
+
+    exit(0);
+}
+
+// Instead of reading the tokens from stdin, read them from a string.
+
+
+void test_scanner(const string & str)
+{
+    ce_exprrestart(0);
+    void *buffer = ce_expr_string(str.c_str());
+    ce_expr_switch_to_buffer(buffer);
+
+    test_scanner(false);
+
+    ce_expr_delete_buffer(buffer);
+}
+
+void test_scanner(bool show_prompt)
+{
+    if (show_prompt)
+        cout << prompt;
+
+    int tok;
+    while ((tok = ce_exprlex())) {
+        switch (tok) {
+        case SCAN_WORD:
+            cout << "WORD: " << ce_exprlval.id << endl;
+            break;
+        case SCAN_STR:
+            cout << "STR: " << *ce_exprlval.val.v.s << endl;
+            break;
+        case SCAN_EQUAL:
+            cout << "EQUAL: " << ce_exprlval.op << endl;
+            break;
+        case SCAN_NOT_EQUAL:
+            cout << "NOT_EQUAL: " << ce_exprlval.op << endl;
+            break;
+        case SCAN_GREATER:
+            cout << "GREATER: " << ce_exprlval.op << endl;
+            break;
+        case SCAN_GREATER_EQL:
+            cout << "GREATER_EQL: " << ce_exprlval.op << endl;
+            break;
+        case SCAN_LESS:
+            cout << "LESS: " << ce_exprlval.op << endl;
+            break;
+        case SCAN_LESS_EQL:
+            cout << "LESS_EQL: " << ce_exprlval.op << endl;
+            break;
+        case SCAN_REGEXP:
+            cout << "REGEXP: " << ce_exprlval.op << endl;
+            break;
+        case '*':
+            cout << "Dereference" << endl;
+            break;
+        case '.':
+            cout << "Field Selector" << endl;
+            break;
+        case ',':
+            cout << "List Element Separator" << endl;
+            break;
+        case '[':
+            cout << "Left Bracket" << endl;
+            break;
+        case ']':
+            cout << "Right Bracket" << endl;
+            break;
+        case '(':
+            cout << "Left Paren" << endl;
+            break;
+        case ')':
+            cout << "Right Paren" << endl;
+            break;
+        case '{':
+            cout << "Left Brace" << endl;
+            break;
+        case '}':
+            cout << "Right Brace" << endl;
+            break;
+        case ':':
+            cout << "Colon" << endl;
+            break;
+        case '&':
+            cout << "Ampersand" << endl;
+            break;
+        default:
+            cout << "Error: Unrecognized input" << endl;
+        }
+
+        cout << prompt << flush;  // print prompt after output
+    }
+}
+
+// NB: The DDS is read in via a file because reading from stdin must be
+// terminated by EOF. However, the EOF used to terminate the DDS also closes
+// stdin and thus the expr scanner exits immediately.
+
+void
+test_parser(ConstraintEvaluator & eval, DDS & dds, const string & dds_name,
+            string constraint)
+{
+    try {
+        read_table(dds, dds_name, true);
+
+        if (constraint.empty()) {
+            cout << "Constraint:";
+            char c[256];
+            cin.getline(c, 256);
+            if (!cin)
+                throw InternalErr(__FILE__, __LINE__,
+                                  "Could not read the constraint expression\n");
+            constraint = c;
+        }
+
+        eval.parse_constraint(constraint, dds);
+        fprintf(stdout, "Input parsed\n");      // Parser throws on failure.
+    }
+    catch(Error & e) {
+        cerr << e.get_error_message() << endl;
+    }
+}
+
+// Read a DDS from stdin and build the corresponding DDS. IF PRINT is true,
+// print the text representation of that DDS on the stdout. The DDS TABLE is
+// modified as a side effect.
+//
+// Returns: true iff that DDS pasted the semantic_check() mfunc, otherwise
+// false.
+
+bool read_table(DDS & table, const string & name, bool print)
+{
+    table.parse(name);
+
+    if (print)
+        table.print(cout);
+
+    if (table.check_semantics(true))
+        return true;
+    else {
+        fprintf(stdout, "Input did not pass semantic checks\n");
+        return false;
+    }
+}
+
+void evaluate_dds(DDS & table, bool print_constrained, bool xml_syntax)
+{
+    if (print_constrained) {
+    	if (xml_syntax)
+    		table.print_xml(cout, print_constrained, "");
+    	else
+    		table.print_constrained(cout);
+    }
+    else {
+        for (DDS::Vars_iter p = table.var_begin(); p != table.var_end(); p++) {
+        	if (xml_syntax)
+        		(*p)->print_decl(cout, "", print_constrained);
+        	else
+        		(*p)->print_decl(cout, "", true, true);
+        }
+    }
+}
+
+// Gobble up the MIME header. At one time the MIME Headers were output from
+// the server filter programs (not the core software) so we could call
+// DDS::send() from this test code and not have to parse the MIME header. But
+// in order to get errors to work more reliably the header generation was
+// moved `closer to the send'. That is, we put off determining whether to
+// send a DDS or an Error object until later. That trade off is that the
+// header generation is not buried in the core software. This code simply
+// reads until the end of the header is found. 3/25/98 jhrg
+
+void parse_mime(FILE * data_source)
+{
+    char line[256];
+
+    fgets(line, 256, data_source);
+
+    while (strncmp(line, CRLF, 2) != 0)
+        fgets(line, 256, data_source);
+}
+
+void set_series_values(DDS & dds, bool state)
+{
+    for (DDS::Vars_iter q = dds.var_begin(); q != dds.var_end(); q++) {
+        dynamic_cast < TestCommon & >(**q).set_series_values(state);
+    }
+}
+
+// Test the transmission of constrained datasets. Use read_table() to read
+// the DDS from a file. Once done, prompt for the variable name and
+// constraint expression. In a real client-server system the server would
+// read the DDS for the entire dataset and send it to the client. The client
+// would then respond to the server by asking for a variable given a
+// constraint.
+//
+// Once the constraint has been entered, it is evaluated in the context of
+// the DDS using DDS:eval_constraint() (this would happen on the server-side
+// in a real system). Once the evaluation is complete,
+// DDS::print_constrained() is used to create a DDS describing only those
+// parts of the dataset that are to be sent to the client process and written
+// to the output stream. After that, the marker `Data:' is written to the
+// output stream, followed by the binary data.
+
+void
+constrained_trans(const string & dds_name, const bool constraint_expr,
+                  const string & constraint, const bool series_values)
+{
+    // If the CE was not passed in, read it from the command line.
+    string ce;
+    if (!constraint_expr) {
+        cout << "Constraint:";
+        char c[256];
+        cin.getline(c, 256);
+        if (!cin) {
+            throw InternalErr(__FILE__, __LINE__,
+                              "Could not read the constraint expression\n");
+        }
+        ce = c;
+    }
+    else {
+        ce = constraint;
+    }
+
+    TestTypeFactory ttf;
+    DDS server(&ttf);
+    ConstraintEvaluator eval;
+
+    cout << "The complete DDS:" << endl;
+    read_table(server, dds_name, true);
+
+    // by default this is false (to get the old-style values that are
+    // constant); set series_values to true for testing Sequence constraints.
+    // 01/14/05 jhrg And Array constraints, although it's of limited
+    // versatility 02/05/07 jhrg
+    set_series_values(server, series_values);
+
+    ResponseBuilder df;
+    df.set_ce(ce);
+    df.set_dataset_name(dds_name);
+    // df.set_URL("test://test");
+    // df.set_response("DataDDS");
+
+    ofstream out("expr-test-data.bin", ios::out|ios::trunc|ios::binary);
+#if 0
+    df.send_data(server, eval, out, "", false);
+#endif
+    df.send_data(out, server, eval, true);
+    //cout << "Server protocol version: " << server.get_dap_major() << "." << server.get_dap_minor() << endl;
+    out.close();
+
+    // Now do what Connect::request_data() does:
+    FILE *fp = fopen("expr-test-data.bin", "r");
+
+    Response r(fp, 400);
+#if 0
+    r.set_type(dods_data);
+    r.set_protocol("3.2");
+#endif
+    Connect c("http://dummy_argument");
+
+    BaseTypeFactory factory;
+    DataDDS dds(&factory, "Test_data", "DAP/3.2");      // Must use DataDDS on receiving end
+
+#if 0
+    c.read_data_no_mime(dds, &r);
+#endif
+    c.read_data(dds, &r);
+
+    //cout << "Protocol version: " << dds.get_protocol() << endl;
+
+    cout << "The data:" << endl;
+    for (DDS::Vars_iter q = dds.var_begin(); q != dds.var_end(); q++) {
+        (*q)->print_val(cout);
+    }
+}
+
+/** This function does what constrained_trans() does but does not use the
+    serialize()/deserialize() methods. Instead it uses the new (11/2007)
+    intern_data() methods.
+
+    @param dds_name
+    @param constraint_expr True is one was given, else false
+    @param constraint The constraint expression if \c constraint_expr is
+    true.
+    @param series_values True if TestTypes should generate 'series values'
+    like the DTS. False selects the old-style values. */
+void
+intern_data_test(const string & dds_name, const bool constraint_expr,
+                 const string & constraint, const bool series_values)
+{
+    // If the CE was not passed in, read it from the command line.
+    string ce;
+    if (!constraint_expr) {
+        cout << "Constraint: ";
+        char c[256];
+        cin.getline(c, 256);
+        if (!cin) {
+            throw InternalErr(__FILE__, __LINE__,
+                              "Could not read the constraint expression\n");
+        }
+        ce = c;
+    }
+    else {
+        ce = constraint;
+    }
+
+    TestTypeFactory ttf;
+    DDS server(&ttf);
+    ConstraintEvaluator eval;
+
+    cout << "The complete DDS:\n";
+    read_table(server, dds_name, true);
+
+    // by default this is false (to get the old-style values that are
+    // constant); set series_values to true for testing Sequence constraints.
+    // 01/14/05 jhrg And Array constraints, although it's of limited
+    // versatility 02/05/07 jhrg
+    set_series_values(server, series_values);
+
+    eval.parse_constraint(ce, server);  // Throws Error if the ce doesn't parse.
+
+    server.tag_nested_sequences();      // Tag Sequences as Parent or Leaf node.
+
+#if 0
+    if (eval.functional_expression()) {
+        BaseType *var = eval.eval_function(server, dds_name);
+        if (!var)
+            throw Error(unknown_error, "Error calling the CE function.");
+
+        var->intern_data(eval, server);
+
+        var->set_send_p(true);
+        server.add_var(var);
+    }
+#endif
+
+    if (eval.function_clauses()) {
+        DDS *fdds = eval.eval_function_clauses(server);
+
+        for (DDS::Vars_iter i = fdds->var_begin(); i != fdds->var_end(); i++)
+            if ((*i)->send_p())
+                (*i)->intern_data(eval, *fdds);
+
+        cout << "The data:\n";
+
+        // This code calls 'output_values()' because print_val() does not test
+        // the value of send_p(). We need to wrap a method around the calls to
+        // print_val() to ensure that only values for variables with send_p() set
+        // are called. In the serialize/deserialize case, the 'client' DDS only
+        // has variables sent by the 'server' but in the intern_data() case, the
+        // whole DDS is still present and only variables selected in the CE have
+        // values.
+        for (DDS::Vars_iter q = fdds->var_begin(); q != fdds->var_end(); q++) {
+            if ((*q)->send_p()) {
+                (*q)->print_decl(cout, "", false, false, true);
+                cout << " = ";
+                dynamic_cast<TestCommon&>(**q).output_values(cout);
+                cout << ";\n";
+            }
+        }
+
+        delete fdds;
+    }
+    else {
+        for (DDS::Vars_iter i = server.var_begin(); i != server.var_end(); i++)
+            if ((*i)->send_p())
+                (*i)->intern_data(eval, server);
+        cout << "The data:\n";
+
+        // This code calls 'output_values()' because print_val() does not test
+        // the value of send_p(). We need to wrap a method around the calls to
+        // print_val() to ensure that only values for variables with send_p() set
+        // are called. In the serialize/deserialize case, the 'client' DDS only
+        // has variables sent by the 'server' but in the intern_data() case, the
+        // whole DDS is still present and only variables selected in the CE have
+        // values.
+        for (DDS::Vars_iter q = server.var_begin(); q != server.var_end(); q++) {
+            if ((*q)->send_p()) {
+                (*q)->print_decl(cout, "", false, false, true);
+                cout << " = ";
+                dynamic_cast<TestCommon&>(**q).output_values(cout);
+                cout << ";\n";
+            }
+        }
+    }
+}
diff --git a/tests/expr-testsuite/data.61a.base b/tests/expr-testsuite/data.61a.base
new file mode 100644
index 0000000..bde0b8e
--- /dev/null
+++ b/tests/expr-testsuite/data.61a.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Int32 i[4][5];
+} test61;
+The data:
+Int32 i[4][5] = {{32, 1024, 32768, 1048576, 33554432},{1073741824, 32, 1024, 32768, 1048576},{33554432, 1073741824, 32, 1024, 32768},{1048576, 33554432, 1073741824, 32, 1024}};
diff --git a/tests/expr-testsuite/data.61b.base b/tests/expr-testsuite/data.61b.base
new file mode 100644
index 0000000..8790f25
--- /dev/null
+++ b/tests/expr-testsuite/data.61b.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Int32 i[4][5];
+} test61;
+The data:
+Int32 i[3][3] = {{32, 1024, 32768},{1073741824, 32, 1024},{33554432, 1073741824, 32}};
diff --git a/tests/expr-testsuite/data.61c.base b/tests/expr-testsuite/data.61c.base
new file mode 100644
index 0000000..6eec1d0
--- /dev/null
+++ b/tests/expr-testsuite/data.61c.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Int32 i[4][5];
+} test61;
+The data:
+Int32 i[2][3] = {{1073741824, 32, 1024},{33554432, 1073741824, 32}};
diff --git a/tests/expr-testsuite/data.61d.base b/tests/expr-testsuite/data.61d.base
new file mode 100644
index 0000000..d08c939
--- /dev/null
+++ b/tests/expr-testsuite/data.61d.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Int32 i[4][5];
+} test61;
+The data:
+Int32 i[2][2] = {{32, 1024},{1073741824, 32}};
diff --git a/tests/expr-testsuite/data.z0.base b/tests/expr-testsuite/data.z0.base
new file mode 100644
index 0000000..74490b7
--- /dev/null
+++ b/tests/expr-testsuite/data.z0.base
@@ -0,0 +1 @@
+Wrong number of arguments to geogrid() (expected at least 5 args). See geogrid() for more information.
diff --git a/tests/expr-testsuite/data.z1.base b/tests/expr-testsuite/data.z1.base
new file mode 100644
index 0000000..37d0567
--- /dev/null
+++ b/tests/expr-testsuite/data.z1.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[lat = 13][lon = 11];
+      Maps:
+        Float32 lat[13];
+        Float32 lon[11];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[lat = 13][lon = 11];
+  Maps:
+    Float32 lat[13];
+    Float32 lon[11];
+} SST = {  Array: {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21},{22, 23, 24, 25, 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, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109},{110, 111, 112, 113, 11 [...]
diff --git a/tests/expr-testsuite/data.z2.base b/tests/expr-testsuite/data.z2.base
new file mode 100644
index 0000000..a964053
--- /dev/null
+++ b/tests/expr-testsuite/data.z2.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[lat = 13][lon = 11];
+      Maps:
+        Float32 lat[13];
+        Float32 lon[11];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[lat = 3][lon = 3];
+  Maps:
+    Float32 lat[3];
+    Float32 lon[3];
+} SST = {  Array: {{156, 157, 158},{167, 168, 169},{178, 179, 180}}  Maps: {64, 51, 38}, {96, 128, 160} };
diff --git a/tests/expr-testsuite/data.z3.base b/tests/expr-testsuite/data.z3.base
new file mode 100644
index 0000000..09dee5c
--- /dev/null
+++ b/tests/expr-testsuite/data.z3.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[lat_reversed = 13][lon = 11];
+      Maps:
+        Float32 lat_reversed[13];
+        Float32 lon[11];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[lat_reversed = 4][lon = 3];
+  Maps:
+    Float32 lat_reversed[4];
+    Float32 lon[3];
+} SST = {  Array: {{10, 11, 12},{255, 0, 1},{244, 245, 246},{233, 234, 235}}  Maps: {67, 54, 41, 28}, {96, 128, 160} };
diff --git a/tests/expr-testsuite/data.z4.base b/tests/expr-testsuite/data.z4.base
new file mode 100644
index 0000000..7ced514
--- /dev/null
+++ b/tests/expr-testsuite/data.z4.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[time = 3][lon = 11][lat = 13];
+      Maps:
+        Int32 time[3];
+        Float32 lon[11];
+        Float32 lat[13];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[time = 3][lon = 3][lat = 3];
+  Maps:
+    Int32 time[3];
+    Float32 lon[3];
+    Float32 lat[3];
+} SST = {  Array: {{{173, 174, 175},{176, 177, 178},{179, 180, 181}},{{182, 183, 184},{185, 186, 187},{188, 189, 190}},{{191, 192, 193},{194, 195, 196},{197, 198, 199}}}  Maps: {32, 1024, 32768}, {96, 128, 160}, {64, 51, 38} };
diff --git a/tests/expr-testsuite/data.z5.base b/tests/expr-testsuite/data.z5.base
new file mode 100644
index 0000000..e37ac9a
--- /dev/null
+++ b/tests/expr-testsuite/data.z5.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[time = 3][lon = 11][lat = 13];
+      Maps:
+        Int32 time[3];
+        Float32 lon[11];
+        Float32 lat[13];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[time = 1][lon = 3][lat = 3];
+  Maps:
+    Int32 time[1];
+    Float32 lon[3];
+    Float32 lat[3];
+} SST = {  Array: {{{173, 174, 175},{176, 177, 178},{179, 180, 181}}}  Maps: {1048576}, {96, 128, 160}, {64, 51, 38} };
diff --git a/tests/expr-testsuite/data.z6.base b/tests/expr-testsuite/data.z6.base
new file mode 100644
index 0000000..1cc8706
--- /dev/null
+++ b/tests/expr-testsuite/data.z6.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[lon = 11][lat = 13];
+      Maps:
+        Float32 lon[11];
+        Float32 lat[13];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[lon = 3][lat = 3];
+  Maps:
+    Float32 lon[3];
+    Float32 lat[3];
+} SST = {  Array: {{170, 171, 172},{183, 184, 185},{196, 197, 198}}  Maps: {96, 128, 160}, {64, 51, 38} };
diff --git a/tests/expr-testsuite/data.z7.base b/tests/expr-testsuite/data.z7.base
new file mode 100644
index 0000000..e37ac9a
--- /dev/null
+++ b/tests/expr-testsuite/data.z7.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[time = 3][lon = 11][lat = 13];
+      Maps:
+        Int32 time[3];
+        Float32 lon[11];
+        Float32 lat[13];
+    } SST;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[time = 1][lon = 3][lat = 3];
+  Maps:
+    Int32 time[1];
+    Float32 lon[3];
+    Float32 lat[3];
+} SST = {  Array: {{{173, 174, 175},{176, 177, 178},{179, 180, 181}}}  Maps: {1048576}, {96, 128, 160}, {64, 51, 38} };
diff --git a/tests/expr-testsuite/data.z8.base b/tests/expr-testsuite/data.z8.base
new file mode 100644
index 0000000..f434fa1
--- /dev/null
+++ b/tests/expr-testsuite/data.z8.base
@@ -0,0 +1,32 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Byte SST[lat = 13][lon = 11];
+      Maps:
+        Float32 lat[13];
+        Float32 lon[11];
+    } SST;
+    Grid {
+      Array:
+        Byte AIRT[lat = 13][lon = 11];
+      Maps:
+        Float32 lat[13];
+        Float32 lon[11];
+    } AIRT;
+} SST_grid;
+The data:
+Grid {
+  Array:
+    Byte SST[lat = 3][lon = 3];
+  Maps:
+    Float32 lat[3];
+    Float32 lon[3];
+} SST = {  Array: {{156, 157, 158},{167, 168, 169},{178, 179, 180}}  Maps: {64, 51, 38}, {96, 128, 160} };
+Grid {
+  Array:
+    Byte AIRT[lat = 3][lon = 3];
+  Maps:
+    Float32 lat[3];
+    Float32 lon[3];
+} AIRT = {  Array: {{156, 157, 158},{167, 168, 169},{178, 179, 180}}  Maps: {64, 51, 38}, {96, 128, 160} };
diff --git a/tests/expr-testsuite/data.zz0.base b/tests/expr-testsuite/data.zz0.base
new file mode 100644
index 0000000..f492da3
--- /dev/null
+++ b/tests/expr-testsuite/data.zz0.base
@@ -0,0 +1 @@
+Wrong number of arguments to geoarray(). See geoarray() for more information.
diff --git a/tests/expr-testsuite/data.zz1.base b/tests/expr-testsuite/data.zz1.base
new file mode 100644
index 0000000..8dfe2b4
--- /dev/null
+++ b/tests/expr-testsuite/data.zz1.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Byte SST[lat = 13][lon = 11];
+} SST_Array;
+The data:
+Byte SST[lat = 13][lon = 11] = {{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10},{11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21},{22, 23, 24, 25, 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, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109},{110, 111, [...]
diff --git a/tests/expr-testsuite/data.zz2.base b/tests/expr-testsuite/data.zz2.base
new file mode 100644
index 0000000..b108db4
--- /dev/null
+++ b/tests/expr-testsuite/data.zz2.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Byte SST[lat = 13][lon = 11];
+} SST_Array;
+The data:
+Byte SST[lat = 7][lon = 5] = {{36, 37, 38, 39, 40},{47, 48, 49, 50, 51},{58, 59, 60, 61, 62},{69, 70, 71, 72, 73},{80, 81, 82, 83, 84},{91, 92, 93, 94, 95},{102, 103, 104, 105, 106}};
diff --git a/tests/expr-testsuite/test.1 b/tests/expr-testsuite/test.1
new file mode 100644
index 0000000..9bf5f7a
--- /dev/null
+++ b/tests/expr-testsuite/test.1
@@ -0,0 +1,11 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: simple projections and shorthand names.
+
+dataset {
+    Int32 i;
+    Int32 j;
+} test1;
+
diff --git a/tests/expr-testsuite/test.1.base b/tests/expr-testsuite/test.1.base
new file mode 100644
index 0000000..895e938
--- /dev/null
+++ b/tests/expr-testsuite/test.1.base
@@ -0,0 +1,7 @@
+The complete DDS:
+Dataset {
+    Int32 i;
+    Int32 j;
+} test1;
+The data:
+Int32 i = 123456789;
diff --git a/tests/expr-testsuite/test.1a.base b/tests/expr-testsuite/test.1a.base
new file mode 100644
index 0000000..9f57cae
--- /dev/null
+++ b/tests/expr-testsuite/test.1a.base
@@ -0,0 +1,8 @@
+The complete DDS:
+Dataset {
+    Int32 i;
+    Int32 j;
+} test1;
+The data:
+Int32 i = 123456789;
+Int32 j = 123456789;
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.1b.base b/tests/expr-testsuite/test.1b.base
new file mode 100644
index 0000000..9f57cae
--- /dev/null
+++ b/tests/expr-testsuite/test.1b.base
@@ -0,0 +1,8 @@
+The complete DDS:
+Dataset {
+    Int32 i;
+    Int32 j;
+} test1;
+The data:
+Int32 i = 123456789;
+Int32 j = 123456789;
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.1c.base b/tests/expr-testsuite/test.1c.base
new file mode 100644
index 0000000..b6831cd
--- /dev/null
+++ b/tests/expr-testsuite/test.1c.base
@@ -0,0 +1,6 @@
+The complete DDS:
+Dataset {
+    Int32 i;
+    Int32 j;
+} test1;
+The data:
diff --git a/tests/expr-testsuite/test.1d.base b/tests/expr-testsuite/test.1d.base
new file mode 100644
index 0000000..f605bfe
--- /dev/null
+++ b/tests/expr-testsuite/test.1d.base
@@ -0,0 +1,7 @@
+The complete DDS:
+Dataset {
+    Int32 i;
+    Int32 j;
+} test1;
+The data:
+Int32 i = 123456789;
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.2 b/tests/expr-testsuite/test.2
new file mode 100644
index 0000000..93de2d3
--- /dev/null
+++ b/tests/expr-testsuite/test.2
@@ -0,0 +1,21 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: simple projections and shorthand names.
+
+dataset {
+    Structure {
+	Int32 j;
+	Int32 k;
+    } s1;
+    Structure {
+	Int32 l;
+	Int32 m;
+    } s2[10];
+    Structure {
+	Int32 n;
+	Int32 o;
+    } s3;
+} test2;
+
diff --git a/tests/expr-testsuite/test.2.base b/tests/expr-testsuite/test.2.base
new file mode 100644
index 0000000..7cb7a1b
--- /dev/null
+++ b/tests/expr-testsuite/test.2.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l;
+        Int32 m;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 j;
+    Int32 k;
+} s1 = { 123456789, 123456789 };
diff --git a/tests/expr-testsuite/test.2a b/tests/expr-testsuite/test.2a
new file mode 100644
index 0000000..57a29ee
--- /dev/null
+++ b/tests/expr-testsuite/test.2a
@@ -0,0 +1,22 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: simple projections and shorthand names.
+
+dataset {
+    Structure {
+	Int32 j;
+	Int32 k;
+    } s1;
+    Structure {
+	Int32 l[100];
+	Int32 m[100];
+	Int32 p;
+    } s2[10];
+    Structure {
+	Int32 n;
+	Int32 o;
+    } s3;
+} test2;
+
diff --git a/tests/expr-testsuite/test.2a.base b/tests/expr-testsuite/test.2a.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/expr-testsuite/test.2b.base b/tests/expr-testsuite/test.2b.base
new file mode 100644
index 0000000..f4c8569
--- /dev/null
+++ b/tests/expr-testsuite/test.2b.base
@@ -0,0 +1,24 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l;
+        Int32 m;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 l;
+    Int32 m;
+} s2[10] = {{ 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }, { 123456789, 123456789 }};
+Structure {
+    Int32 n;
+    Int32 o;
+} s3 = { 123456789, 123456789 };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.2c.base b/tests/expr-testsuite/test.2c.base
new file mode 100644
index 0000000..db85a4c
--- /dev/null
+++ b/tests/expr-testsuite/test.2c.base
@@ -0,0 +1,23 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l;
+        Int32 m;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 l;
+    Int32 m;
+} s2[2] = {{ 123456789, 123456789 }, { 123456789, 123456789 }};
+Structure {
+    Int32 o;
+} s3 = { 123456789 };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.2d.base b/tests/expr-testsuite/test.2d.base
new file mode 100644
index 0000000..596b318
--- /dev/null
+++ b/tests/expr-testsuite/test.2d.base
@@ -0,0 +1,19 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l;
+        Int32 m;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 m;
+} s2[2] = {{ 123456789 }, { 123456789 }};
diff --git a/tests/expr-testsuite/test.2e.base b/tests/expr-testsuite/test.2e.base
new file mode 100644
index 0000000..fc352ac
--- /dev/null
+++ b/tests/expr-testsuite/test.2e.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l;
+        Int32 m;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 l;
+    Int32 m;
+} s2[2] = {{ 123456789, 123456789 }, { 123456789, 123456789 }};
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.2f.base b/tests/expr-testsuite/test.2f.base
new file mode 100644
index 0000000..f599450
--- /dev/null
+++ b/tests/expr-testsuite/test.2f.base
@@ -0,0 +1,21 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l[100];
+        Int32 m[100];
+        Int32 p;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 l[6];
+    Int32 m[5];
+} s2[3] = {{ {123456789, 123456789, 123456789, 123456789, 123456789, 123456789}, {123456789, 123456789, 123456789, 123456789, 123456789} }, { {123456789, 123456789, 123456789, 123456789, 123456789, 123456789}, {123456789, 123456789, 123456789, 123456789, 123456789} }, { {123456789, 123456789, 123456789, 123456789, 123456789, 123456789}, {123456789, 123456789, 123456789, 123456789, 123456789} }};
diff --git a/tests/expr-testsuite/test.2g.base b/tests/expr-testsuite/test.2g.base
new file mode 100644
index 0000000..adaa3d1
--- /dev/null
+++ b/tests/expr-testsuite/test.2g.base
@@ -0,0 +1,22 @@
+The complete DDS:
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 k;
+    } s1;
+    Structure {
+        Int32 l;
+        Int32 m;
+    } s2[10];
+    Structure {
+        Int32 n;
+        Int32 o;
+    } s3;
+} test2;
+The data:
+Structure {
+    Int32 j;
+} s1 = { 123456789 };
+Structure {
+    Int32 o;
+} s3 = { 123456789 };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.3 b/tests/expr-testsuite/test.3
new file mode 100644
index 0000000..5a68167
--- /dev/null
+++ b/tests/expr-testsuite/test.3
@@ -0,0 +1,11 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: simple projections and shorthand names.
+
+dataset {
+    Int32 i[20];
+    Int32 j;
+} test1;
+
diff --git a/tests/expr-testsuite/test.3.base b/tests/expr-testsuite/test.3.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/expr-testsuite/test.4 b/tests/expr-testsuite/test.4
new file mode 100644
index 0000000..2cf533f
--- /dev/null
+++ b/tests/expr-testsuite/test.4
@@ -0,0 +1,12 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: simple projections and shorthand names.
+
+dataset {
+    Int32 i[20];
+    String s;
+    Int32 j;
+} test1;
+
diff --git a/tests/expr-testsuite/test.4.base b/tests/expr-testsuite/test.4.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/expr-testsuite/test.4a.base b/tests/expr-testsuite/test.4a.base
new file mode 100644
index 0000000..06f15f5
--- /dev/null
+++ b/tests/expr-testsuite/test.4a.base
@@ -0,0 +1,7 @@
+The complete DDS:
+Dataset {
+    Int32 i[20];
+    String s;
+    Int32 j;
+} test1;
+The data:
diff --git a/tests/expr-testsuite/test.5 b/tests/expr-testsuite/test.5
new file mode 100644
index 0000000..7b062c8
--- /dev/null
+++ b/tests/expr-testsuite/test.5
@@ -0,0 +1,20 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: Grid projections
+
+dataset {
+    Int32 i[20];
+    Int32 j;
+    String s;
+    Grid {
+      Array:
+	    Float64 val[length = 5][width = 6][height = 7];
+      Maps:
+		Float64 length[5];
+		Float64 width[6];
+		Float64 height[7];
+    } g;
+} test1;
+
diff --git a/tests/expr-testsuite/test.5.base b/tests/expr-testsuite/test.5.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/expr-testsuite/test.5a.base b/tests/expr-testsuite/test.5a.base
new file mode 100644
index 0000000..d0b0ca0
--- /dev/null
+++ b/tests/expr-testsuite/test.5a.base
@@ -0,0 +1,23 @@
+The complete DDS:
+Dataset {
+    Int32 i[20];
+    Int32 j;
+    String s;
+    Grid {
+      Array:
+        Float64 val[length = 5][width = 6][height = 7];
+      Maps:
+        Float64 length[5];
+        Float64 width[6];
+        Float64 height[7];
+    } g;
+} test1;
+The data:
+Grid {
+  Array:
+    Float64 val[length = 3][width = 3][height = 3];
+  Maps:
+    Float64 length[3];
+    Float64 width[3];
+    Float64 height[3];
+} g = {  Array: {{{99.999, 99.999, 99.999},{99.999, 99.999, 99.999},{99.999, 99.999, 99.999}},{{99.999, 99.999, 99.999},{99.999, 99.999, 99.999},{99.999, 99.999, 99.999}},{{99.999, 99.999, 99.999},{99.999, 99.999, 99.999},{99.999, 99.999, 99.999}}}  Maps: {99.999, 99.999, 99.999}, {99.999, 99.999, 99.999}, {99.999, 99.999, 99.999} };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.5b.base b/tests/expr-testsuite/test.5b.base
new file mode 100644
index 0000000..83ae5fc
--- /dev/null
+++ b/tests/expr-testsuite/test.5b.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Int32 i[20];
+    Int32 j;
+    String s;
+    Grid {
+      Array:
+        Float64 val[length = 5][width = 6][height = 7];
+      Maps:
+        Float64 length[5];
+        Float64 width[6];
+        Float64 height[7];
+    } g;
+} test1;
+The data:
+Structure {
+    Float64 val[length = 2][width = 2][height = 2];
+} g = { {{{99.999, 99.999},{99.999, 99.999}},{{99.999, 99.999},{99.999, 99.999}}} };
diff --git a/tests/expr-testsuite/test.5c.base b/tests/expr-testsuite/test.5c.base
new file mode 100644
index 0000000..2818b30
--- /dev/null
+++ b/tests/expr-testsuite/test.5c.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Int32 i[20];
+    Int32 j;
+    String s;
+    Grid {
+      Array:
+        Float64 val[length = 5][width = 6][height = 7];
+      Maps:
+        Float64 length[5];
+        Float64 width[6];
+        Float64 height[7];
+    } g;
+} test1;
+The data:
+Structure {
+    Float64 length[5];
+} g = { {99.999, 99.999, 99.999, 99.999, 99.999} };
diff --git a/tests/expr-testsuite/test.5d.base b/tests/expr-testsuite/test.5d.base
new file mode 100644
index 0000000..876b203
--- /dev/null
+++ b/tests/expr-testsuite/test.5d.base
@@ -0,0 +1,19 @@
+The complete DDS:
+Dataset {
+    Int32 i[20];
+    Int32 j;
+    String s;
+    Grid {
+      Array:
+        Float64 val[length = 5][width = 6][height = 7];
+      Maps:
+        Float64 length[5];
+        Float64 width[6];
+        Float64 height[7];
+    } g;
+} test1;
+The data:
+Structure {
+    Float64 length[5];
+    Float64 width[6];
+} g = { {99.999, 99.999, 99.999, 99.999, 99.999}, {99.999, 99.999, 99.999, 99.999, 99.999, 99.999} };
diff --git a/tests/expr-testsuite/test.5e.base b/tests/expr-testsuite/test.5e.base
new file mode 100644
index 0000000..6a00790
--- /dev/null
+++ b/tests/expr-testsuite/test.5e.base
@@ -0,0 +1 @@
+Error: The number of dimensions in the constraint for g must match the number in the grid.
diff --git a/tests/expr-testsuite/test.6 b/tests/expr-testsuite/test.6
new file mode 100644
index 0000000..6e05712
--- /dev/null
+++ b/tests/expr-testsuite/test.6
@@ -0,0 +1,11 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: multiple dimension arrays.
+
+dataset {
+    Int32 i[20][10];
+    String s;
+} test1;
+
diff --git a/tests/expr-testsuite/test.6.base b/tests/expr-testsuite/test.6.base
new file mode 100644
index 0000000..e69de29
diff --git a/tests/expr-testsuite/test.61 b/tests/expr-testsuite/test.61
new file mode 100644
index 0000000..c0a3bfd
--- /dev/null
+++ b/tests/expr-testsuite/test.61
@@ -0,0 +1,10 @@
+#
+# -*- C++ -*-
+#
+
+# Test projections: multiple dimension arrays.
+
+dataset {
+    Int32 i[4][5];
+} test61;
+
diff --git a/tests/expr-testsuite/test.6a.base b/tests/expr-testsuite/test.6a.base
new file mode 100644
index 0000000..b97413a
--- /dev/null
+++ b/tests/expr-testsuite/test.6a.base
@@ -0,0 +1,7 @@
+The complete DDS:
+Dataset {
+    Int32 i[20][10];
+    String s;
+} test1;
+The data:
+Int32 i[2][3] = {{123456789, 123456789, 123456789},{123456789, 123456789, 123456789}};
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.6b.base b/tests/expr-testsuite/test.6b.base
new file mode 100644
index 0000000..29092a2
--- /dev/null
+++ b/tests/expr-testsuite/test.6b.base
@@ -0,0 +1,2 @@
+Error: The number of dimensions in the constraint for i must match the number in the array.
+ 
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.7 b/tests/expr-testsuite/test.7
new file mode 100644
index 0000000..31fa2f5
--- /dev/null
+++ b/tests/expr-testsuite/test.7
@@ -0,0 +1,8 @@
+#
+# Test new datatypes (int16, uint16, float32)
+
+Dataset {
+    int16 x;
+    uint16 y;
+    float32 f;
+} data5;
diff --git a/tests/expr-testsuite/test.7.base b/tests/expr-testsuite/test.7.base
new file mode 100644
index 0000000..0bb1bab
--- /dev/null
+++ b/tests/expr-testsuite/test.7.base
@@ -0,0 +1,10 @@
+The complete DDS:
+Dataset {
+    Int16 x;
+    UInt16 y;
+    Float32 f;
+} data5;
+The data:
+Int16 x = 32000;
+UInt16 y = 64000;
+Float32 f = 99.999;
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.8 b/tests/expr-testsuite/test.8
new file mode 100644
index 0000000..e98fcd0
--- /dev/null
+++ b/tests/expr-testsuite/test.8
@@ -0,0 +1,11 @@
+#
+# Test variables with odd characters (#) and escapes in their names.
+
+Dataset {
+    int16 x#y;
+    uint16 y;
+    Int32 data#i[20][10];
+    Float64 data%20name[10];
+} data8;
+
+
diff --git a/tests/expr-testsuite/test.8.base b/tests/expr-testsuite/test.8.base
new file mode 100644
index 0000000..5ed7f2d
--- /dev/null
+++ b/tests/expr-testsuite/test.8.base
@@ -0,0 +1,9 @@
+The complete DDS:
+Dataset {
+    Int16 x%23y;
+    UInt16 y;
+    Int32 data%23i[20][10];
+    Float64 data%20name[10];
+} data8;
+The data:
+Int32 data%23i[5][3] = {{123456789, 123456789, 123456789},{123456789, 123456789, 123456789},{123456789, 123456789, 123456789},{123456789, 123456789, 123456789},{123456789, 123456789, 123456789}};
diff --git a/tests/expr-testsuite/test.8a.base b/tests/expr-testsuite/test.8a.base
new file mode 100644
index 0000000..26cc009
--- /dev/null
+++ b/tests/expr-testsuite/test.8a.base
@@ -0,0 +1,10 @@
+The complete DDS:
+Dataset {
+    Int16 x%23y;
+    UInt16 y;
+    Int32 data%23i[20][10];
+    Float64 data%20name[10];
+} data8;
+The data:
+Int16 x%23y = 32000;
+UInt16 y = 64000;
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.8b.base b/tests/expr-testsuite/test.8b.base
new file mode 100644
index 0000000..e04d2b7
--- /dev/null
+++ b/tests/expr-testsuite/test.8b.base
@@ -0,0 +1,10 @@
+The complete DDS:
+Dataset {
+    Int16 x%23y;
+    UInt16 y;
+    Int32 data%23i[20][10];
+    Float64 data%20name[10];
+} data8;
+The data:
+UInt16 y = 64000;
+Float64 data%20name[10] = {99.999, 99.999, 99.999, 99.999, 99.999, 99.999, 99.999, 99.999, 99.999, 99.999};
diff --git a/tests/expr-testsuite/test.9 b/tests/expr-testsuite/test.9
new file mode 100644
index 0000000..5af2431
--- /dev/null
+++ b/tests/expr-testsuite/test.9
@@ -0,0 +1,15 @@
+
+# -*- C++ -*-
+#
+# Test problems reported with an HDF-EOS dataset. Should be able to access
+# Data%2dSet%2d2. 
+
+Dataset {
+   Grid {
+     ARRAY:
+       Float64 Data%2dSet%2d2[fakeDim0 = 72][fakeDim1 = 144];
+     MAPS:
+       Float64 fakeDim0[72];
+       Float64 fakeDim1[144];
+   } Data%2dSet%2d2;
+} ftp#data#lim93#msup#L93rain.90daygrd_msu.hdf;
diff --git a/tests/expr-testsuite/test.9.base b/tests/expr-testsuite/test.9.base
new file mode 100644
index 0000000..3905f75
--- /dev/null
+++ b/tests/expr-testsuite/test.9.base
@@ -0,0 +1,15 @@
+The complete DDS:
+Dataset {
+    Grid {
+      Array:
+        Float64 Data-Set-2[fakeDim0 = 72][fakeDim1 = 144];
+      Maps:
+        Float64 fakeDim0[72];
+        Float64 fakeDim1[144];
+    } Data-Set-2;
+} ftp%23data%23lim93%23msup%23L93rain.90daygrd_msu.hdf;
+The data:
+Structure {
+    Float64 fakeDim0[4];
+    Float64 fakeDim1[4];
+} Data-Set-2 = { {99.999, 99.999, 99.999, 99.999}, {99.999, 99.999, 99.999, 99.999} };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.a b/tests/expr-testsuite/test.a
new file mode 100644
index 0000000..30d67d4
--- /dev/null
+++ b/tests/expr-testsuite/test.a
@@ -0,0 +1,8 @@
+# Test Sequences
+
+dataset {
+	Sequence {
+		Int32 i;
+		Int32 j;
+	} s;
+} testa;
diff --git a/tests/expr-testsuite/test.a.base b/tests/expr-testsuite/test.a.base
new file mode 100644
index 0000000..60d1db6
--- /dev/null
+++ b/tests/expr-testsuite/test.a.base
@@ -0,0 +1,12 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+    } s;
+} testa;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+} s = { { 32, 32 }, { 1024, 1024 }, { 32768, 32768 }, { 1048576, 1048576 } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.aa.base b/tests/expr-testsuite/test.aa.base
new file mode 100644
index 0000000..5058c4d
--- /dev/null
+++ b/tests/expr-testsuite/test.aa.base
@@ -0,0 +1,12 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+    } s;
+} testa;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+} s = { { 32, 32 }, { 1024, 1024 } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.ab.base b/tests/expr-testsuite/test.ab.base
new file mode 100644
index 0000000..f8b7782
--- /dev/null
+++ b/tests/expr-testsuite/test.ab.base
@@ -0,0 +1,11 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+    } s;
+} testa;
+The data:
+Sequence {
+    Int32 j;
+} s = { { 32768 }, { 1048576 } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.ac.base b/tests/expr-testsuite/test.ac.base
new file mode 100644
index 0000000..43bebad
--- /dev/null
+++ b/tests/expr-testsuite/test.ac.base
@@ -0,0 +1,12 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+    } s;
+} testa;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+} s = { {  } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.b b/tests/expr-testsuite/test.b
new file mode 100644
index 0000000..a89c2bc
--- /dev/null
+++ b/tests/expr-testsuite/test.b
@@ -0,0 +1,12 @@
+# Test Sequences
+
+dataset {
+	Sequence {
+		Int32 i;
+		Int32 j;
+		Sequence {
+			Float32 f;
+			Float32 g;
+		} child;
+	} parent;
+} testb;
diff --git a/tests/expr-testsuite/test.b.base b/tests/expr-testsuite/test.b.base
new file mode 100644
index 0000000..71c80c9
--- /dev/null
+++ b/tests/expr-testsuite/test.b.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+        } child;
+    } parent;
+} testb;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+    Sequence {
+        Float32 f;
+        Float32 g;
+    } child;
+} parent = { { 32, 32, { { -54.4, -54.4 }, { -1.77, -1.77 }, { 98.93, 98.93 }, { 92.68, 92.68 } } }, { 1024, 1024, { { 99.48, 99.48 }, { 81.67, 81.67 }, { 10.59, 10.59 }, { 91.29, 91.29 } } }, { 32768, 32768, { { 45.2, 45.2 }, { -99.97, -99.97 }, { -86, -86 }, { -56.61, -56.61 } } }, { 1048576, 1048576, { { -90.17, -90.17 }, { 99.38, 99.38 }, { 81.67, 81.67 }, { 10.59, 10.59 } } } };
diff --git a/tests/expr-testsuite/test.ba.base b/tests/expr-testsuite/test.ba.base
new file mode 100644
index 0000000..d06bec0
--- /dev/null
+++ b/tests/expr-testsuite/test.ba.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+        } child;
+    } parent;
+} testb;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+    } child;
+} parent = { { 32, { { -54.4 }, { -1.77 }, { 98.93 }, { 92.68 } } }, { 1024, { { 99.48 }, { 81.67 }, { 10.59 }, { 91.29 } } }, { 32768, { { 45.2 }, { -99.97 }, { -86 }, { -56.61 } } }, { 1048576, { { -90.17 }, { 99.38 }, { 81.67 }, { 10.59 } } } };
diff --git a/tests/expr-testsuite/test.bb.base b/tests/expr-testsuite/test.bb.base
new file mode 100644
index 0000000..8c67dbe
--- /dev/null
+++ b/tests/expr-testsuite/test.bb.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+        } child;
+    } parent;
+} testb;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+    } child;
+} parent = { { 32, { { -54.4 }, { -1.77 }, { 98.93 }, { 92.68 } } }, { 1024, { { 99.48 }, { 81.67 }, { 10.59 }, { 91.29 } } } };
diff --git a/tests/expr-testsuite/test.bc.base b/tests/expr-testsuite/test.bc.base
new file mode 100644
index 0000000..202e62c
--- /dev/null
+++ b/tests/expr-testsuite/test.bc.base
@@ -0,0 +1,18 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+        } child;
+    } parent;
+} testb;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+    } child;
+} parent = { { 32, { { -54.4 }, { -1.77 } } }, { 32768, { { -99.97 }, { -86 }, { -56.61 } } }, { 1048576, { { -90.17 } } } };
diff --git a/tests/expr-testsuite/test.bd.base b/tests/expr-testsuite/test.bd.base
new file mode 100644
index 0000000..256a073
--- /dev/null
+++ b/tests/expr-testsuite/test.bd.base
@@ -0,0 +1,16 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+        } child;
+    } parent;
+} testb;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+} parent = { { 32, 32 }, { 1024, 1024 } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.be.base b/tests/expr-testsuite/test.be.base
new file mode 100644
index 0000000..c3684bc
--- /dev/null
+++ b/tests/expr-testsuite/test.be.base
@@ -0,0 +1,20 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+        } child;
+    } parent;
+} testb;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+    Sequence {
+        Float32 f;
+        Float32 g;
+    } child;
+} parent = { {  } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.c0 b/tests/expr-testsuite/test.c0
new file mode 100644
index 0000000..4a6a5f8
--- /dev/null
+++ b/tests/expr-testsuite/test.c0
@@ -0,0 +1,12 @@
+# -*- C++ -*-
+#
+
+Dataset {
+   Grid {
+     ARRAY:
+       Byte SST[lat = 13][lon = 11];
+     MAPS:
+       Float32 lat[13];
+       Float32 lon[11];
+   } SST;
+} SST_grid;
diff --git a/tests/expr-testsuite/test.c1 b/tests/expr-testsuite/test.c1
new file mode 100644
index 0000000..f5f1527
--- /dev/null
+++ b/tests/expr-testsuite/test.c1
@@ -0,0 +1,12 @@
+# -*- C++ -*-
+#
+
+Dataset {
+   Grid {
+     ARRAY:
+       Byte SST[lat_reversed = 13][lon = 11];
+     MAPS:
+       Float32 lat_reversed[13];
+       Float32 lon[11];
+   } SST;
+} SST_grid;
diff --git a/tests/expr-testsuite/test.c2 b/tests/expr-testsuite/test.c2
new file mode 100644
index 0000000..b7ae46b
--- /dev/null
+++ b/tests/expr-testsuite/test.c2
@@ -0,0 +1,13 @@
+# -*- C++ -*-
+#
+
+Dataset {
+   Grid {
+     ARRAY:
+       Byte SST[time=3][lon = 11][lat = 13];
+     MAPS:
+       Int32 time[3];
+       Float32 lon[11];
+       Float32 lat[13];
+   } SST;
+} SST_grid;
diff --git a/tests/expr-testsuite/test.c3 b/tests/expr-testsuite/test.c3
new file mode 100644
index 0000000..f6b0950
--- /dev/null
+++ b/tests/expr-testsuite/test.c3
@@ -0,0 +1,9 @@
+Dataset {
+   Grid {
+     ARRAY:
+       Byte SST[lon = 11][lat = 13];
+     MAPS:
+       Float32 lon[11];
+       Float32 lat[13];
+   } SST;
+} SST_grid;
diff --git a/tests/expr-testsuite/test.c4 b/tests/expr-testsuite/test.c4
new file mode 100644
index 0000000..b7ae46b
--- /dev/null
+++ b/tests/expr-testsuite/test.c4
@@ -0,0 +1,13 @@
+# -*- C++ -*-
+#
+
+Dataset {
+   Grid {
+     ARRAY:
+       Byte SST[time=3][lon = 11][lat = 13];
+     MAPS:
+       Int32 time[3];
+       Float32 lon[11];
+       Float32 lat[13];
+   } SST;
+} SST_grid;
diff --git a/tests/expr-testsuite/test.c5 b/tests/expr-testsuite/test.c5
new file mode 100644
index 0000000..d7b7c92
--- /dev/null
+++ b/tests/expr-testsuite/test.c5
@@ -0,0 +1,17 @@
+Dataset {
+   Grid {
+     ARRAY:
+       Byte SST[lat = 13][lon = 11];
+     MAPS:
+       Float32 lat[13];
+       Float32 lon[11];
+   } SST;
+
+   Grid {
+     ARRAY:
+       Byte AIRT[lat = 13][lon = 11];
+     MAPS:
+       Float32 lat[13];
+       Float32 lon[11];
+   } AIRT;
+} SST_grid;
diff --git a/tests/expr-testsuite/test.cc0 b/tests/expr-testsuite/test.cc0
new file mode 100644
index 0000000..42bb166
--- /dev/null
+++ b/tests/expr-testsuite/test.cc0
@@ -0,0 +1,6 @@
+# -*- C++ -*-
+#
+
+Dataset {
+   Byte SST[lat = 13][lon = 11];
+} SST_Array;
diff --git a/tests/expr-testsuite/test.cc1 b/tests/expr-testsuite/test.cc1
new file mode 100644
index 0000000..6be9c88
--- /dev/null
+++ b/tests/expr-testsuite/test.cc1
@@ -0,0 +1,6 @@
+# -*- C++ -*-
+#
+
+Dataset {
+   Byte SST[lon = 11][lat = 13];
+} SST_Array;
diff --git a/tests/expr-testsuite/test.d b/tests/expr-testsuite/test.d
new file mode 100644
index 0000000..e9587f6
--- /dev/null
+++ b/tests/expr-testsuite/test.d
@@ -0,0 +1,16 @@
+# Test Sequences
+
+dataset {
+   Sequence {
+      Int32 i;
+      Int32 j;
+         Sequence {
+             Float32 f;
+             Float32 g;
+             Sequence {
+                Byte a;
+                Byte b;
+             } baby;
+         } child;
+   } parent;
+} testc;
diff --git a/tests/expr-testsuite/test.d.base b/tests/expr-testsuite/test.d.base
new file mode 100644
index 0000000..eddc364
--- /dev/null
+++ b/tests/expr-testsuite/test.d.base
@@ -0,0 +1,28 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Int32 j;
+    Sequence {
+        Float32 f;
+        Float32 g;
+        Sequence {
+            Byte a;
+            Byte b;
+        } baby;
+    } child;
+} parent = { { 32, 32, { { -54.4, -54.4, { { 0, 0 }, { 1, 1 }, { 2, 2 }, { 3, 3 } } }, { -1.77, -1.77, { { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 } } }, { 98.93, 98.93, { { 8, 8 }, { 9, 9 }, { 10, 10 }, { 11, 11 } } }, { 92.68, 92.68, { { 12, 12 }, { 13, 13 }, { 14, 14 }, { 15, 15 } } } } }, { 1024, 1024, { { 99.48, 99.48, { { 16, 16 }, { 17, 17 }, { 18, 18 }, { 19, 19 } } }, { 81.67, 81.67, { { 20, 20 }, { 21, 21 }, { 22, 22 }, { 23, 23 } } }, { 10.59, 10.59, { { 24, 24 }, { 25, 25 }, { 26, [...]
diff --git a/tests/expr-testsuite/test.da.base b/tests/expr-testsuite/test.da.base
new file mode 100644
index 0000000..26a3a45
--- /dev/null
+++ b/tests/expr-testsuite/test.da.base
@@ -0,0 +1,25 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+        Sequence {
+            Byte a;
+        } baby;
+    } child;
+} parent = { { 32, { { -54.4, { { 0 }, { 1 }, { 2 }, { 3 } } }, { -1.77, { { 4 }, { 5 }, { 6 }, { 7 } } }, { 98.93, { { 8 }, { 9 }, { 10 }, { 11 } } }, { 92.68, { { 12 }, { 13 }, { 14 }, { 15 } } } } }, { 1024, { { 99.48, { { 16 }, { 17 }, { 18 }, { 19 } } }, { 81.67, { { 20 }, { 21 }, { 22 }, { 23 } } }, { 10.59, { { 24 }, { 25 }, { 26 }, { 27 } } }, { 91.29, { { 28 }, { 29 }, { 30 }, { 31 } } } } }, { 32768, { { 45.2, { { 32 }, { 33 }, { 34 }, { 35 } } }, { -99.97, { { 36 }, { 37 }, {  [...]
diff --git a/tests/expr-testsuite/test.db.base b/tests/expr-testsuite/test.db.base
new file mode 100644
index 0000000..5fcc850
--- /dev/null
+++ b/tests/expr-testsuite/test.db.base
@@ -0,0 +1,25 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+        Sequence {
+            Byte a;
+        } baby;
+    } child;
+} parent = { { 32, { { -54.4, { { 0 }, { 1 }, { 2 }, { 3 } } }, { -1.77, { { 4 }, { 5 }, { 6 }, { 7 } } }, { 98.93, { { 8 }, { 9 }, { 10 }, { 11 } } }, { 92.68, { { 12 }, { 13 }, { 14 }, { 15 } } } } }, { 1024, { { 99.48, { { 16 }, { 17 }, { 18 }, { 19 } } }, { 81.67, { { 20 }, { 21 }, { 22 }, { 23 } } }, { 10.59, { { 24 }, { 25 }, { 26 }, { 27 } } }, { 91.29, { { 28 }, { 29 }, { 30 }, { 31 } } } } } };
diff --git a/tests/expr-testsuite/test.dc.base b/tests/expr-testsuite/test.dc.base
new file mode 100644
index 0000000..5ddb331
--- /dev/null
+++ b/tests/expr-testsuite/test.dc.base
@@ -0,0 +1,25 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+        Sequence {
+            Byte a;
+        } baby;
+    } child;
+} parent = { { 32, { { -54.4, { { 0 }, { 1 }, { 2 }, { 3 } } }, { -1.77, { { 4 }, { 5 }, { 6 }, { 7 } } } } }, { 32768, { { -99.97, { { 36 }, { 37 }, { 38 }, { 39 } } }, { -86, { { 40 }, { 41 }, { 42 }, { 43 } } }, { -56.61, { { 44 }, { 45 }, { 46 }, { 47 } } } } }, { 1048576, { { -90.17, { { 48 }, { 49 }, { 50 }, { 51 } } } } } };
diff --git a/tests/expr-testsuite/test.dd.base b/tests/expr-testsuite/test.dd.base
new file mode 100644
index 0000000..6a71e8e
--- /dev/null
+++ b/tests/expr-testsuite/test.dd.base
@@ -0,0 +1,25 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+        Sequence {
+            Byte a;
+        } baby;
+    } child;
+} parent = { { 32, { { -54.4, { { 0 }, { 1 }, { 2 }, { 3 } } }, { -1.77, { { 4 }, { 5 }, { 6 }, { 7 } } }, { 98.93, { { 8 }, { 9 } } } } } };
diff --git a/tests/expr-testsuite/test.de.base b/tests/expr-testsuite/test.de.base
new file mode 100644
index 0000000..4a1dca0
--- /dev/null
+++ b/tests/expr-testsuite/test.de.base
@@ -0,0 +1,22 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+    } child;
+} parent = { { 32, { { -54.4 }, { -1.77 }, { 98.93 }, { 92.68 } } }, { 1024, { { 99.48 }, { 81.67 }, { 10.59 }, { 91.29 } } } };
diff --git a/tests/expr-testsuite/test.df.base b/tests/expr-testsuite/test.df.base
new file mode 100644
index 0000000..1c0a32a
--- /dev/null
+++ b/tests/expr-testsuite/test.df.base
@@ -0,0 +1,19 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+} parent = { { 32 }, { 1024 } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.dg.base b/tests/expr-testsuite/test.dg.base
new file mode 100644
index 0000000..1f83951
--- /dev/null
+++ b/tests/expr-testsuite/test.dg.base
@@ -0,0 +1,25 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        Int32 j;
+        Sequence {
+            Float32 f;
+            Float32 g;
+            Sequence {
+                Byte a;
+                Byte b;
+            } baby;
+        } child;
+    } parent;
+} testc;
+The data:
+Sequence {
+    Int32 i;
+    Sequence {
+        Float32 f;
+        Sequence {
+            Byte a;
+        } baby;
+    } child;
+} parent = { {  } };
\ No newline at end of file
diff --git a/tests/expr-testsuite/test.e b/tests/expr-testsuite/test.e
new file mode 100644
index 0000000..5c139d6
--- /dev/null
+++ b/tests/expr-testsuite/test.e
@@ -0,0 +1,8 @@
+# Test Sequences
+
+dataset {
+   Sequence {
+      Int32 i;
+      String s;
+   } names;
+} test.e;
diff --git a/tests/expr-testsuite/test.ea.base b/tests/expr-testsuite/test.ea.base
new file mode 100644
index 0000000..5410eb6
--- /dev/null
+++ b/tests/expr-testsuite/test.ea.base
@@ -0,0 +1,11 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        String s;
+    } names;
+} test.e;
+The data:
+Sequence {
+    String s;
+} names = { { "Silly test string: 3" } };
diff --git a/tests/expr-testsuite/test.eb.base b/tests/expr-testsuite/test.eb.base
new file mode 100644
index 0000000..4b0bc59
--- /dev/null
+++ b/tests/expr-testsuite/test.eb.base
@@ -0,0 +1,11 @@
+The complete DDS:
+Dataset {
+    Sequence {
+        Int32 i;
+        String s;
+    } names;
+} test.e;
+The data:
+Sequence {
+    String s;
+} names = { {  } };
diff --git a/tests/package.m4 b/tests/package.m4
new file mode 100644
index 0000000..577b5c2
--- /dev/null
+++ b/tests/package.m4
@@ -0,0 +1,6 @@
+# Signature of the current package.
+m4_define([AT_PACKAGE_NAME],      [libdap])
+m4_define([AT_PACKAGE_TARNAME],   [libdap])
+m4_define([AT_PACKAGE_VERSION],   [3.11.1])
+m4_define([AT_PACKAGE_STRING],    [libdap 3.11.1])
+m4_define([AT_PACKAGE_BUGREPORT], [opendap-tech at opendap.org])
diff --git a/unit-tests/ArrayGeoConstraintTest.cc b/unit-tests/ArrayGeoConstraintTest.cc
new file mode 100644
index 0000000..4f90b1e
--- /dev/null
+++ b/unit-tests/ArrayGeoConstraintTest.cc
@@ -0,0 +1,231 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Tests for the AISResources class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG
+
+#include "BaseType.h"
+
+#include "Byte.h"
+#include "Int32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Array.h"
+#include "Grid.h"
+#include "DDS.h"
+#include "DAS.h"
+
+#include "../tests/TestArray.h"
+#include "ArrayGeoConstraint.h"
+#include "ce_functions.h"
+
+#include "../tests/TestTypeFactory.h"
+
+#include "debug.h"
+
+using namespace CppUnit;
+using namespace libdap;
+using namespace std;
+
+int test_variable_sleep_interval = 0;
+
+namespace libdap
+{
+
+class ArrayGeoConstraintTest:public TestFixture
+{
+private:
+    TestTypeFactory btf;
+    ConstraintEvaluator ce;
+
+    TestArray *a1, *a2, *a3;
+
+public:
+    ArrayGeoConstraintTest()
+    {}
+    ~ArrayGeoConstraintTest()
+    {}
+
+    void setUp()
+    {
+        a1 = new TestArray("test1", new Int32("test1"));
+        a1->append_dim(21); // latitude
+        a1->append_dim(10); // longitude
+
+        a2 = new TestArray("test2", new Int32("test2"));
+        a2->append_dim(21); // latitude
+        a2->append_dim(10); // longitude
+
+        a3 = new TestArray("test3", new Byte("test3"));
+        a3->append_dim(10); // latitude
+        a3->append_dim(10); // longitude
+        dods_byte tmp_data[10][10] =
+                { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                  { 10,11,12,13,14,15,16,17,18,19},
+                  { 20,21,22,23,24,25,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} };
+        a3->val2buf((void*)tmp_data);
+        a3->set_read_p(true);
+
+
+    }
+
+    void tearDown()
+    {
+        delete a1; a1 = 0;
+        delete a2; a2 = 0;
+        delete a3; a3 = 0;
+    }
+
+    CPPUNIT_TEST_SUITE( ArrayGeoConstraintTest );
+
+    CPPUNIT_TEST(constructor_test);
+    CPPUNIT_TEST(build_lat_lon_maps_test);
+    CPPUNIT_TEST(set_bounding_box_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void constructor_test() {
+        TestArray *ta = new TestArray("test", new Int32("test"));
+        ta->append_dim(10);
+
+        try {
+            ArrayGeoConstraint agc(ta);
+            CPPUNIT_ASSERT(!"Constructor should throw");
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Caught Error");
+        }
+
+        try {
+            ArrayGeoConstraint agc(ta, 10, 10, 89.9, 89);
+            CPPUNIT_ASSERT(!"Constructor should throw");
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Caught Error");
+        }
+
+        ta->append_dim(20);
+        try {
+            ArrayGeoConstraint agc(ta, 10, 10, 89.9, 89);
+            CPPUNIT_ASSERT(agc.d_extent.d_left == 10
+                           && agc.d_extent.d_top == 10
+                           && agc.d_extent.d_right == 89
+                           && agc.d_extent.d_bottom == 89.9);
+            CPPUNIT_ASSERT(agc.d_projection.d_name == "plat-carre"
+                           && agc.d_projection.d_datum == "wgs84");
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"Constructor should not throw");
+        }
+
+        try {
+            ArrayGeoConstraint agc(ta, 10, 10, 89.9, 89,
+                                   "plat-carre", "wgs84");
+            CPPUNIT_ASSERT(agc.d_extent.d_left == 10
+                           && agc.d_extent.d_top == 10
+                           && agc.d_extent.d_right == 89
+                           && agc.d_extent.d_bottom == 89.9);
+            CPPUNIT_ASSERT(agc.d_projection.d_name == "plat-carre"
+                           && agc.d_projection.d_datum == "wgs84");
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"Constructor should not throw");
+        }
+
+        try {
+            ArrayGeoConstraint agc(ta, 10, 10, 89.9, 89,
+                                   "plat-carre", "huh?");
+            CPPUNIT_ASSERT(!"Constructor should throw Error");
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Caught Error");
+        }
+    }
+
+    void build_lat_lon_maps_test() {
+        // build_lat_lon_maps() is called in the ctor
+        ArrayGeoConstraint agc(a1, 90, 10, -90, 89);
+
+        CPPUNIT_ASSERT(agc.get_lon()[0] == 10.0);
+        DBG(cerr << "agc.get_lon()[9]: " << agc.get_lon()[9] << endl);
+        CPPUNIT_ASSERT(agc.get_lon()[9] == 89.0);
+        CPPUNIT_ASSERT(agc.get_lat()[0] == 90.0);
+        CPPUNIT_ASSERT(agc.get_lat()[20] == -90.0);
+    }
+
+    void set_bounding_box_test() {
+	try {
+	    ArrayGeoConstraint agc1(a1, 90, 10, -90, 89);
+	    agc1.set_bounding_box(90, 10, -90, 89);
+	    CPPUNIT_ASSERT(agc1.get_longitude_index_left() == 0);
+	    CPPUNIT_ASSERT(agc1.get_longitude_index_right() == 9);
+	    CPPUNIT_ASSERT(agc1.get_latitude_index_top() == 0);
+	    CPPUNIT_ASSERT(agc1.get_latitude_index_bottom() == 20);
+
+	    ArrayGeoConstraint agc2(a2, 90, 0, -90, 359);
+	    agc2.set_bounding_box(45, 10, -45, 89);
+	    DBG(cerr << "agc2.get_longitude_index_left(): " << agc2.get_longitude_index_left() << endl); DBG(cerr << "agc2.get_longitude_index_right(): " << agc2.get_longitude_index_right() << endl); DBG(cerr << "agc2.get_latitude_index_top(): " << agc2.get_latitude_index_top() << endl); DBG(cerr << "agc2.get_latitude_index_bottom(): " << agc2.get_latitude_index_bottom() << endl);
+	    CPPUNIT_ASSERT(agc2.get_longitude_index_left() == 0);
+	    CPPUNIT_ASSERT(agc2.get_longitude_index_right() == 3);
+	    CPPUNIT_ASSERT(agc2.get_latitude_index_top() == 5);
+	    CPPUNIT_ASSERT(agc2.get_latitude_index_bottom() == 15);
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL(e.get_error_message());
+	}
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ArrayGeoConstraintTest);
+
+} // namespace libdap
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/ArrayTest.cc b/unit-tests/ArrayTest.cc
new file mode 100644
index 0000000..9ce2ebc
--- /dev/null
+++ b/unit-tests/ArrayTest.cc
@@ -0,0 +1,232 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <cstring>
+#include <string>
+
+#include "GNURegex.h"
+
+#include "Array.h"
+#include "Int16.h"
+#include "Str.h"
+#include "Structure.h"
+
+#include "debug.h"
+
+using namespace CppUnit;
+using namespace std;
+
+namespace libdap
+{
+
+class ArrayTest : public TestFixture {
+private:
+    Array *d_cardinal, *d_string, *d_structure;
+    Int16 *d_int16;
+    Str *d_str;
+    Structure *d_struct;
+    
+    string svalues[4];
+public:
+    ArrayTest() {
+        svalues[0] = "0 String";
+        svalues[1] = "1 String";
+        svalues[2] = "2 String";
+        svalues[3] = "3 String";
+    }
+    
+    ~ArrayTest() {}
+
+    void setUp() {
+        d_int16 = new Int16("Int16");
+        DBG(cerr << "d_int16: " << d_int16 << endl);
+        d_cardinal = new Array("Array_of_Int16", d_int16);
+        d_cardinal->append_dim(4, "dimension");
+        dods_int16 buffer[4] = {0, 1, 2, 3};
+        d_cardinal->val2buf(buffer);
+#ifdef DODS_DEBUG
+        for (int i = 0; i < 4; ++i)
+            cerr << "buffer[" << i << "]: " << buffer[i] << endl;
+#endif
+
+        d_str = new Str("Str");
+        d_string = new Array("Array_of_String", d_str);
+        d_string->append_dim(4, "dimension");
+        string sbuffer[4] = {"0 String", "1 String", "2 String", "3 String"};
+        d_string->val2buf(sbuffer);
+#ifdef DODS_DEBUG
+        for (int i = 0; i < 4; ++i)
+            cerr << "sbuffer[" << i << "]: " << sbuffer[i] << endl;
+#endif
+
+        d_struct = new Structure("Structure");
+        d_struct->add_var(d_int16);
+        d_structure = new Array("Array_of_Strctures", d_struct);
+        d_structure->append_dim(4, "dimension");
+        ostringstream oss;
+        for (int i = 0; i < 4; ++i) {
+            oss.str(""); oss << "field" << i;
+            Int16 *n = new Int16(oss.str());
+            DBG(cerr << "n " << i << ": " << n << endl);
+            oss.str(""); oss << "element" << i;
+            Structure *s = new Structure(oss.str());
+            s->add_var(n);
+            d_structure->set_vec(i, s);
+            delete n; n = 0;
+            delete s; s = 0;
+        }
+
+        delete d_int16; d_int16 = 0;
+        delete d_str; d_str = 0;
+        delete d_struct; d_struct = 0;        
+   } 
+
+    void tearDown() {
+        delete d_cardinal;
+        delete d_string;
+        delete d_structure;
+    }
+
+    bool re_match(Regex &r, const char *s) {
+        int match_position = r.match(s, strlen(s));
+        DBG(cerr << "match position: " << match_position 
+                 << " string length: " << (int)strlen(s) << endl);
+        return match_position == (int)strlen(s);
+    }
+
+    CPPUNIT_TEST_SUITE( ArrayTest );
+
+    CPPUNIT_TEST(duplicate_cardinal_test);
+    CPPUNIT_TEST(duplicate_string_test);
+    CPPUNIT_TEST(duplicate_structure_test);
+
+    CPPUNIT_TEST_SUITE_END();
+    
+    void duplicate_structure_test() {
+        Array::Dim_iter i = d_structure->dim_begin();
+        CPPUNIT_ASSERT(d_structure->dimension_size(i) == 4);
+#ifdef DODS_DEBUG
+        for (int i = 0; i < 4; ++i) {
+            Structure *s = dynamic_cast<Structure*>(d_structure->var(i));
+            DBG(cerr << "s: " << s << endl);
+            if (s)
+                s->print_decl(cerr);
+        }
+#endif
+
+        Array *a = new Array(*d_structure);
+        // a = *d_structure; I test operator= in duplicate_cardinal_test().
+        i = a->dim_begin();
+        CPPUNIT_ASSERT(a->dimension_size(i) == 4);
+        for (int i = 0; i < 4; ++i) {
+            // The point of this test is to ensure that the const ctor
+            // performs a deep copy; first test to make sure the pointers
+            // to BaseType instnaces are different in the two objects.
+            Structure *src = dynamic_cast<Structure*>(d_structure->var(i));
+            Structure *dest = dynamic_cast<Structure*>(a->var(i));
+            CPPUNIT_ASSERT(src != dest);
+            
+            // However, for the deep copy to be correct, the two arrays must
+            // have equivalent elements. We know there's only one field...
+            CPPUNIT_ASSERT(src->type() == dods_structure_c 
+                           && dest->type() == dods_structure_c);
+            Constructor::Vars_iter s = src->var_begin();
+            Constructor::Vars_iter d = dest->var_begin();
+            CPPUNIT_ASSERT((*s)->type() == dods_int16_c 
+                           && (*d)->type() == dods_int16_c);
+            CPPUNIT_ASSERT((*s)->name() == (*d)->name());
+        }
+        delete a; a = 0;
+    }
+    
+    void duplicate_string_test() {
+        Array::Dim_iter i = d_string->dim_begin();
+        CPPUNIT_ASSERT(d_string->dimension_size(i) == 4);
+        string *s = new string[4];
+        d_string->buf2val((void**)&s);
+        for (int i = 0; i < 4; ++i) {
+            CPPUNIT_ASSERT(s[i] == svalues[i] );
+            DBG(cerr << "s[" << i << "]: " << s[i] << endl);
+        }
+        
+        Array a = *d_string;
+        i = a.dim_begin();
+        CPPUNIT_ASSERT(a.dimension_size(i) == 4);
+        
+        string *s2 = new string[4];
+        d_string->buf2val((void**)&s2);
+        for (int i = 0; i < 4; ++i) {
+            CPPUNIT_ASSERT(s2[i] == svalues[i]);
+            DBG(cerr << "s2[" << i << "]: " << s2[i] << endl);
+        }
+        
+        delete[] s; s = 0;
+        delete[] s2; s2 = 0;
+    }
+    
+    void duplicate_cardinal_test() {
+        Array::Dim_iter i = d_cardinal->dim_begin();
+        CPPUNIT_ASSERT(d_cardinal->dimension_size(i) == 4);
+        dods_int16 *b = new dods_int16[4];
+        d_cardinal->buf2val((void**)&b);
+        for (int i = 0; i < 4; ++i) {
+            CPPUNIT_ASSERT(b[i] == i);
+            DBG(cerr << "b[" << i << "]: " << b[i] << endl);
+        }
+        delete[] b; b = 0;
+        
+        Array a = *d_cardinal;
+        i = a.dim_begin();
+        CPPUNIT_ASSERT(a.dimension_size(i) == 4);
+        
+        dods_int16 *b2 = new dods_int16[4];
+        d_cardinal->buf2val((void**)&b2);
+        for (int i = 0; i < 4; ++i) {
+            CPPUNIT_ASSERT(b2[i] == i);
+            DBG(cerr << "b2[" << i << "]: " << b2[i] << endl);
+        }
+        delete[] b2; b2 = 0;
+    }
+    
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ArrayTest);
+
+} // namespace libdap
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/AttrTableTest.cc b/unit-tests/AttrTableTest.cc
new file mode 100644
index 0000000..33bd5aa
--- /dev/null
+++ b/unit-tests/AttrTableTest.cc
@@ -0,0 +1,400 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <cstring>
+#include <string>
+#include <sstream>
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "GNURegex.h"
+
+#include "AttrTable.h"
+
+#include "testFile.cc"
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+static string build_fqn(AttrTable *at, string fqn)
+{
+    // The strange behavior at the top level is because the top level of an
+    // AttrTable (i.e. the DAS) is anonymous. Another bad design... jhrg 2/8/06
+    if (!at || !at->get_parent() || at->get_name().empty())
+        return fqn;
+    else
+        return build_fqn(at->get_parent(), at->get_name() + string(".") + fqn);
+}
+
+namespace libdap {
+
+class AttrTableTest: public TestFixture {
+    private:
+        AttrTable *at1;
+        AttrTable *cont_a, *cont_b, *cont_c, *cont_ba, *cont_ca, *cont_caa;
+
+    public:
+        AttrTableTest()
+        {
+        }
+        ~AttrTableTest()
+        {
+        }
+
+        void setUp()
+        {
+            at1 = new AttrTable;
+            cont_a = at1->append_container("a");
+            cont_a->append_attr("size", "Int32", "7");
+            cont_a->append_attr("type", "String", "cars");
+
+            cont_b = at1->append_container("b");
+            cont_b->append_attr("number", "Int32", "1");
+            cont_b->append_attr("type", "String", "houses");
+            cont_ba = cont_b->append_container("ba");
+            cont_ba->append_attr("name", "String", "fred");
+
+            cont_c = at1->append_container("c");
+            cont_ca = cont_c->append_container("ca");
+            cont_caa = cont_ca->append_container("caa");
+            cont_caa->append_attr("color", "String", "red");
+
+            // This AttrTable looks like:
+            //      Attributes {
+            //          a {
+            //              Int32 size 7;
+            //              String type cars;
+            //          }
+            //          b {
+            //              Int32 number 1;
+            //              String type houses;
+            //              ba {
+            //                  String name fred;
+            //              }
+            //          }
+            //          c {
+            //              ca {
+            //                  caa {
+            //                      String color red;
+            //                  }
+            //              }
+            //          }
+            //      }
+        }
+
+        void tearDown()
+        {
+            delete at1;
+            at1 = 0;
+        }
+
+        bool re_match(Regex &r, const char *s)
+        {
+            return r.match(s, strlen(s)) == (int) strlen(s);
+        }
+
+        CPPUNIT_TEST_SUITE( AttrTableTest );
+
+        CPPUNIT_TEST(clone_test);
+#if 1
+        CPPUNIT_TEST(find_container_test);
+        CPPUNIT_TEST(get_parent_test);
+        CPPUNIT_TEST(recurrsive_find_test);
+        CPPUNIT_TEST(find_test);
+        CPPUNIT_TEST(copy_ctor);
+        CPPUNIT_TEST(assignment);
+        CPPUNIT_TEST(erase_test);
+        CPPUNIT_TEST(names_with_spaces_test);
+        CPPUNIT_TEST(containers_with_spaces_test);
+        CPPUNIT_TEST(get_attr_iter_test);
+        CPPUNIT_TEST(del_attr_table_test);
+        CPPUNIT_TEST(append_attr_vector_test);
+#endif
+#if 0
+        CPPUNIT_TEST(print_xml_test);
+#endif
+
+        CPPUNIT_TEST_SUITE_END();
+
+        // Tests for methods
+
+        // This is to test for leaks in the clone() method.
+        void clone_test() {
+            AttrTable *att = new AttrTable;
+            att->append_container(new AttrTable(*cont_a), "copy_of_a");
+            delete att;
+        }
+
+        void recurrsive_find_test() {
+            AttrTable::Attr_iter location;
+            AttrTable *a = at1->recurrsive_find("color", &location);
+            CPPUNIT_ASSERT(a && a == cont_caa && a->get_name(location) == "color");
+
+            a = cont_caa->recurrsive_find("color", &location);
+            CPPUNIT_ASSERT(a && a == cont_caa && a->get_name(location) == "color");
+
+            a = at1->recurrsive_find("ba", &location);
+            CPPUNIT_ASSERT(a && a == cont_b && a->get_name(location) == "ba");
+        }
+
+        void get_parent_test() {
+            CPPUNIT_ASSERT(cont_caa->get_parent() == cont_ca);
+            CPPUNIT_ASSERT(cont_ca->get_parent() == cont_c);
+            CPPUNIT_ASSERT(cont_c->get_parent() == at1);
+            CPPUNIT_ASSERT(at1->get_parent() == 0);
+            CPPUNIT_ASSERT(build_fqn(cont_caa, "color") == "c.ca.caa.color");
+        }
+
+        void find_container_test() {
+            AttrTable *tmp = at1->find_container("a");
+            CPPUNIT_ASSERT(tmp != 0);
+            CPPUNIT_ASSERT(tmp == cont_a);
+
+            CPPUNIT_ASSERT(at1->find_container("b.ba") == cont_ba);
+            CPPUNIT_ASSERT(at1->find_container("a.b") == 0);
+            CPPUNIT_ASSERT(at1->find_container("c.ca.caa") == cont_caa);
+            CPPUNIT_ASSERT(at1->find_container("caa") == 0);
+
+            CPPUNIT_ASSERT(at1->find_container("a.size") == 0);
+            CPPUNIT_ASSERT(at1->find_container("b.ba.name") == 0);
+        }
+
+        void find_test() {
+            AttrTable *tmp;
+            AttrTable::Attr_iter iter;
+            at1->find("a", &tmp, &iter);
+            CPPUNIT_ASSERT(tmp && iter != tmp->attr_end() && tmp->is_container(iter)
+                    && tmp->get_name(iter) == "a");
+            at1->find("a.size", &tmp, &iter);
+            CPPUNIT_ASSERT(tmp && iter != tmp->attr_end() && !tmp->is_container(iter)
+                    && tmp->get_name(iter) == "size" && tmp->get_attr(iter) == "7");
+            at1->find("b.type", &tmp, &iter);
+            CPPUNIT_ASSERT(tmp && iter != tmp->attr_end() && !tmp->is_container(iter)
+                    && tmp->get_name(iter) == "type"
+                    && tmp->get_attr(iter) == "houses");
+            at1->find("c.ca.caa.color", &tmp, &iter);
+            CPPUNIT_ASSERT(tmp && iter != tmp->attr_end() && !tmp->is_container(iter)
+                    && tmp->get_name(iter) == "color"
+                    && tmp->get_attr(iter) == "red");
+            at1->find("d.size", &tmp, &iter);
+            CPPUNIT_ASSERT(!tmp);
+            at1->find("c.size", &tmp, &iter);
+            CPPUNIT_ASSERT(tmp == cont_c && iter == tmp->attr_end());
+        }
+
+        void copy_ctor() {
+            AttrTable at2 = *at1;
+            AttrTable::Attr_iter piter = at2.attr_begin();
+            CPPUNIT_ASSERT(at2.get_name(piter) == "a");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+            AttrTable *tmp = at2.get_attr_table(piter);
+            AttrTable::Attr_iter qiter = tmp->attr_begin();
+            CPPUNIT_ASSERT(tmp->get_name(qiter) == "size");
+            piter++;
+            CPPUNIT_ASSERT(at2.get_name(piter) == "b");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+            piter++;
+            CPPUNIT_ASSERT(at2.get_name(piter) == "c");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+        }
+
+        void assignment() {
+            AttrTable at2;
+            at2 = *at1;
+
+            AttrTable::Attr_iter piter = at2.attr_begin();
+            CPPUNIT_ASSERT(at2.get_name(piter) == "a");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+            AttrTable *tmp = at2.get_attr_table(piter);
+            AttrTable::Attr_iter qiter = tmp->attr_begin();
+            CPPUNIT_ASSERT(tmp->get_name(qiter) == "size");
+            piter++;
+            CPPUNIT_ASSERT(at2.get_name(piter) == "b");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+            piter++;
+            CPPUNIT_ASSERT(at2.get_name(piter) == "c");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+        }
+
+        void erase_test() {
+            // Copy at1 to at2 and verify that at2 is full of stuff...
+            AttrTable at2 = *at1;
+            AttrTable::Attr_iter piter = at2.attr_begin();
+            CPPUNIT_ASSERT(at2.get_name(piter) == "a");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+            AttrTable *tmp = at2.get_attr_table(piter);
+            AttrTable::Attr_iter qiter = tmp->attr_begin();
+            CPPUNIT_ASSERT(tmp->get_name(qiter) == "size");
+            piter++;
+            CPPUNIT_ASSERT(at2.get_name(piter) == "b");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+            piter++;
+            CPPUNIT_ASSERT(at2.get_name(piter) == "c");
+            CPPUNIT_ASSERT(at2.is_container(piter));
+
+            at2.erase();
+            CPPUNIT_ASSERT(at2.attr_map.size() == 0);
+            CPPUNIT_ASSERT(at2.d_name == "");
+        }
+
+        void names_with_spaces_test() {
+            // Create an AttrTable where some names have spaces. The spaces
+            // should be replaced by %20 escapes.
+            AttrTable *t = new AttrTable;
+            t->append_attr("long name", "String", "first");
+            t->append_attr("longer name", "String", "\"second test\"");
+            string sof;
+            FILE2string(sof, of, t->print(of, ""));
+            string attrs = "String long%20name \"first\";\n\
+String longer%20name \"second test\";";
+            CPPUNIT_ASSERT(sof.find(attrs) != string::npos);
+            delete t; t = 0;
+        }
+
+        void containers_with_spaces_test() {
+            AttrTable *top = new AttrTable;
+            try {
+                AttrTable *cont = top->append_container("Data Field");
+                cont->append_attr("long name", "String", "first");
+                cont->add_value_alias(top, "an alias", "long name");
+            }
+            catch (Error &e) {
+                cerr << e.get_error_message() << endl;
+                CPPUNIT_ASSERT("Caught Error exception!" && false);
+            }
+            try {
+                string sof;
+                FILE2string(sof, of, top->print(of, ""));
+                Regex r("Data%20Field \\{\n\
+.*String long%20name \"first\";\n\
+.*Alias an%20alias long%20name;\n\
+\\}\n\n");
+		cout << sof << endl ;
+                CPPUNIT_ASSERT(re_match(r, sof.c_str()));
+                delete top; top = 0;
+            }
+            catch (Error &e) {
+                cerr << e.get_error_message() << endl;
+                CPPUNIT_ASSERT("Caught Error exception!" && false);
+            }
+        }
+
+        void get_attr_iter_test() {
+            int n = at1->get_size();
+            CPPUNIT_ASSERT(n == 3);
+
+            AttrTable::Attr_iter i = at1->get_attr_iter(0);
+            CPPUNIT_ASSERT(at1->get_name(i) == "a");
+            i = at1->get_attr_iter(2);
+            CPPUNIT_ASSERT(at1->get_name(i) == "c");
+
+            i = at1->get_attr_iter(1);
+            CPPUNIT_ASSERT(at1->is_container(i));
+            AttrTable *t1 = at1->get_attr_table(i);
+            AttrTable::Attr_iter k = t1->get_attr_iter(1);
+            CPPUNIT_ASSERT(t1->get_name(k) == "type");
+            CPPUNIT_ASSERT(t1->get_attr(k, 0) == "houses");
+        }
+
+        void del_attr_table_test() {
+            AttrTable *b = at1->find_container("b");
+            AttrTable::Attr_iter i = b->attr_begin();
+            CPPUNIT_ASSERT(b->get_name(i) == "number");
+            i += 2;
+            CPPUNIT_ASSERT(b->get_name(i) == "ba");
+            b->del_attr_table(i);
+            i = b->attr_begin();
+            CPPUNIT_ASSERT(b->get_name(i) == "number");
+            i += 2;
+            CPPUNIT_ASSERT(i == b->attr_end());
+
+            // try a second table. at2 contains a scalar attribute followed by a
+            // container names 'a'.
+            try {
+                AttrTable *at2 = new AttrTable;
+                at2->append_attr("color", "String", "red");
+                AttrTable *cont_at2 = at2->append_container("a");
+                cont_at2->append_attr("size", "Int32", "7");
+                cont_at2->append_attr("type", "String", "cars");
+                i = at2->attr_begin();
+                CPPUNIT_ASSERT(at2->get_name(i) == "color");
+		i++ ;
+                CPPUNIT_ASSERT(at2->get_name(i) == "a");
+                at2->del_attr_table(i);
+                i = at2->attr_begin();
+                CPPUNIT_ASSERT(at2->get_name(i) == "color");
+		i++ ;
+                CPPUNIT_ASSERT(i == at2->attr_end());
+            }
+            catch (Error &e) {
+                cerr << "Error: " << e.get_error_message() << endl;
+                throw;
+            }
+            catch (...) {
+                cerr << "caught an exception!" << endl;
+                throw;
+            }
+        }
+
+        void append_attr_vector_test() {
+            // ("size", "Int32", "7")
+            vector<string> vs;
+            vs.push_back("8");
+            vs.push_back("9");
+            cont_a->append_attr("size", "Int32", &vs);
+
+            CPPUNIT_ASSERT(cont_a->get_attr("size", 0) == "7");
+            CPPUNIT_ASSERT(cont_a->get_attr("size", 1) == "8");
+            CPPUNIT_ASSERT(cont_a->get_attr("size", 2) == "9");
+            CPPUNIT_ASSERT(cont_a->get_attr_num("size") == 3);
+        }
+
+        void print_xml_test() {
+            at1->print_xml(stdout);
+        }
+    };
+
+    CPPUNIT_TEST_SUITE_REGISTRATION(AttrTableTest);
+
+} // namespace libdap
+
+int main(int, char**)
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/ByteTest.cc b/unit-tests/ByteTest.cc
new file mode 100644
index 0000000..be9f237
--- /dev/null
+++ b/unit-tests/ByteTest.cc
@@ -0,0 +1,118 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+// Tests for Byte. Tests features of BaseType, too. 7/19/2001 jhrg
+
+#include <sstream>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "Byte.h"
+
+#include "testFile.cc"
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+class ByteTest:public TestFixture {
+  private:
+    Byte * tb1;
+    Byte *tb2;
+    Byte *tb3;
+    Byte *tb4;
+
+  public:
+     ByteTest() {
+    } ~ByteTest() {
+    }
+
+    void setUp() {
+        tb1 = new Byte("tb1");
+        tb2 = new Byte("tb2 name with spaces");
+        tb3 = new Byte("tb3 %");
+        tb4 = new Byte("tb4 #");
+    }
+
+    void tearDown() {
+        delete tb1;
+        tb1 = 0;
+        delete tb2;
+        tb2 = 0;
+        delete tb3;
+        tb3 = 0;
+        delete tb4;
+        tb4 = 0;
+    }
+
+    CPPUNIT_TEST_SUITE(ByteTest);
+
+    CPPUNIT_TEST(name_mangling_test);
+    CPPUNIT_TEST(decl_mangling_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void name_mangling_test() {
+        CPPUNIT_ASSERT(tb1->name() == "tb1");
+        CPPUNIT_ASSERT(tb2->name() == "tb2 name with spaces");
+        CPPUNIT_ASSERT(tb3->name() == "tb3 %");
+        CPPUNIT_ASSERT(tb4->name() == "tb4 #");
+    }
+
+    void decl_mangling_test() {
+        ostringstream sof;
+        tb1->print_decl(sof, "", false);
+        CPPUNIT_ASSERT(sof.str().find("Byte tb1") != string::npos);
+
+        tb2->print_decl(sof, "", false);
+        CPPUNIT_ASSERT(sof.str().find("Byte tb2%20name%20with%20spaces") != string::npos);
+
+        tb3->print_decl(sof, "", false);
+        CPPUNIT_ASSERT(sof.str().find("Byte tb3%20%") != string::npos);
+
+        tb4->print_decl(sof, "", false);
+        CPPUNIT_ASSERT(sof.str().find("Byte tb4%20%23") != string::npos);
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ByteTest);
+
+int main(int, char **)
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/CEFunctionsTest.cc b/unit-tests/CEFunctionsTest.cc
new file mode 100644
index 0000000..557971c
--- /dev/null
+++ b/unit-tests/CEFunctionsTest.cc
@@ -0,0 +1,582 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Tests for the AISResources class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG
+
+#include "BaseType.h"
+#include "Int32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Array.h"
+#include "Grid.h"
+#include "DDS.h"
+#include "DAS.h"
+#include "ce_functions.h"
+#include <test_config.h>
+
+#include "../tests/TestTypeFactory.h"
+
+#include "debug.h"
+
+#if 1
+#define TWO_GRID_DDS "ce-functions-testsuite/two_grid.dds"
+#define TWO_GRID_DAS "ce-functions-testsuite/two_grid.das"
+#else
+#define TWO_GRID_DDS "unit-tests/ce-functions-testsuite/two_grid.dds"
+#define TWO_GRID_DAS "unit-tests/ce-functions-testsuite/two_grid.das"
+#endif
+
+using namespace CppUnit;
+using namespace libdap;
+using namespace std;
+
+int test_variable_sleep_interval = 0;
+
+class CEFunctionsTest:public TestFixture
+{
+private:
+    DDS * dds;
+    TestTypeFactory btf;
+    ConstraintEvaluator ce;
+public:
+    CEFunctionsTest()
+    {}
+    ~CEFunctionsTest()
+    {}
+
+    void setUp()
+    {
+        try {
+            dds = new DDS(&btf);
+	    string dds_file = (string)TEST_SRC_DIR + "/" + TWO_GRID_DDS ;
+            dds->parse(dds_file);
+            DAS das;
+	    string das_file = (string)TEST_SRC_DIR + "/" + TWO_GRID_DAS ;
+            das.parse(das_file);
+            dds->transfer_attributes(&das);
+            DBG(dds->print_xml(stderr, false, "noBlob"));
+            // Load values into the grid variables
+            Grid & a = dynamic_cast < Grid & >(*dds->var("a"));
+            Array & m1 = dynamic_cast < Array & >(**a.map_begin());
+
+            dods_float64 first_a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+            m1.val2buf(first_a);
+            m1.set_read_p(true);
+
+            dods_byte tmp_data[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
+            a.get_array()->val2buf((void*)tmp_data);
+            a.get_array()->set_read_p(true);
+
+            Grid & b = dynamic_cast < Grid & >(*dds->var("b"));
+            Array & m2 = dynamic_cast < Array & >(**b.map_begin());
+            dods_float64 first_b[10] = { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+            m2.val2buf(first_b);
+            m2.set_read_p(true);
+        }
+
+        catch (Error & e) {
+            cerr << "SetUp: " << e.get_error_message() << endl;
+            throw;
+        }
+    }
+
+    void tearDown()
+    {
+        delete dds; dds = 0;
+    }
+
+    CPPUNIT_TEST_SUITE( CEFunctionsTest );
+
+    // Test void projection_function_grid(int argc, BaseType *argv[], DDS &dds)
+
+    CPPUNIT_TEST(no_arguments_test);
+    CPPUNIT_TEST(one_argument_test);
+    CPPUNIT_TEST(one_argument_not_a_grid_test);
+    CPPUNIT_TEST(map_not_in_grid_test);
+    CPPUNIT_TEST(one_dim_grid_test);
+    CPPUNIT_TEST(one_dim_grid_two_expressions_test);
+    CPPUNIT_TEST(one_dim_grid_noninclusive_values_test);
+    CPPUNIT_TEST(one_dim_grid_descending_test);
+    CPPUNIT_TEST(one_dim_grid_two_expressions_descending_test);
+#if 0
+    // grid() is not required to handle this case.
+    CPPUNIT_TEST(values_outside_map_range_test);
+#endif
+
+    // Tests for linear_scale
+    CPPUNIT_TEST(linear_scale_args_test);
+    CPPUNIT_TEST(linear_scale_array_test);
+    CPPUNIT_TEST(linear_scale_grid_test);
+    CPPUNIT_TEST(linear_scale_grid_attributes_test);
+    CPPUNIT_TEST(linear_scale_grid_attributes_test2);
+    CPPUNIT_TEST(linear_scale_scalar_test);
+#if 0
+    // Not used and defined to throw by default. 2/23/11 jhrg
+    CPPUNIT_TEST(function_dap_1_test);
+    CPPUNIT_TEST(function_dap_2_test);
+    CPPUNIT_TEST(function_dap_3_test);
+#endif
+    CPPUNIT_TEST_SUITE_END();
+
+    void no_arguments_test()
+    {
+        try {
+            BaseType *btp = 0;
+            function_grid(0, 0, *dds, &btp);
+            CPPUNIT_ASSERT(true);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"no_arguments_test() should not have failed");
+        }
+    }
+
+    void one_argument_test()
+    {
+        try {
+            BaseType *argv[1];
+            argv[0] = dds->var("a");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+            BaseType *btp = 0;
+            function_grid(1, argv, *dds, &btp);
+            CPPUNIT_ASSERT("one_argument_not_a_grid_test() should work");
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"one_argument_test should not fail");
+        }
+    }
+
+    void one_argument_not_a_grid_test()
+    {
+        try {
+            BaseType *argv[1];
+            argv[0] = dds->var("lat");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this, although it is not a grid");
+            BaseType *btp = 0;
+            function_grid(1, argv, *dds, &btp);
+            CPPUNIT_ASSERT(!"one_argument_not_a_grid_test() should have failed");
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(true);
+        }
+    }
+
+    void map_not_in_grid_test()
+    {
+        try {
+            BaseType *argv[2];
+            argv[0] = dds->var("a");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+            argv[1] = new Str("");
+            string expression = "3<second<=7";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+            BaseType *btp = 0;
+            function_grid(2, argv, *dds, &btp);
+            CPPUNIT_ASSERT(!"map_not_in_grid_test() should have failed");
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(true);
+        }
+    }
+
+    void one_dim_grid_test()
+    {
+        try {
+            BaseType *argv[2];
+            argv[0] = dds->var("a");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+            argv[1] = new Str("");
+            string expression = "3<first<=7";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+
+            BaseType *btp = 0;
+            function_grid(2, argv, *dds, &btp);
+            Grid &g = dynamic_cast<Grid&>(*btp);
+
+            //Grid &g = dynamic_cast<Grid&>(*argv[0]);
+            Array &m = dynamic_cast<Array&>(**g.map_begin());
+            CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 4);
+            CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 7);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"one_dim_grid_test() should have worked");
+        }
+    }
+
+    void one_dim_grid_two_expressions_test()
+    {
+        try {
+            BaseType *argv[3];
+            argv[0] = dds->var("a");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+
+            argv[1] = new Str("");
+            string expression = "first>3";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+
+            argv[2] = new Str("");
+            expression = "first<=7";
+            dynamic_cast<Str*>(argv[2])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[2])->set_read_p(true);
+
+            //function_grid(3, argv, *dds);
+            BaseType *btp = 0;
+            function_grid(3, argv, *dds, &btp);
+            Grid &g = dynamic_cast<Grid&>(*btp);
+
+            //Grid &g = dynamic_cast<Grid&>(*function_grid(3, argv, *dds));
+            //Grid &g = dynamic_cast<Grid&>(*argv[0]);
+            Array &m = dynamic_cast<Array&>(**g.map_begin());
+            CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 4);
+            CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 7);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"one_dim_grid_two_expressions_test() should have worked");
+        }
+    }
+
+    void one_dim_grid_descending_test()
+    {
+        try {
+            BaseType *argv[2];
+            argv[0] = dds->var("b");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+            argv[1] = new Str("");
+            string expression = "3<first<=7";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+
+            BaseType *btp = 0;
+            function_grid(2, argv, *dds, &btp);
+            Grid &g = dynamic_cast<Grid&>(*btp);
+
+            //function_grid(2, argv, *dds);
+            //Grid &g = dynamic_cast<Grid&>(*function_grid(2, argv, *dds));
+            //Grid &g = dynamic_cast<Grid&>(*argv[0]);
+            Array &m = dynamic_cast<Array&>(**g.map_begin());
+            CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 2);
+            CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 5);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"one_dim_grid_test() should have worked");
+        }
+    }
+
+    void one_dim_grid_two_expressions_descending_test()
+    {
+        try {
+            BaseType *argv[3];
+            argv[0] = dds->var("b");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+
+            argv[1] = new Str("");
+            string expression = "first>3";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+
+            argv[2] = new Str("");
+            expression = "first<=7";
+            dynamic_cast<Str*>(argv[2])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[2])->set_read_p(true);
+
+            BaseType *btp = 0;
+            function_grid(3, argv, *dds, &btp);
+            Grid &g = dynamic_cast<Grid&>(*btp);
+
+            //function_grid(3, argv, *dds);
+            //Grid &g = dynamic_cast<Grid&>(*function_grid(3, argv, *dds));
+            //Grid &g = dynamic_cast<Grid&>(*argv[0]);
+            Array &m = dynamic_cast<Array&>(**g.map_begin());
+            CPPUNIT_ASSERT(m.dimension_start(m.dim_begin(), true) == 2);
+            CPPUNIT_ASSERT(m.dimension_stop(m.dim_begin(), true) == 5);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"one_dim_grid_two_expressions_test() should have worked");
+        }
+    }
+
+    void one_dim_grid_noninclusive_values_test()
+    {
+        try {
+            BaseType *argv[2];
+            argv[0] = dds->var("a");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+            argv[1] = new Str("");
+            string expression = "7<first<=3";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+
+            BaseType *btp = 0;
+            function_grid(2, argv, *dds, &btp);
+            Grid &g = dynamic_cast<Grid&>(*btp);
+
+            // function_grid(2, argv, *dds);
+
+            CPPUNIT_ASSERT(!"one_dim_grid_noninclusive_values_test() should not have worked");
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(true);
+        }
+    }
+
+    // grid() is not required to handle this case. This test is not used.
+    void values_outside_map_range_test()
+    {
+        try {
+            BaseType *argv[2];
+            argv[0] = dds->var("a");
+            CPPUNIT_ASSERT(argv[0] && "dds->var should find this");
+            argv[1] = new Str("");
+            string expression = "3<=first<20";
+            dynamic_cast<Str*>(argv[1])->val2buf(&expression);
+            dynamic_cast<Str*>(argv[1])->set_read_p(true);
+
+            BaseType *btp = 0;
+            function_grid(2, argv, *dds, &btp);
+            Grid &g = dynamic_cast<Grid&>(*btp);
+
+            // function_grid(2, argv, *dds);
+
+            CPPUNIT_ASSERT(!"values_outside_map_range_test() should not have worked");
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(true);
+        }
+    }
+
+    // linear_scale tests
+    void linear_scale_args_test() {
+        try {
+            BaseType *btp = 0;
+            function_linear_scale(0, 0, *dds, &btp);
+            CPPUNIT_ASSERT(true);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"linear_scale_args_test: should not throw Error");
+        }
+    }
+
+    void linear_scale_array_test() {
+        try {
+            Array *a = dynamic_cast<Grid&>(*dds->var("a")).get_array();
+            CPPUNIT_ASSERT(a);
+            BaseType *argv[3];
+            argv[0] = a;
+            argv[1] = new Float64("");
+            dynamic_cast<Float64*>(argv[1])->set_value(0.1);//m
+            argv[2] = new Float64("");
+            dynamic_cast<Float64*>(argv[2])->set_value(10);//b
+            BaseType *scaled = 0;
+            function_linear_scale(3, argv, *dds, &scaled);
+            CPPUNIT_ASSERT(scaled->type() == dods_array_c
+                           && scaled->var()->type() == dods_float64_c);
+            double *values = extract_double_array(dynamic_cast<Array*>(scaled));
+            CPPUNIT_ASSERT(values[0] == 10);
+            CPPUNIT_ASSERT(values[1] == 10.1);
+            CPPUNIT_ASSERT(values[9] == 10.9);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
+        }
+    }
+
+    void linear_scale_grid_test() {
+        try {
+            Grid *g = dynamic_cast<Grid*>(dds->var("a"));
+            CPPUNIT_ASSERT(g);
+            BaseType *argv[3];
+            argv[0] = g;
+            argv[1] = new Float64("");
+            dynamic_cast<Float64*>(argv[1])->set_value(0.1);
+            argv[2] = new Float64("");
+            dynamic_cast<Float64*>(argv[2])->set_value(10);
+            BaseType *scaled = 0;
+            function_linear_scale(3, argv, *dds, &scaled);
+            CPPUNIT_ASSERT(scaled->type() == dods_grid_c);
+            Grid *g_s = dynamic_cast<Grid*>(scaled);
+            CPPUNIT_ASSERT(g_s->get_array()->var()->type() == dods_float64_c);
+            double *values = extract_double_array(g_s->get_array());
+            CPPUNIT_ASSERT(values[0] == 10);
+            CPPUNIT_ASSERT(values[1] == 10.1);
+            CPPUNIT_ASSERT(values[9] == 10.9);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
+        }
+    }
+
+    void linear_scale_grid_attributes_test() {
+        try {
+            Grid *g = dynamic_cast<Grid*>(dds->var("a"));
+            CPPUNIT_ASSERT(g);
+            BaseType *argv[1];
+            argv[0] = g;
+            BaseType *scaled = 0;
+            function_linear_scale(1, argv, *dds, &scaled);
+            CPPUNIT_ASSERT(scaled->type() == dods_grid_c);
+            Grid *g_s = dynamic_cast<Grid*>(scaled);
+            CPPUNIT_ASSERT(g_s->get_array()->var()->type() == dods_float64_c);
+            double *values = extract_double_array(g_s->get_array());
+            CPPUNIT_ASSERT(values[0] == 10);
+            CPPUNIT_ASSERT(values[1] == 10.1);
+            CPPUNIT_ASSERT(values[9] == 10.9);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"Error in linear_scale_grid_test()");
+        }
+    }
+
+    // This tests the case where attributes are not found
+    void linear_scale_grid_attributes_test2() {
+        try {
+            Grid *g = dynamic_cast<Grid*>(dds->var("b"));
+            CPPUNIT_ASSERT(g);
+            BaseType *argv[1];
+            argv[0] = g;
+            BaseType *btp = 0;
+            function_linear_scale(1, argv, *dds, &btp);
+            CPPUNIT_FAIL("Should not get here; no params passed and no attributes set for grid 'b'");
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Caught exception");
+        }
+    }
+
+    void linear_scale_scalar_test() {
+        try {
+            Int32 *i = new Int32("linear_scale_test_int32");
+            CPPUNIT_ASSERT(i);
+            i->set_value(1);
+            BaseType *argv[3];
+            argv[0] = i;
+            argv[1] = new Float64("");
+            dynamic_cast<Float64*>(argv[1])->set_value(0.1);//m
+            argv[2] = new Float64("");
+            dynamic_cast<Float64*>(argv[2])->set_value(10);//b
+            BaseType *scaled = 0;
+            function_linear_scale(3, argv, *dds, &scaled);
+            CPPUNIT_ASSERT(scaled->type() == dods_float64_c);
+
+            CPPUNIT_ASSERT(dynamic_cast<Float64*>(scaled)->value() == 10.1);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT(!"Error in linear_scale_scalar_test()");
+        }
+    }
+
+
+    void function_dap_1_test() {
+        try {
+            Int32 *i = new Int32("function_dap_1_test_int32");
+            CPPUNIT_ASSERT(i);
+            i->set_value(2);
+            BaseType *argv[1];
+            argv[0] = i;
+
+            ConstraintEvaluator unused;
+            function_dap(1, argv, *dds, unused);
+
+            CPPUNIT_ASSERT(dds->get_dap_major() == 2);
+            CPPUNIT_ASSERT(dds->get_dap_minor() == 0);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_FAIL("Error in function_dap_1_test(): " + e.get_error_message());
+        }
+    }
+
+    void function_dap_2_test() {
+        try {
+            Float64 *d = new Float64("function_dap_1_test_float64");
+            CPPUNIT_ASSERT(d);
+            d->set_value(3.2);
+            BaseType *argv[1];
+            argv[0] = d;
+
+            ConstraintEvaluator unused;
+            function_dap(1, argv, *dds, unused);
+
+            CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+            CPPUNIT_ASSERT(dds->get_dap_minor() == 2);
+        }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_FAIL("Error in function_dap_2_test(): " + e.get_error_message());
+        }
+    }
+
+    void function_dap_3_test() {
+        try {
+            cerr <<"In function_dap_3_test" << endl;
+            ConstraintEvaluator unused;
+            function_dap(0, 0, *dds, unused);
+
+            CPPUNIT_FAIL("Should have thrown an exception on no args");
+                    }
+        catch (Error &e) {
+            DBG(cerr << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Pass: Caught exception");
+        }
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(CEFunctionsTest);
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/DASTest.cc b/unit-tests/DASTest.cc
new file mode 100644
index 0000000..1f3e5c1
--- /dev/null
+++ b/unit-tests/DASTest.cc
@@ -0,0 +1,96 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <string>
+
+#include "DAS.h"
+#include "debug.h"
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace libdap;
+
+class DASTest: public TestFixture {
+private:
+    DAS *das, *das2;
+
+public:
+    DASTest() {}
+    ~DASTest() {}
+
+    void setUp() {
+	das = new DAS();
+	das2 = new DAS();
+    }
+
+    void tearDown() {
+	delete das; das = 0;
+	delete das2; das2 = 0;
+    }
+
+    CPPUNIT_TEST_SUITE( DASTest );
+
+    CPPUNIT_TEST(error_values_test);
+    CPPUNIT_TEST(symbol_name_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void error_values_test() {
+	try {
+	    das->parse((string)TEST_SRC_DIR + "/das-testsuite/bad_value_test.1");
+	    DBG2(das->print(stderr));
+	}
+	catch (Error &e) {
+            cerr << e.get_error_message() << endl;
+	    CPPUNIT_ASSERT(!"Caught an unexpected Error object.");
+	}
+    }
+
+    void symbol_name_test() {
+	das->parse((string)TEST_SRC_DIR + "/das-testsuite/test.34");
+	CPPUNIT_ASSERT(das->get_table("var1")->get_attr("y#z", 0) == "15");
+
+	string s = das->get_table("var1.component1.inner component")->get_attr("tag");
+        CPPUNIT_ASSERT(s == "xyz123");
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DASTest);
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/DDSTest.cc b/unit-tests/DDSTest.cc
new file mode 100644
index 0000000..8d03b85
--- /dev/null
+++ b/unit-tests/DDSTest.cc
@@ -0,0 +1,610 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <sstream>
+
+#include "config.h"
+
+//#define DODS_DEBUG2
+// #define DODS_DEBUG
+
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "DDS.h"
+
+#include "GNURegex.h"
+#include "util.h"
+#include "debug.h"
+#include "test_config.h"
+
+using namespace CppUnit;
+using namespace std;
+
+namespace libdap {
+
+class DDSTest: public TestFixture {
+    private:
+        DDS *dds1, *dds2;
+        BaseTypeFactory factory;
+
+    public:
+        DDSTest()
+        {
+        }
+        ~DDSTest()
+        {
+        }
+
+        void setUp()
+        {
+            //factory = new BaseTypeFactory;
+            dds1 = new DDS(&factory, "test1");
+            dds2 = new DDS(&factory, "test2");
+        }
+
+        void tearDown()
+        {
+            delete dds1;
+            dds1 = 0;
+            delete dds2;
+            dds2 = 0;
+            //delete factory; factory = 0;
+        }
+
+        bool re_match(Regex &r, const string &s)
+        {
+            int match = r.match(s.c_str(), s.length());
+            DBG(cerr << "Match: " << match << " should be: " << s.length()
+                    << endl);
+            return match == static_cast<int> (s.length());
+        }
+
+        // The tests commented exercise features no longer supported
+        // by libdap. In particular, a DAS must now be properly structured
+        // to work with transfer_attributes() - if a handler builds a malformed
+        // DAS, it will need to specialize the BaseType::transfer_attributes()
+        // method.
+        CPPUNIT_TEST_SUITE( DDSTest );
+#if 1
+        CPPUNIT_TEST(transfer_attributes_test_1);
+        CPPUNIT_TEST(transfer_attributes_test_2);
+
+        CPPUNIT_TEST(symbol_name_test);
+        // These test both transfer_attributes() and print_xml()
+        CPPUNIT_TEST(print_xml_test);
+        CPPUNIT_TEST(print_xml_test2);
+        CPPUNIT_TEST(print_xml_test3);
+#endif
+        // CPPUNIT_TEST(print_xml_test3_1);
+#if 1
+        CPPUNIT_TEST(print_xml_test4);
+
+        CPPUNIT_TEST(print_xml_test5);
+#endif
+        // CPPUNIT_TEST(print_xml_test5_1);
+#if 1
+        CPPUNIT_TEST(print_xml_test6);
+#endif
+        // CPPUNIT_TEST(print_xml_test7);
+
+        CPPUNIT_TEST_SUITE_END();
+
+        void transfer_attributes_test_1() {
+            try {
+                dds1->parse((string)TEST_SRC_DIR + "/dds-testsuite/fnoc1.nc.dds");
+                DAS das;
+                das.parse((string)TEST_SRC_DIR + "/dds-testsuite/fnoc1.nc.das");
+                dds1->transfer_attributes(&das);
+
+                DBG2(dds1->print_xml(cerr, false, ""));
+
+                AttrTable &at = dds1->get_attr_table();
+                AttrTable::Attr_iter i = at.attr_begin();
+                CPPUNIT_ASSERT(i != at.attr_end() && at.get_name(i) == "NC_GLOBAL");
+                CPPUNIT_ASSERT(i != at.attr_end() && at.get_name(++i) == "DODS_EXTRA");
+            }
+            catch (Error &e) {
+                cout << "Error: " << e.get_error_message() << endl;
+                CPPUNIT_FAIL("Error thrown!");
+            }
+        }
+
+        void transfer_attributes_test_2() {
+            try {
+                dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/3B42.980909.5.HDF.dds");
+                DAS das;
+                das.parse((string)TEST_SRC_DIR + "/dds-testsuite/3B42.980909.5.hacked.HDF.das");
+                dds2->transfer_attributes(&das);
+
+                DBG2(dds2->print_xml(cerr, false, ""));
+
+                AttrTable &at = dds2->get_attr_table();
+                AttrTable::Attr_iter i = at.attr_begin();
+                CPPUNIT_ASSERT(i != at.attr_end() && at.get_name(i) == "HDF_GLOBAL");
+                CPPUNIT_ASSERT(i != at.attr_end() && at.get_name(++i) == "CoreMetadata");
+            }
+            catch (Error &e) {
+                cout << "Error: " << e.get_error_message() << endl;
+                CPPUNIT_FAIL("Error thrown!");
+            }
+        }
+
+        void symbol_name_test() {
+            try {
+                // read a DDS.
+                dds1->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.18");
+                CPPUNIT_ASSERT(dds1->var("oddTemp"));
+
+                dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19b");
+                CPPUNIT_ASSERT(dds2->var("b#c"));
+                CPPUNIT_ASSERT(dds2->var("b%23c"));
+                CPPUNIT_ASSERT(dds2->var("huh.Image#data"));
+                CPPUNIT_ASSERT(dds2->var("c d"));
+                CPPUNIT_ASSERT(dds2->var("c%20d"));
+            }
+            catch (Error &e) {
+                cerr << e.get_error_message() << endl;
+                CPPUNIT_FAIL("Caught unexpected Error object");
+            }
+        }
+
+        void print_xml_test() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19b");
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19\"\n\
+.*\
+   <Int32 name=\"a\"/>\n\
+    <Array name=\"b#c\">\n\
+        <Int32/>\n\
+        <dimension size=\"10\"/>\n\
+    </Array>\n\
+    <Float64 name=\"c d\"/>\n\
+    <Grid name=\"huh\">\n\
+        <Array name=\"Image#data\">\n\
+            <Byte/>\n\
+            <dimension size=\"512\"/>\n\
+        </Array>\n\
+        <Map name=\"colors\">\n\
+            <String/>\n\
+            <dimension size=\"512\"/>\n\
+        </Map>\n\
+    </Grid>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+            }
+
+        void print_xml_test2() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19c");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19c.das");
+
+            dds2->transfer_attributes(&das);
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG2(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19c\"\n\
+.*\
+\n\
+    <Attribute name=\"NC_GLOBAL\" type=\"Container\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>Attribute merge test</value>\n\
+        </Attribute>\n\
+        <Attribute name=\"primes\" type=\"Int32\">\n\
+            <value>2</value>\n\
+            <value>3</value>\n\
+            <value>5</value>\n\
+            <value>7</value>\n\
+            <value>11</value>\n\
+        </Attribute>\n\
+    </Attribute>\n\
+\n\
+    <Int32 name=\"a\"/>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+
+        }
+
+        void print_xml_test3() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19d");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19d.das");
+
+            dds2->transfer_attributes(&das);
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG2(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19d\"\n\
+.*\
+    <Array name=\"b#c\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>b pound c</value>\n\
+        </Attribute>\n\
+        <Int32/>\n\
+        <dimension size=\"10\"/>\n\
+    </Array>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+        // This tests the HDF4 <var>_dim_n attribute. support for that was
+        // moved to the handler itself.
+        void print_xml_test3_1() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19d");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19d1.das");
+
+            dds2->transfer_attributes(&das);
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG2(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19d\"\n\
+.*\
+    <Array name=\"b#c\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>b pound c</value>\n\
+        </Attribute>\n\
+        <Attribute name=\"dim_0\" type=\"Container\">\n\
+            <Attribute name=\"add_offset\" type=\"Float64\">\n\
+                <value>0.125</value>\n\
+            </Attribute>\n\
+        </Attribute>\n\
+        <Int32/>\n\
+        <dimension size=\"10\"/>\n\
+    </Array>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+        void print_xml_test4() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19e");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19e.das");
+
+            dds2->transfer_attributes(&das);
+
+            DBG(AttrTable &at2 = dds2->var("c%20d")->get_attr_table());
+            DBG(at2.print(stderr));
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19e\"\n\
+.*\
+    <Float64 name=\"c d\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>c d with a WWW escape sequence</value>\n\
+        </Attribute>\n\
+        <Attribute name=\"sub\" type=\"Container\">\n\
+            <Attribute name=\"about\" type=\"String\">\n\
+                <value>Attributes inside attributes</value>\n\
+            </Attribute>\n\
+            <Attribute name=\"pi\" type=\"Float64\">\n\
+                <value>3.1415</value>\n\
+            </Attribute>\n\
+        </Attribute>\n\
+    </Float64>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+        void print_xml_test5() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19f");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19f.das");
+
+            try {
+                dds2->transfer_attributes(&das);
+            }
+            catch (Error &e) {
+                cerr << "Error: " << e.get_error_message() << endl;
+                CPPUNIT_FAIL("Error exception");
+            }
+
+            DBG(AttrTable &at2 = dds2->var("huh")->get_attr_table());
+            DBG(at2.print(stderr));
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19f\"\n\
+.*\
+    <Grid name=\"huh\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>The Grid huh</value>\n\
+        </Attribute>\n\
+        <Array name=\"Image#data\">\n\
+            <Byte/>\n\
+            <dimension size=\"512\"/>\n\
+        </Array>\n\
+        <Map name=\"colors\">\n\
+            <Attribute name=\"long_name2\" type=\"String\">\n\
+                <value>The color map vector</value>\n\
+            </Attribute>\n\
+            <String/>\n\
+            <dimension size=\"512\"/>\n\
+        </Map>\n\
+    </Grid>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+        // Tests flat DAS into a DDS; no longer supported by libdap; specialize
+        // handlers if they make these malformed DAS objects
+        void print_xml_test5_1() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19f");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19f1.das");
+
+            try {
+                dds2->transfer_attributes(&das);
+            }
+            catch (Error &e) {
+                cerr << "Error: " << e.get_error_message() << endl;
+                CPPUNIT_FAIL("Error exception");
+            }
+
+            DBG(AttrTable &at2 = dds2->var("huh")->get_attr_table());
+            DBG(at2.print(stderr));
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19f\"\n\
+.*\
+    <Grid name=\"huh\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>The Grid huh</value>\n\
+        </Attribute>\n\
+        <Array name=\"Image#data\">\n\
+            <Byte/>\n\
+            <dimension size=\"512\"/>\n\
+        </Array>\n\
+        <Map name=\"colors\">\n\
+            <Attribute name=\"long_name2\" type=\"String\">\n\
+                <value>The color map vector</value>\n\
+            </Attribute>\n\
+            <Attribute name=\"units\" type=\"String\">\n\
+                <value>m/s</value>\n\
+            </Attribute>\n\
+            <String/>\n\
+            <dimension size=\"512\"/>\n\
+        </Map>\n\
+    </Grid>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+        void print_xml_test6() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19b");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19b.das");
+
+            dds2->transfer_attributes(&das);
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19\"\n\
+.*\
+    <Attribute name=\"NC_GLOBAL\" type=\"Container\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>Attribute merge test</value>\n\
+        </Attribute>\n\
+        <Attribute name=\"primes\" type=\"Int32\">\n\
+            <value>2</value>\n\
+            <value>3</value>\n\
+            <value>5</value>\n\
+            <value>7</value>\n\
+            <value>11</value>\n\
+        </Attribute>\n\
+    </Attribute>\n\
+\n\
+    <Int32 name=\"a\"/>\n\
+    <Array name=\"b#c\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>b pound c</value>\n\
+        </Attribute>\n\
+        <Int32/>\n\
+        <dimension size=\"10\"/>\n\
+    </Array>\n\
+    <Float64 name=\"c d\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>c d with a WWW escape sequence</value>\n\
+        </Attribute>\n\
+        <Attribute name=\"sub\" type=\"Container\">\n\
+            <Attribute name=\"about\" type=\"String\">\n\
+                <value>Attributes inside attributes</value>\n\
+            </Attribute>\n\
+            <Attribute name=\"pi\" type=\"Float64\">\n\
+                <value>3.1415</value>\n\
+            </Attribute>\n\
+        </Attribute>\n\
+    </Float64>\n\
+    <Grid name=\"huh\">\n\
+        <Attribute name=\"long_name\" type=\"String\">\n\
+            <value>The Grid huh</value>\n\
+        </Attribute>\n\
+        <Array name=\"Image#data\">\n\
+            <Byte/>\n\
+            <dimension size=\"512\"/>\n\
+        </Array>\n\
+        <Map name=\"colors\">\n\
+            <Attribute name=\"long_name\" type=\"String\">\n\
+                <value>The color map vector</value>\n\
+            </Attribute>\n\
+            <String/>\n\
+            <dimension size=\"512\"/>\n\
+        </Map>\n\
+    </Grid>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+        // Tests flat DAS into a DDS; no longer supported by libdap; specialize
+        // handlers if they make these malformed DAS objects
+        void print_xml_test7() {
+            dds2->parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19g");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/dds-testsuite/test.19g.das");
+
+            try {
+                dds2->transfer_attributes(&das);
+            }
+            catch (Error &e) {
+                cerr << "Error: " << e.get_error_message() << endl;
+                CPPUNIT_FAIL("Error exception");
+            }
+
+            DBG(AttrTable &at2 = dds2->var("huh")->get_attr_table());
+            DBG(at2.print(stderr));
+
+            ostringstream oss;
+            dds2->print_xml(oss, false, "http://localhost/dods/test.xyz");
+
+            DBG(cerr << oss.str() << endl);
+
+            Regex r("<.xml version=\"1.0\" encoding=\"UTF-8\".>\n\
+<Dataset name=\"test.19\"\n\
+.*\
+    <Structure name=\"s\">\n\
+        <Array name=\"b#c\">\n\
+            <Attribute name=\"long_name\" type=\"String\">\n\
+                <value>b pound c</value>\n\
+            </Attribute>\n\
+            <Attribute name=\"dim_0\" type=\"Container\">\n\
+                <Attribute name=\"add_offset\" type=\"Float64\">\n\
+                    <value>0.125</value>\n\
+                </Attribute>\n\
+            </Attribute>\n\
+            <Int32/>\n\
+            <dimension size=\"10\"/>\n\
+        </Array>\n\
+        <Grid name=\"huh\">\n\
+            <Attribute name=\"long_name\" type=\"String\">\n\
+                <value>The Grid huh</value>\n\
+            </Attribute>\n\
+            <Array name=\"Image#data\">\n\
+                <Byte/>\n\
+                <dimension size=\"512\"/>\n\
+            </Array>\n\
+            <Map name=\"colors\">\n\
+                <Attribute name=\"long_name2\" type=\"String\">\n\
+                    <value>The color map vector</value>\n\
+                </Attribute>\n\
+                <Attribute name=\"units\" type=\"String\">\n\
+                    <value>m/s</value>\n\
+                </Attribute>\n\
+                <String/>\n\
+                <dimension size=\"512\"/>\n\
+            </Map>\n\
+        </Grid>\n\
+    </Structure>\n\
+\n\
+    <dataBLOB href=\"\"/>\n\
+</Dataset>\n");
+
+            CPPUNIT_ASSERT(re_match(r, oss.str()));
+        }
+
+    };
+
+    CPPUNIT_TEST_SUITE_REGISTRATION(DDSTest);
+
+}
+
+int main(int, char**)
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/DDXParserTest.cc b/unit-tests/DDXParserTest.cc
new file mode 100644
index 0000000..0033cb2
--- /dev/null
+++ b/unit-tests/DDXParserTest.cc
@@ -0,0 +1,568 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Tests for the AISResources class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG 1
+
+#include "DDXParserSAX2.h"
+//#include "DDXParser.h"
+#include "BaseTypeFactory.h"
+#include "ObjectType.h"
+#include "mime_util.h"
+#include "debug.h"
+
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+namespace libdap {
+
+class DDXParserTest : public TestFixture {
+private:
+    BaseTypeFactory *factory;
+    DDXParser *ddx_parser;
+    DDS *dds;
+
+public:
+    DDXParserTest() {}
+    ~DDXParserTest() {}
+
+    void setUp() {
+	factory = new BaseTypeFactory;
+	ddx_parser = new DDXParser(factory);
+	dds = new DDS(factory);
+    }
+
+    void tearDown() {
+	delete ddx_parser; ddx_parser = 0;
+	delete factory; factory = 0;
+	delete dds; dds = 0;
+    }
+
+    CPPUNIT_TEST_SUITE( DDXParserTest );
+
+    CPPUNIT_TEST(other_xml_parse_test1);
+    CPPUNIT_TEST(other_xml_parse_test2);
+    CPPUNIT_TEST(other_xml_parse_test3);
+    CPPUNIT_TEST(dap_version_test);
+    CPPUNIT_TEST(no_blob_version_32_test);
+    CPPUNIT_TEST(blob_in_version_32_test);
+    CPPUNIT_TEST(parsing_ddx_from_dataddx_test);
+    CPPUNIT_TEST(top_level_attribute_test);
+    CPPUNIT_TEST(top_level_attribute_container_test);
+    CPPUNIT_TEST(top_level_simple_types_test);
+    CPPUNIT_TEST(top_level_simple_types_with_attributes_test);
+    CPPUNIT_TEST(simple_arrays_test);
+    CPPUNIT_TEST(simple_arrays_multi_dim_test);
+    CPPUNIT_TEST(simple_arrays_attributes_test);
+    CPPUNIT_TEST(structure_test);
+    CPPUNIT_TEST(sequence_test);
+    CPPUNIT_TEST(grid_test);
+    CPPUNIT_TEST(intern_stream_test);
+    CPPUNIT_TEST(intern_ddx_from_dataddx_test);
+
+    // Error tests
+    CPPUNIT_TEST(unknown_tag_test);
+    CPPUNIT_TEST(bad_nesting_test);
+    CPPUNIT_TEST(unknown_end_tag_test);
+    CPPUNIT_TEST(variable_in_attribtue_container_test);
+    CPPUNIT_TEST(simple_type_missing_attribute_test);
+    CPPUNIT_TEST(array_missing_dimension_test);
+    CPPUNIT_TEST(array_missing_dimension_stream_read_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void other_xml_parse_test1() {
+        try {
+            string cid;
+            ddx_parser->intern((string)TEST_SRC_DIR + "/ddx-testsuite/test.1.other_xml.ddx", dds, cid);
+            DBG(dds->print_xml(cout, false, "    "));
+            CPPUNIT_ASSERT(dds->get_dataset_name() == "200803061600_HFRadar_USEGC_6km_rtv_SIO.nc");
+            CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+            CPPUNIT_ASSERT(dds->get_dap_minor() == 3);
+        }
+        catch (DDXParseFailed &e) {
+            DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_FAIL("test.00.ddx failed.");
+        }
+    }
+
+    void other_xml_parse_test2() {
+        try {
+            string cid;
+            ddx_parser->intern((string)TEST_SRC_DIR + "/ddx-testsuite/test.2.other_xml.ddx", dds, cid);
+            DBG(dds->print_xml(cout, false, "    "));
+            CPPUNIT_ASSERT(dds->get_dataset_name() == "200803061600_HFRadar_USEGC_6km_rtv_SIO.nc");
+            CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+            CPPUNIT_ASSERT(dds->get_dap_minor() == 3);
+        }
+        catch (DDXParseFailed &e) {
+            DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_FAIL("test.00.ddx failed.");
+        }
+    }
+
+    void other_xml_parse_test3() {
+        try {
+            string cid;
+            ddx_parser->intern((string)TEST_SRC_DIR + "/ddx-testsuite/test.3.other_xml.ddx", dds, cid);
+            DBG(dds->print_xml(cout, false, "    "));
+            CPPUNIT_ASSERT(dds->get_dataset_name() == "200803061600_HFRadar_USEGC_6km_rtv_SIO.nc");
+            CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+            CPPUNIT_ASSERT(dds->get_dap_minor() == 3);
+        }
+        catch (DDXParseFailed &e) {
+            DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_FAIL("test.00.ddx failed.");
+        }
+    }
+
+    void dap_version_test() {
+    	FILE *in;
+    	try {
+    	    string blob;
+    	    ddx_parser->intern((string) TEST_SRC_DIR
+    		    + "/ddx-testsuite/test.00.ddx", dds, blob);
+    	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+    	    CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+    	    CPPUNIT_ASSERT(dds->get_dap_minor() == 2);
+
+	    DBG(dds->print_xml(cout, false));
+
+	    string name = string(TEST_SRC_DIR) + "/ddx-testsuite/test.00.ddx";
+	    in = fopen(name.c_str(), "r");
+
+	    ddx_parser->intern_stream(in, dds, blob);
+
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+	    CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+	    CPPUNIT_ASSERT(dds->get_dap_minor() == 2);
+
+	    DBG(dds->print_xml(cout, false));
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.00.ddx failed.");
+	}
+
+	fclose(in);
+    }
+
+    void no_blob_version_32_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.0c.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+	    CPPUNIT_ASSERT(dds->get_dap_major() == 3);
+	    CPPUNIT_ASSERT(dds->get_dap_minor() == 2);
+
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.0c.ddx failed.");
+	}
+    }
+
+    void blob_in_version_32_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.0d.ddx", dds, blob);
+	    CPPUNIT_FAIL("Parsing test.0d.ddx should fail since it's a DAP 3.2 doc with a dataBLOB tag.");
+
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_ASSERT("test.0d.ddx failed as expected.");
+	}
+    }
+
+    void parsing_ddx_from_dataddx_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/DDX_from_dataddx.xml", dds, blob);
+	    CPPUNIT_ASSERT(true);
+	    DBG(dds->print_xml(cout, false));
+	}
+	catch (DDXParseFailed &e) {
+	    CPPUNIT_FAIL(e.get_error_message());
+	}
+
+    }
+
+    void top_level_attribute_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.01.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.01.ddx failed.");
+	}
+    }
+
+    void top_level_attribute_container_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.02.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.02.ddx failed.");
+	}
+    }
+
+    // ALiases are broken *** 05/29/03 jhrg
+    void top_level_attribute_alias_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.03.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.03.ddx failed.");
+	}
+    }
+
+    void top_level_simple_types_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.04.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "DDXParseFailed: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.04.ddx failed.");
+	}
+	catch (Error &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.04.ddx failed.");
+	}
+    }
+
+    void top_level_simple_types_with_attributes_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.05.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "SimpleTypes");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.05.ddx failed.");
+	}
+    }
+
+    void simple_arrays_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.06.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "OneDimensionalSimpleArrays");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.06.ddx failed.");
+	}
+    }
+
+    void simple_arrays_multi_dim_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.07.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "MultiDimensionalSimpleArrays");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.07.ddx failed.");
+	}
+    }
+
+    void simple_arrays_attributes_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.08.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.08.ddx failed.");
+	}
+    }
+
+    void structure_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.09.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.09.ddx failed.");
+	}
+    }
+
+    void sequence_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.0a.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.0a.ddx failed.");
+	}
+    }
+
+    void grid_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.0b.ddx", dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.0b.ddx failed.");
+	}
+    }
+
+    void intern_stream_test()
+    {
+	try {
+	    string file_name = (string) TEST_SRC_DIR
+		    + "/ddx-testsuite/test.0b.ddx";
+	    FILE *in = fopen(file_name.c_str(), "r");
+	    string blob;
+	    ddx_parser->intern_stream(in, dds, blob);
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "testdata");
+	    DBG(dds->print_xml(cout, false))
+	    ;
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << endl << "Error: " << e.get_error_message() << endl);
+	    CPPUNIT_FAIL("test.0b.ddx failed.");
+	}
+    }
+
+    // Error tests start here.
+
+    void unknown_tag_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.01.ddx", dds, blob);
+	    CPPUNIT_FAIL("error.01.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void bad_nesting_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.02.ddx", dds, blob);
+	    CPPUNIT_FAIL("error.02.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void unknown_end_tag_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.03.ddx", dds, blob);
+	    CPPUNIT_FAIL("error.03.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void variable_in_attribtue_container_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.04.ddx", dds, blob);
+	    CPPUNIT_FAIL("error.04.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void array_missing_dimension_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.05.ddx", dds, blob);
+	    CPPUNIT_FAIL("error.05.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void simple_type_missing_attribute_test()
+    {
+	try {
+	    string blob;
+	    ddx_parser->intern((string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.06.ddx", dds, blob);
+	    CPPUNIT_FAIL("error.06.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void array_missing_dimension_stream_read_test()
+    {
+	try {
+	    string file_name = (string) TEST_SRC_DIR
+		    + "/ddx-testsuite/error.05.ddx";
+	    FILE *in = fopen(file_name.c_str(), "r");
+	    string blob;
+	    ddx_parser->intern_stream(in, dds, blob);
+	    CPPUNIT_FAIL("error.05.ddx should fail!");
+	}
+	catch (DDXParseFailed &e) {
+	    DBG(cerr << "Error: " << e.get_error_message() << endl)
+	    ;
+	}
+    }
+
+    void intern_ddx_from_dataddx_test()
+    {
+	try {
+	    string file_name = (string) TEST_SRC_DIR
+		    + "/ddx-testsuite/dataddx_without_top_headers.dap";
+	    FILE *in = fopen(file_name.c_str(), "r");
+
+	    // First read the initial set of 'part' headers for the DDX
+	    read_multipart_headers(in, "text/xml", dap4_ddx);
+
+	    string blob;
+	    ddx_parser->intern_stream(in, dds, blob, "--boundary-string-1");
+	    CPPUNIT_ASSERT(dds->get_dataset_name() == "fnoc1.nc");
+
+	    DBG(dds->print_xml(cout, false));
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL(e.get_error_message());
+	}
+    }
+};
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION( DDXParserTest );
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return (wasSuccessful) ? 0 : 1;
+}
diff --git a/unit-tests/DODSFilterTest.cc b/unit-tests/DODSFilterTest.cc
new file mode 100644
index 0000000..e5445d3
--- /dev/null
+++ b/unit-tests/DODSFilterTest.cc
@@ -0,0 +1,571 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>  // for stat
+
+#include <cstring>
+#include <sstream>
+
+//#define DODS_DEBUG
+
+#include "DODSFilter.h"
+#include "DAS.h"
+#include "DDS.h"
+#include "GNURegex.h"
+#include "debug.h"
+
+#include "../tests/TestTypeFactory.h"
+#include "../tests/TestByte.h"
+
+#include <test_config.h>
+
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+int test_variable_sleep_interval = 0;
+
+namespace libdap {
+
+class DODSFilterTest : public TestFixture {
+private:
+    DODSFilter *df, *df_conditional, *df1, *df2, *df3, *df4, *df5, *df6;
+
+    AttrTable *cont_a;
+    DAS *das;
+    DDS *dds;
+    ostringstream oss;
+    time_t now;
+    char now_array[256];
+
+public:
+    DODSFilterTest() {
+	now = time(0);
+	ostringstream time_string;
+	time_string << (int)now;
+	strncpy(now_array, time_string.str().c_str(), 255);
+	now_array[255] = '\0';
+    }
+
+    ~DODSFilterTest() {}
+
+    void setUp() {
+	// Test pathname
+	string test_file = (string)TEST_SRC_DIR + "/server-testsuite/bears.data" ;
+	char *argv_1[] = {(char*)"test_case", (char *)test_file.c_str()};
+	df = new DODSFilter(2, argv_1);
+
+	char *argv_1_1[] = {(char*)"test_case", (char *)test_file.c_str(), (char*)"-l", &now_array[0]};
+	df_conditional = new DODSFilter(4, argv_1_1);
+
+	// Test missing file
+	argv_1[1] = (char*)"no-such-file";
+	df1 = new DODSFilter(2, argv_1);
+
+	// Test files in CWD. Note that the time is the GM time : Tue, 01 May
+	// 2001 01:08:14 -0700
+	argv_1[1] = (char*)"test_config.h";
+	df2 = new DODSFilter(2, argv_1);
+
+	// This file has an ancillary DAS in the server-testsuite dir.
+	// df3 is also used to test escaping stuff in URLs. 5/4/2001 jhrg
+	char *argv_2[8];
+	argv_2[0] = (char*)"test_case";
+	test_file = (string)TEST_SRC_DIR + "/server-testsuite/coads.data";
+	argv_2[1] = (char *)test_file.c_str();
+	argv_2[2] = (char*)"-l";
+	argv_2[3] = &now_array[0];
+	argv_2[4] = (char*)"-e";
+	argv_2[5] = (char*)"u,x,z[0]&grid(u,\"lat<10.0\")";
+	argv_2[6] = (char*)"-t";
+	argv_2[7] = (char*)"1";
+	df3 = new DODSFilter(6, argv_2);
+
+	// Go back to this data source to test w/o an ancillary DAS.
+	argv_2[0] = (char*)"test_case";
+	test_file = (string)TEST_SRC_DIR + "/server-testsuite/bears.data";
+	argv_2[1] = (char *)test_file.c_str();
+	argv_2[2] = (char*)"-l";
+	argv_2[3] = &now_array[0];
+	argv_2[4] = (char*)"-e";
+	argv_2[5] = (char*)"u,x,z[0]&grid(u,\"lat<10.0\")";
+	argv_2[6] = (char*)"-t";
+	argv_2[7] = (char*)"1";
+	df4 = new DODSFilter(6, argv_2);
+
+	// Test escaping stuff. 5/4/2001 jhrg
+	char *argv_3[]={(char*)"test_case", (char*)"nowhere%5Bmydisk%5Dmyfile", (char*)"-e", (char*)"u%5B0%5D"};
+	df5 = new DODSFilter(4, argv_3);
+
+	char *argv_4[]={(char*)"test_case", (char*)"nowhere%3a%5bmydisk%5dmyfile", (char*)"-e", (char*)"Grid%20field%3au%5b0%5d,Grid%20field%3av"};
+	df6 = new DODSFilter(4, argv_4);
+
+	cont_a = new AttrTable;
+	cont_a->append_attr("size", "Int32", "7");
+	cont_a->append_attr("type", "String", "cars");
+	das = new DAS;
+	das->add_table( "a", cont_a ) ;
+
+	// This AttrTable looks like:
+	//      Attributes {
+	//          a {
+	//              Int32 size 7;
+	//              String type cars;
+	//          }
+	//      }
+
+	TestTypeFactory ttf;
+	dds = new DDS(&ttf, "test");
+	TestByte a("a");
+	dds->add_var(&a);
+
+	dds->transfer_attributes(das);
+	dds->set_dap_major(3);
+	dds->set_dap_minor(2);
+    }
+
+    void tearDown() {
+	delete df; df = 0;
+	delete df_conditional; df_conditional = 0;
+	delete df1; df1 = 0;
+	delete df2; df2 = 0;
+	delete df3; df3 = 0;
+	delete df4; df4 = 0;
+	delete df5; df5 = 0;
+	delete df6; df6 = 0;
+
+	delete das; das = 0;
+    }
+
+    bool re_match(Regex &r, const string &s) {
+	DBG(cerr << "s.length(): " << s.length() << endl);
+	int pos = r.match(s.c_str(), s.length());
+	DBG(cerr << "r.match(s): " << pos << endl);
+	return pos > 0 && static_cast<unsigned>(pos) == s.length();
+    }
+
+    bool re_match_binary(Regex &r, const string &s) {
+	DBG(cerr << "s.length(): " << s.length() << endl);
+	int pos = r.match(s.c_str(), s.length());
+	DBG(cerr << "r.match(s): " << pos << endl);
+	return pos > 0;
+    }
+
+#if 0
+    void add_keyword_test() {
+	DODSFilter tdf;
+	tdf.add_keyword("test");
+	CPPUNIT_ASSERT(tdf.d_keywords.find("test") != tdf.d_keywords.end());
+	CPPUNIT_ASSERT(tdf.d_keywords.find("test") == tdf.d_keywords.begin());
+	CPPUNIT_ASSERT(*(tdf.d_keywords.find("test")) == string("test"));
+	tdf.add_keyword("dap3.3");
+	CPPUNIT_ASSERT(tdf.d_keywords.size() == 2);
+    }
+
+    void is_keyword_test() {
+	DODSFilter tdf;
+	tdf.add_keyword("test");
+	tdf.add_keyword("dap3.3");
+	CPPUNIT_ASSERT(tdf.is_keyword("test"));
+	CPPUNIT_ASSERT(!tdf.is_keyword("TEST"));
+    }
+
+    void get_keywords() {
+	DODSFilter tdf;
+	tdf.add_keyword("test");
+	tdf.add_keyword("dap2.0");
+	tdf.add_keyword("dap4.0");
+	CPPUNIT_ASSERT(tdf.d_keywords.size() == 3);
+
+	ostringstream oss;
+	list<string> kwds = tdf.get_keywords();
+	list<string>::iterator i = kwds.begin();
+	while (i != kwds.end())
+	    oss << *i++;
+	//cerr << oss.str() << endl;
+
+	CPPUNIT_ASSERT(oss.str().find("test") != string::npos);
+	CPPUNIT_ASSERT(oss.str().find("dap2.0") != string::npos);
+	CPPUNIT_ASSERT(oss.str().find("dap4.0") != string::npos);
+    }
+#endif
+
+    void get_dataset_last_modified_time_test() {
+	time_t t = time(0);
+	CPPUNIT_ASSERT(df1->get_dataset_last_modified_time() == t);
+
+	struct stat st;
+	string test_file = (string)TEST_SRC_DIR
+	                   + "/server-testsuite/bears.data";
+	stat(test_file.c_str(), &st);
+	CPPUNIT_ASSERT(df->get_dataset_last_modified_time() == st.st_mtime);
+
+	stat("test_config.h", &st);
+	CPPUNIT_ASSERT(df2->get_dataset_last_modified_time() == st.st_mtime);
+
+	test_file = (string)TEST_SRC_DIR + "/server-testsuite/coads.data";
+	stat(test_file.c_str(), &st);
+	CPPUNIT_ASSERT(df3->get_dataset_last_modified_time() == st.st_mtime);
+    }
+
+    void get_das_last_modified_time_test() {
+	// the dataset pointed to by df has no anc. DAS
+	struct stat st;
+	string test_file = (string)TEST_SRC_DIR
+	                   + "/server-testsuite/bears.data";
+	stat(test_file.c_str(), &st);
+	CPPUNIT_ASSERT(df->get_das_last_modified_time() == st.st_mtime);
+
+	// the dataset pointed by df3 has an anc. DAS
+	test_file = (string)TEST_SRC_DIR + "/server-testsuite/coads.data.das";
+	stat(test_file.c_str(), &st);
+	CPPUNIT_ASSERT(df3->get_das_last_modified_time() == st.st_mtime);
+    }
+
+    void send_das_test() {
+	Regex r1("HTTP/1.0 200 OK\r\n\
+XDODS-Server: .*\
+XOPeNDAP-Server: .*\
+XDAP: .*\
+Date: .*\
+Last-Modified: .*\
+Content-Type: text/plain\r\n\
+Content-Description: dods_das\r\n\
+\r\n\
+Attributes \\{\n\
+    a \\{\n\
+        Int32 size 7;\n\
+        String type \"cars\";\n\
+    \\}\n\
+\\}\n");
+
+	df->send_das(oss, *das);
+
+	DBG(cerr << "DAS: " << oss.str() << endl);
+
+	CPPUNIT_ASSERT(re_match(r1, oss.str()));
+	oss.str("");
+
+	Regex r2("HTTP/1.0 304 NOT MODIFIED\r\n\
+Date: .*\r\n\
+\r\n");
+
+	df_conditional->send_das(oss, *das);
+	CPPUNIT_ASSERT(re_match(r2, oss.str()));
+    }
+
+    void send_dds_test() {
+	Regex r1("HTTP/1.0 200 OK\r\n\
+XDODS-Server: .*\
+XOPeNDAP-Server: .*\
+XDAP: .*\
+Date: .*\
+Last-Modified: .*\
+Content-Type: text/plain\r\n\
+Content-Description: dods_dds\r\n\
+\r\n\
+Dataset \\{\n\
+    Byte a;\n\
+\\} test;\n");
+
+	ConstraintEvaluator ce;
+
+	df->send_dds(oss, *dds, ce);
+
+	DBG(cerr << "DDS: " << oss.str() << endl);
+
+	CPPUNIT_ASSERT(re_match(r1, oss.str()));
+	oss.str("");
+
+	Regex r2("HTTP/1.0 304 NOT MODIFIED\r\n\
+Date: .*\r\n\
+\r\n");
+
+	df_conditional->send_dds(oss, *dds, ce);
+	CPPUNIT_ASSERT(re_match(r2, oss.str()));
+    }
+
+    void send_ddx_test() {
+	Regex r1("HTTP/1.0 200 OK\r\n\
+XDODS-Server: .*\
+XOPeNDAP-Server: .*\
+XDAP: .*\
+Date: .*\
+Last-Modified: .*\
+Content-Type: text/xml\r\n\
+Content-Description: dap4-ddx\r\n\
+\r\n\
+<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>.*\
+<Dataset name=\"test\".*\
+.*\
+.*\
+.*\
+.*\
+.*\
+.*\
+dapVersion=\"3.2\">.*\
+.*\
+<Byte name=\"a\">.*\
+    <Attribute name=\"size\" type=\"Int32\">.*\
+        <value>7</value>.*\
+    </Attribute>.*\
+    <Attribute name=\"type\" type=\"String\">.*\
+        <value>cars</value>.*\
+    </Attribute>.*\
+</Byte>.*\
+.*\
+</Dataset>.*");
+
+	ConstraintEvaluator ce;
+
+	try {
+	    df->send_ddx(*dds, ce, oss);
+
+	    DBG(cerr << "DDX: " << oss.str() << endl);
+
+	    CPPUNIT_ASSERT(re_match(r1, oss.str()));
+	    oss.str("");
+
+	    Regex r2("HTTP/1.0 304 NOT MODIFIED\r\n\
+Date: .*\r\n\
+\r\n");
+
+	    df_conditional->send_ddx(*dds, ce, oss);
+	    CPPUNIT_ASSERT(re_match(r2, oss.str()));
+	}
+	catch(Error &e) {
+	    cerr << "Error (line 306): " << e.get_error_message() << endl;
+	}
+    }
+
+    void send_data_ddx_test() {
+	Regex r1("HTTP/1.0 200 OK\r\n\
+.*\
+XDAP:.*\r\n\
+.*\
+Content-Type: Multipart/Related; boundary=boundary; start=\"<start at opendap.org>\"; type=\"Text/xml\"\r\n\
+Content-Description: dap4-data-ddx\r\n\
+\r\n\
+--boundary\r\n\
+Content-Type: Text/xml; charset=iso-8859-1\r\n\
+Content-Id: <start at opendap.org>\r\n\
+Content-Description: dap4-ddx\r\n\
+\r\n\
+<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>.*\
+<Dataset name=\"test\".*\
+.*\
+dapVersion=\"3.2\">.*\
+.*\
+    <Byte name=\"a\">.*\
+        <Attribute name=\"size\" type=\"Int32\">.*\
+            <value>7</value>.*\
+        </Attribute>.*\
+        <Attribute name=\"type\" type=\"String\">.*\
+            <value>cars</value>.*\
+        </Attribute>.*\
+    </Byte>.*\
+.*\
+    <blob href=\"cid:.*@.*\"/>.*\
+</Dataset>.*\
+--boundary\r\n\
+Content-Type: application/octet-stream\r\n\
+Content-Id: <.*@.*>\r\n\
+Content-Description: dap4-data\r\n\
+Content-Encoding: binary\r\n\
+\r\n\
+.*");
+
+	// I do not look for the closing '--boundary' because the binary
+	// data breaks the regex functions in the c library WRT subsequent
+	// pattern matches. jhrg
+	//--boundary--\r\n");
+
+	ConstraintEvaluator ce;
+
+	try {
+	    df->send_data_ddx(*dds, ce, oss, "start at opendap.org", "boundary",
+		    "", true);
+
+	    DBG(cerr << "DataDDX: " << oss.str() << endl);
+
+	    CPPUNIT_ASSERT(re_match_binary(r1, oss.str()));
+	    oss.str("");
+
+	    Regex r2("HTTP/1.0 304 NOT MODIFIED\r\n\
+Date: .*\r\n\
+\r\n");
+
+	    df_conditional->send_data_ddx(*dds, ce, oss, "start at opendap.org",
+		    "boundary", "", true);
+	    CPPUNIT_ASSERT(re_match(r2, oss.str()));
+	}
+	catch(Error &e) {
+	    cerr << "Error (line 306): " << e.get_error_message() << endl;
+	}
+    }
+
+    void send_data_ddx_test2() {
+	Regex r1("--boundary\r\n\
+Content-Type: Text/xml; charset=iso-8859-1\r\n\
+Content-Id: <start at opendap.org>\r\n\
+Content-Description: dap4-ddx\r\n\
+\r\n\
+<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>.*\
+<Dataset name=\"test\".*\
+.*\
+dapVersion=\"3.2\">.*\
+.*\
+    <Byte name=\"a\">.*\
+        <Attribute name=\"size\" type=\"Int32\">.*\
+            <value>7</value>.*\
+        </Attribute>.*\
+        <Attribute name=\"type\" type=\"String\">.*\
+            <value>cars</value>.*\
+        </Attribute>.*\
+    </Byte>.*\
+.*\
+    <blob href=\"cid:.*@.*\"/>.*\
+</Dataset>.*\
+--boundary\r\n\
+Content-Type: application/octet-stream\r\n\
+Content-Id: <.*@.*>\r\n\
+Content-Description: dap4-data\r\n\
+Content-Encoding: binary\r\n\
+\r\n\
+.*");
+
+	ConstraintEvaluator ce;
+
+	try {
+	    df->send_data_ddx(*dds, ce, oss, "start at opendap.org", "boundary",
+		    "", false);
+	    DBG(cerr << "DataDDX: " << oss.str() << endl);
+	    CPPUNIT_ASSERT(re_match_binary(r1, oss.str()));
+
+	    // Unlike the test where the full headers are generated, there's
+	    // no check for a conditional response here because that feature
+	    // of DODSFilter is only supported when MIME headers are built by
+	    // the class. In order to return a '304' response, headers must be
+	    // built.
+	}
+	catch(Error &e) {
+	    cerr << "Error (line 306): " << e.get_error_message() << endl;
+	}
+    }
+
+    void is_conditional_test() {
+	CPPUNIT_ASSERT(df->is_conditional() == false);
+	CPPUNIT_ASSERT(df3->is_conditional() == true);
+    }
+
+    void get_request_if_modified_since_test() {
+	CPPUNIT_ASSERT(df->get_request_if_modified_since() == -1);
+	CPPUNIT_ASSERT(df3->get_request_if_modified_since() == now);
+    }
+
+    void escape_code_test() {
+	// These should NOT be escaped.
+
+	DBG(cerr << df3->get_dataset_name() << endl);
+	DBG(cerr << df3->get_ce() << endl);
+
+	CPPUNIT_ASSERT(df3->get_dataset_name() == (string)TEST_SRC_DIR + "/server-testsuite/coads.data");
+	CPPUNIT_ASSERT(df3->get_ce() == "u,x,z[0]&grid(u,\"lat<10.0\")");
+
+	// The DODSFIlter instance is feed escaped values; they should be
+	// unescaped by the ctor and the mutators. 5/4/2001 jhrg
+
+	DBG(cerr << df5->get_dataset_name() << endl);
+	DBG(cerr << df5->get_ce() << endl);
+
+	CPPUNIT_ASSERT(df5->get_dataset_name() == "nowhere[mydisk]myfile");
+	CPPUNIT_ASSERT(df5->get_ce() == "u[0]");
+
+	df5->set_ce("u%5B0%5D");
+	CPPUNIT_ASSERT(df5->get_ce() == "u[0]");
+
+	DBG(cerr << df6->get_dataset_name() << endl);
+	DBG(cerr << df6->get_ce() << endl);
+#if 0
+	CPPUNIT_ASSERT(df6->get_dataset_name() == "nowhere:[mydisk]myfile");
+	CPPUNIT_ASSERT(df6->get_ce() == "Grid%20field:u[0],Grid%20field:v");
+#endif
+	df5->set_ce("Grid%20u%5B0%5D");
+	CPPUNIT_ASSERT(df5->get_ce() == "Grid%20u[0]");
+    }
+
+    // This tests reading the timeout value from argv[].
+    void timeout_test() {
+	CPPUNIT_ASSERT(df3->get_timeout() == 1);
+	CPPUNIT_ASSERT(df1->get_timeout() == 0);
+    }
+
+    CPPUNIT_TEST_SUITE( DODSFilterTest );
+#if 0
+    CPPUNIT_TEST(add_keyword_test);
+    CPPUNIT_TEST(is_keyword_test);
+    CPPUNIT_TEST(get_keywords);
+#endif
+
+    CPPUNIT_TEST(get_dataset_last_modified_time_test);
+    CPPUNIT_TEST(get_das_last_modified_time_test);
+
+    CPPUNIT_TEST(send_das_test);
+    CPPUNIT_TEST(send_dds_test);
+
+    CPPUNIT_TEST(send_ddx_test);
+    CPPUNIT_TEST(send_data_ddx_test);
+    CPPUNIT_TEST(send_data_ddx_test2);
+
+    CPPUNIT_TEST(is_conditional_test);
+    CPPUNIT_TEST(get_request_if_modified_since_test);
+    CPPUNIT_TEST(escape_code_test);
+
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(DODSFilterTest);
+}
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
+
+
+
diff --git a/unit-tests/GridGeoConstraintTest.cc b/unit-tests/GridGeoConstraintTest.cc
new file mode 100644
index 0000000..3199688
--- /dev/null
+++ b/unit-tests/GridGeoConstraintTest.cc
@@ -0,0 +1,1312 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Tests for the AISResources class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+// #define DODS_DEBUG
+
+#include "BaseType.h"
+#include "Int32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Array.h"
+#include "Grid.h"
+#include "DDS.h"
+#include "DAS.h"
+#include "GridGeoConstraint.h"
+#include "ce_functions.h"
+
+#include "../tests/TestTypeFactory.h"
+
+#include "debug.h"
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace libdap;
+using namespace std;
+
+int test_variable_sleep_interval = 0;
+
+namespace libdap
+{
+
+class GridGeoConstraintTest:public TestFixture
+{
+private:
+    TestTypeFactory btf;
+    ConstraintEvaluator ce;
+
+    DDS *geo_dds;
+    DDS *geo_dds_3d;
+    DDS *geo_dds_coads_lon;
+
+public:
+    GridGeoConstraintTest()
+    {}
+    ~GridGeoConstraintTest()
+    {}
+
+    void setUp()
+    {
+        // geo grid test data
+        try {
+            geo_dds = new DDS(&btf);
+            geo_dds->parse((string)TEST_SRC_DIR + "/ce-functions-testsuite/geo_grid.dds");
+            DAS das;
+            das.parse((string)TEST_SRC_DIR + "/ce-functions-testsuite/geo_grid.das");
+            geo_dds->transfer_attributes(&das);
+
+            DBG2(geo_dds->print_xml(stderr, false, "No blob"));
+
+            // Load values into the grid variables
+            Grid & sst1 = dynamic_cast < Grid & >(*geo_dds->var("SST1"));
+
+            Array & lon1 = dynamic_cast < Array & >(**sst1.map_begin());
+            dods_float64 tmp_lon1[10] =
+                { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+            lon1.val2buf(tmp_lon1);
+            lon1.set_read_p(true);
+
+            Array & lat1 = dynamic_cast < Array & >(**(sst1.map_begin() + 1));
+            dods_float64 tmp_lat1[10] =
+                { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+            lat1.val2buf(tmp_lat1);
+            lat1.set_read_p(true);
+
+             dods_byte tmp_data[10][10] =
+                { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                  { 10,11,12,13,14,15,16,17,18,19},
+                  { 20,21,22,23,24,25,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} };
+            sst1.get_array()->val2buf((void*)tmp_data);
+            sst1.get_array()->set_read_p(true);
+
+            // Load values into the grid variables
+            Grid & sst1_1 = dynamic_cast < Grid & >(*geo_dds->var("SST1_1"));
+
+            Array & lat1_1 = dynamic_cast < Array & >(**sst1_1.map_begin());
+            dods_float64 tmp_lat1_1[10] =
+                { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+            lat1_1.val2buf(tmp_lat1_1);
+            lat1_1.set_read_p(true);
+
+            Array & lon1_1 = dynamic_cast < Array & >(**(sst1_1.map_begin() + 1));
+            dods_float64 tmp_lon1_1[10] =
+                { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+            lon1_1.val2buf(tmp_lon1_1);
+            lon1_1.set_read_p(true);
+
+            sst1_1.get_array()->val2buf((void*)tmp_data);
+            sst1_1.get_array()->set_read_p(true);
+
+            // Load values into the grid variables
+            Grid & sst2 = dynamic_cast < Grid & >(*geo_dds->var("SST2"));
+
+            Array & lon2 = dynamic_cast < Array & >(**sst2.map_begin());
+            dods_float64 tmp_lon2[10] =
+            //    { -180, -120, -80, -40, 0, 40, 80, 120, 160, 179 };
+		{ 0, 40, 80, 120, 160, -160, -120, -80, -40, -1};
+            lon2.val2buf(tmp_lon2);
+            lon2.set_read_p(true);
+            //unused BaseType *btp = lon2.var(0);
+            DBG2(cerr << "lon2[0]: " << dynamic_cast<Float64*>(btp)->value() << endl);
+
+            Array & lat2 = dynamic_cast < Array & >(**(sst2.map_begin() + 1));
+            dods_float64 tmp_lat2[10] =
+                { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+            lat2.val2buf(tmp_lat2);
+            lat2.set_read_p(true);
+
+            sst2.get_array()->val2buf((void*)tmp_data);
+            sst2.get_array()->set_read_p(true);
+
+            // Load values into the grid variables
+            Grid & sst3 = dynamic_cast < Grid & >(*geo_dds->var("SST3"));
+
+            Array & lat3 = dynamic_cast < Array & >(**sst3.map_begin());
+            dods_float64 tmp_lat3[10] =
+                { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+            lat3.val2buf(tmp_lat3);
+            lat3.set_read_p(true);
+
+            Array & lon3 = dynamic_cast < Array & >(**(sst3.map_begin() + 1));
+            dods_float64 tmp_lon3[10] =
+                { 20, 60, 100, 140, 180, 220, 260, 300, 340, 379 };
+            lon3.val2buf(tmp_lon3);
+            lon3.set_read_p(true);
+
+            sst3.get_array()->val2buf((void*)tmp_data);
+            sst3.get_array()->set_read_p(true);
+
+
+
+            // Build the three dimensional grid
+            geo_dds_3d = new DDS(&btf);
+            geo_dds_3d->parse((string)TEST_SRC_DIR + "/ce-functions-testsuite/geo_grid_3d.dds");
+            // Load values into the grid variables
+            Grid & sst4 = dynamic_cast < Grid & >(*geo_dds_3d->var("SST4"));
+
+            Array & time = dynamic_cast<Array&>(**sst4.map_begin());
+            dods_int32 tmp_time[3] = { 0, 1, 2 };
+            time.val2buf(tmp_time);
+            time.set_read_p(true);
+
+            Array & lon4 = dynamic_cast < Array & >(**(sst4.map_begin()+1));
+            dods_float64 tmp_lon4[5] = { 160, 200, 240, 280, 320 };
+            lon4.val2buf(tmp_lon4);
+            lon4.set_read_p(true);
+
+            Array & lat4 = dynamic_cast < Array & >(**(sst4.map_begin()+2));
+            dods_float64 tmp_lat4[5] = { 40, 30, 20, 10, 0 };
+            lat4.val2buf(tmp_lat4);
+            lat4.set_read_p(true);
+
+            dods_byte tmp_data4[3][5][5] =
+                {
+                    { { 0, 1, 2, 3, 4},
+                      { 10,11,12,13,14},
+                      { 20,21,22,23,24},
+                      { 30,31,32,33,34},
+                      { 40,41,42,43,44}  },
+                    { { 100, 101, 102, 103, 104},
+                      { 110, 111, 112, 113, 114},
+                      { 120, 121, 122, 123, 124},
+                      { 130, 131, 132, 133, 134},
+                      { 140, 141, 142, 143, 144}  },
+                    { { 200, 201, 202, 203, 204},
+                      { 210, 211, 212, 213, 214},
+                      { 220, 221, 222, 223, 224},
+                      { 230, 231, 232, 233, 234},
+                      { 240, 241, 242, 243, 244}  }
+                };
+            sst4.get_array()->val2buf((void*)tmp_data4);
+            sst4.get_array()->set_read_p(true);
+
+            DBG2(sst4.print_val(stderr));
+
+            geo_dds_coads_lon = new DDS(&btf);
+            geo_dds_coads_lon->parse((string)TEST_SRC_DIR + "/ce-functions-testsuite/geo_grid_coads_lon.dds");
+            Grid & sst5 = dynamic_cast < Grid & >(*geo_dds_coads_lon->var("SST5"));
+            Array & lon5 = dynamic_cast < Array & >(**sst5.map_begin());
+            dods_float64 tmp_lon5[15] =
+                { 41, 81, 121, 161, 201, 241, 281, 321, 361, 365, 370, 375, 380, 385, 390 };
+            lon5.val2buf(tmp_lon5);
+            lon5.set_read_p(true);
+
+            Array & lat5 = dynamic_cast < Array & >(**(sst5.map_begin() + 1));
+            dods_float64 tmp_lat5[5] = { 20, 10, 0, -10, -20 };
+            lat5.val2buf(tmp_lat5);
+            lat5.set_read_p(true);
+
+            dods_byte tmp_data5[15][5] =
+                { { 0, 1, 2, 3, 4},
+                  { 10,11,12,13,14},
+                  { 20,21,22,23,24},
+                  { 30,31,32,33,34},
+                  { 40,41,42,43,44},
+                  { 100, 101, 102, 103, 104},
+                  { 110, 111, 112, 113, 114},
+                  { 120, 121, 122, 123, 124},
+                  { 130, 131, 132, 133, 134},
+                  { 140, 141, 142, 143, 144},
+                  { 200, 201, 202, 203, 204},
+                  { 210, 211, 212, 213, 214},
+                  { 220, 221, 222, 223, 224},
+                  { 230, 231, 232, 233, 234},
+                  { 240, 241, 242, 243, 244}  } ;
+            sst5.get_array()->val2buf((void*)tmp_data5);
+            sst5.get_array()->set_read_p(true);
+            DBG2(sst5.print_val(stderr));
+        }
+
+        catch (Error & e) {
+            cerr << "SetUp: " << e.get_error_message() << endl;
+            throw;
+        }
+    }
+
+    void tearDown()
+    {
+        delete geo_dds;
+    delete geo_dds_3d;
+    delete geo_dds_coads_lon;
+
+    }
+
+    CPPUNIT_TEST_SUITE( GridGeoConstraintTest );
+
+#if 1
+    CPPUNIT_TEST(geoconstraint_build_lat_lon_maps_test);
+    CPPUNIT_TEST(lat_lon_dimensions_ok_test);
+    CPPUNIT_TEST(transform_longitude_to_pos_notation_test);
+    CPPUNIT_TEST(find_longitude_indeces_test);
+    CPPUNIT_TEST(categorize_latitude_test);
+    CPPUNIT_TEST(find_latitude_indeces_test);
+    CPPUNIT_TEST(set_array_using_double_test);
+    CPPUNIT_TEST(reorder_longitude_map_test);
+    // See the comment at the function...
+    // CPPUNIT_TEST(reorder_data_longitude_axis_test);
+    CPPUNIT_TEST(set_bounding_box_test1);
+    CPPUNIT_TEST(set_bounding_box_test2);
+    CPPUNIT_TEST(set_bounding_box_test3);
+    CPPUNIT_TEST(set_bounding_box_test4);
+    CPPUNIT_TEST(set_bounding_box_test5);
+    CPPUNIT_TEST(set_bounding_box_test6);
+    CPPUNIT_TEST(set_bounding_box_test7);
+    CPPUNIT_TEST(apply_constriant_to_data_test);
+    CPPUNIT_TEST(apply_constriant_to_data_test2);
+    CPPUNIT_TEST(apply_constriant_to_data_test3);
+    CPPUNIT_TEST(apply_constriant_to_data_test4);
+#endif
+    CPPUNIT_TEST(apply_constriant_to_data_test_three_arg);
+    CPPUNIT_TEST(apply_constriant_to_data_test2_three_arg);
+    CPPUNIT_TEST(apply_constriant_to_data_test3_three_arg);
+    CPPUNIT_TEST(apply_constriant_to_data_test4_three_arg);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void geoconstraint_build_lat_lon_maps_test()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc1(g);
+            CPPUNIT_ASSERT(gc1.build_lat_lon_maps());
+
+            g = dynamic_cast<Grid*>(geo_dds->var("SST2"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc2(g);
+            CPPUNIT_ASSERT(gc2.build_lat_lon_maps());
+
+            g = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc3(g);
+            CPPUNIT_ASSERT(gc3.build_lat_lon_maps());
+
+            g = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc4(g);
+            CPPUNIT_ASSERT(gc4.build_lat_lon_maps());
+            CPPUNIT_ASSERT(gc4.d_latitude == *(g->map_begin()+2));
+            CPPUNIT_ASSERT(gc4.d_longitude == *(g->map_begin()+1));
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"build_lat_lon_maps_test() failed");
+        }
+    }
+
+    void lat_lon_dimensions_ok_test()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc1(g);
+            CPPUNIT_ASSERT(gc1.build_lat_lon_maps());
+            CPPUNIT_ASSERT(gc1.lat_lon_dimensions_ok());
+            CPPUNIT_ASSERT(gc1.is_longitude_rightmost() == false);
+
+            Grid *g3 = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+            CPPUNIT_ASSERT(g3);
+            GridGeoConstraint gc3(g3);
+            CPPUNIT_ASSERT(gc3.build_lat_lon_maps());
+            CPPUNIT_ASSERT(gc3.lat_lon_dimensions_ok());
+            CPPUNIT_ASSERT(gc3.is_longitude_rightmost() == true);
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"lat_lon_dimensions_ok_test() failed");
+        }
+    }
+
+    void transform_longitude_to_pos_notation_test()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST2"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc2(g);
+            CPPUNIT_ASSERT(gc2.build_lat_lon_maps());
+
+            CPPUNIT_ASSERT(gc2.d_lon[0] == 0);
+            CPPUNIT_ASSERT(gc2.d_lon[gc2.d_lon_length-1] == -1);
+
+            GeoConstraint::Notation map_notation
+            = gc2.categorize_notation(gc2.d_lon[0], gc2.d_lon[gc2.d_lon_length-1]);
+            CPPUNIT_ASSERT(map_notation == GeoConstraint::neg_pos);
+
+            gc2.transform_longitude_to_pos_notation();
+            DBG(cerr << "gc2.d_lon[0]: " << gc2.d_lon[0] << endl);
+            CPPUNIT_ASSERT(gc2.d_lon[0] == 0);
+            DBG(cerr << "gc2.d_lon[gc2.d_lon_length-1]: " << gc2.d_lon[gc2.d_lon_length-1] << endl);
+            CPPUNIT_ASSERT(gc2.d_lon[gc2.d_lon_length-1] == 359);
+
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"transform_map_to_pos_notation_test() failed");
+        }
+    }
+
+    void find_longitude_indeces_test()
+    {
+	try {
+	    //  { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+        Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc1(g);
+
+        int left_i, right_i;
+        gc1.find_longitude_indeces(40.0, 200.0, left_i, right_i);
+        CPPUNIT_ASSERT(left_i == 1);
+        CPPUNIT_ASSERT(right_i == 5);
+
+        g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc2(g);
+
+        gc2.find_longitude_indeces(200, 40.0, left_i, right_i);
+        CPPUNIT_ASSERT(left_i == 5);
+        CPPUNIT_ASSERT(right_i == 1);
+
+        g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc3(g);
+
+        gc3.find_longitude_indeces(5.0, 81.0, left_i, right_i);
+        DBG(cerr << "left_i: " << left_i << endl);
+        DBG(cerr << "right_i: " << right_i << endl);
+        CPPUNIT_ASSERT(left_i == 0);
+        CPPUNIT_ASSERT(right_i == 3);
+
+        g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc4(g);
+
+        gc4.find_longitude_indeces(81.0, 5.0, left_i, right_i);
+        DBG(cerr << "left_i: " << left_i << endl);
+        DBG(cerr << "right_i: " << right_i << endl);
+        CPPUNIT_ASSERT(left_i == 2);
+        CPPUNIT_ASSERT(right_i == 1);
+
+	    // lon: { 41, 81, 121, 161, 201, 241, 281, 321, 361, 365, 370, 375, 380, 385, 390 };
+        g = dynamic_cast<Grid*>(geo_dds_coads_lon->var("SST5"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc5(g);
+
+        gc5.find_longitude_indeces(5.0, 81.0, left_i, right_i);
+        DBG(cerr << "left_i: " << left_i << endl);
+        DBG(cerr << "right_i: " << right_i << endl);
+        CPPUNIT_ASSERT(left_i == 9);
+        CPPUNIT_ASSERT(right_i == 1);
+
+        g = dynamic_cast<Grid*>(geo_dds_coads_lon->var("SST5"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc6(g);
+
+        gc6.find_longitude_indeces(81.0, 5.0, left_i, right_i);
+        DBG(cerr << "left_i: " << left_i << endl);
+        DBG(cerr << "right_i: " << right_i << endl);
+        CPPUNIT_ASSERT(left_i == 1);
+        CPPUNIT_ASSERT(right_i == 9);
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL(e.get_error_message());
+	}
+    }
+
+    void categorize_latitude_test()
+    {
+        Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc1(g);
+
+        CPPUNIT_ASSERT(gc1.categorize_latitude() == GeoConstraint::normal);
+
+        Grid *g3 = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+        CPPUNIT_ASSERT(g3);
+        GridGeoConstraint gc3(g3);
+
+        CPPUNIT_ASSERT(gc3.categorize_latitude() == GeoConstraint::inverted);
+    }
+
+    void find_latitude_indeces_test()
+    {
+        // SST1 lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+        Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        int top_i, bottom_i;
+
+        CPPUNIT_ASSERT(g);
+
+        GridGeoConstraint gc0(g);
+        gc0.find_latitude_indeces(20, -20, GeoConstraint::normal, top_i, bottom_i);
+        DBG(cerr << "SST1, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 2);
+        CPPUNIT_ASSERT(bottom_i == 6);
+
+        // SST1 lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+        GridGeoConstraint gc1(g);
+        gc1.find_latitude_indeces(35, 5, GeoConstraint::normal, top_i, bottom_i);
+        DBG(cerr << "SST1, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 0);
+        CPPUNIT_ASSERT(bottom_i == 4);
+
+        // SST1 lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+        GridGeoConstraint gc2(g);
+        gc2.find_latitude_indeces(25, -25, GeoConstraint::normal, top_i, bottom_i);
+        DBG(cerr << "SST1, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 1);
+        CPPUNIT_ASSERT(bottom_i == 7);
+
+        // SST1 lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+        GridGeoConstraint gc3(g);
+        gc3.find_latitude_indeces(-15, -35, GeoConstraint::normal, top_i, bottom_i);
+        DBG(cerr << "SST1, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 5);
+        CPPUNIT_ASSERT(bottom_i == 8);
+
+        // SST3 lat: { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+        g = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+        CPPUNIT_ASSERT(g);
+
+        GridGeoConstraint gc4(g);
+        gc4.find_latitude_indeces(20, -20, GeoConstraint::inverted, top_i, bottom_i);
+        DBG(cerr << "SST3, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 6);
+        CPPUNIT_ASSERT(bottom_i == 2);
+
+        // SST3 lat: { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+        GridGeoConstraint gc5(g);
+        gc5.find_latitude_indeces(35, 5, GeoConstraint::inverted, top_i, bottom_i);
+        DBG(cerr << "SST3, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 8);
+        CPPUNIT_ASSERT(bottom_i == 4);
+
+        // SST3 lat: { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+        GridGeoConstraint gc6(g);
+        gc6.find_latitude_indeces(-5, -35, GeoConstraint::inverted, top_i, bottom_i);
+        DBG(cerr << "SST3, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 4);
+        CPPUNIT_ASSERT(bottom_i == 0);
+
+        // SST3 lat: { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+        GridGeoConstraint gc7(g);
+        gc7.find_latitude_indeces(25, -25, GeoConstraint::inverted, top_i, bottom_i);
+        DBG(cerr << "SST3, top: " << top_i << ", bottom: " << bottom_i << endl);
+        CPPUNIT_ASSERT(top_i == 7);
+        CPPUNIT_ASSERT(bottom_i == 1);
+    }
+
+    void set_array_using_double_test()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            Array *lon = dynamic_cast<Array*>(*g->map_begin());
+            double ten_values[10] = {-1,1,2,3,4,5,6,7,8,9};
+            set_array_using_double(lon, ten_values, 10);
+            CPPUNIT_ASSERT(extract_double_value(lon->var(0)) == ten_values[0]);
+            CPPUNIT_ASSERT(extract_double_value(lon->var(9)) == ten_values[9]);
+
+            Int32 *i = new Int32("");
+            Array *a = new Array("", i);
+            a->append_dim(10);
+            int dummy_values[10] = {10,11,12,13,14,15,16,17,18,19};
+            a->val2buf((void*)dummy_values);
+            a->set_read_p(true);
+            CPPUNIT_ASSERT(extract_double_value(a->var(0)) == 10.0);
+            CPPUNIT_ASSERT(extract_double_value(a->var(9)) == 19.0);
+            set_array_using_double(a, ten_values, 10);
+            CPPUNIT_ASSERT(extract_double_value(a->var(0)) == ten_values[0]);
+            CPPUNIT_ASSERT(extract_double_value(a->var(9)) == ten_values[9]);
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in set_array_using_double_test.");
+        }
+    }
+
+    void reorder_longitude_map_test()
+    {
+        Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+        CPPUNIT_ASSERT(g);
+        GridGeoConstraint gc1(g);
+        // Longitude map: { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 }
+
+        gc1.reorder_longitude_map(7);
+
+        CPPUNIT_ASSERT(gc1.d_lon[0] == 280);
+        CPPUNIT_ASSERT(gc1.d_lon[2] == 359);
+        CPPUNIT_ASSERT(gc1.d_lon[3] == 0);
+        CPPUNIT_ASSERT(gc1.d_lon[6] == 120);
+        CPPUNIT_ASSERT(gc1.d_lon[9] == 240);
+    }
+#if 0
+    // This test is broken because reorder...() uses read and I haven't worked
+    // out how to get the data used here into the grid so that read() called
+    // elsewhere will return it. Might try using the series_values property to
+    // create a predictable set of values...
+    void reorder_data_longitude_axis_test()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc1(g);
+            /* Data values for Grid SST1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+            gc1.d_longitude_index_left = 5;
+            gc1.d_longitude_index_right = 1;
+
+            cerr << "Before gc1.reorder_data_longitude_axis();" << endl;
+            gc1.reorder_data_longitude_axis();
+            cerr << "past gc1.reorder_data_longitude_axis();" << endl;
+
+            // Read the data out into local storage
+            dods_byte *tmp_data2=0;
+            dods_byte **tmp_data2_ptr = &tmp_data2;
+            int size = g->get_array()->buf2val((void**)tmp_data2_ptr);
+            cerr << "size = " << size << endl;
+
+            cerr << "tmp_data2[0]: " << (int)tmp_data2[0] << endl;
+            CPPUNIT_ASSERT(tmp_data2[0] == 5);
+            CPPUNIT_ASSERT(tmp_data2[9] == 4);
+            CPPUNIT_ASSERT(tmp_data2[10] == 15);
+            CPPUNIT_ASSERT(tmp_data2[90] == 95);
+            CPPUNIT_ASSERT(tmp_data2[99] == 94);
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in reorder_data_longitude_axis_test.");
+        }
+    }
+#endif
+
+    void set_bounding_box_test1()
+    {
+        try {
+            // SST1 uses pos notation; constraint uses pos
+            Grid *g = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g);
+            GridGeoConstraint gc1(g);
+            // lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+            // This should be lon 1 to 5 and lat 0 to 3
+            gc1.set_bounding_box(40.0, 40.0, 10.0, 200.0);
+
+            CPPUNIT_ASSERT(gc1.d_longitude_index_left == 1);
+            CPPUNIT_ASSERT(gc1.d_longitude_index_right == 5);
+
+            CPPUNIT_ASSERT(gc1.d_latitude_index_top == 0);
+            CPPUNIT_ASSERT(gc1.d_latitude_index_bottom == 3);
+
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in set_bounding_box_test.");
+        }
+    }
+
+    void set_bounding_box_test2()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g2);
+            GridGeoConstraint gc2(g2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            gc2.set_bounding_box(40.0, 40.0, 10.0, -160.0);
+            CPPUNIT_ASSERT(gc2.d_longitude_index_left == 1);
+            CPPUNIT_ASSERT(gc2.d_longitude_index_right == 5);
+
+            CPPUNIT_ASSERT(gc2.d_latitude_index_top == 0);
+            CPPUNIT_ASSERT(gc2.d_latitude_index_bottom == 3);
+
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in set_bounding_box_test.");
+        }
+    }
+
+    void set_bounding_box_test3()
+    {
+        try {
+            Grid *g3 = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g3);
+            GridGeoConstraint gc3(g3);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            gc3.set_bounding_box(30.0, 200.0, 20.0, 280.0);
+            CPPUNIT_ASSERT(gc3.d_longitude_index_left == 1);
+            CPPUNIT_ASSERT(gc3.d_longitude_index_right == 3);
+
+            CPPUNIT_ASSERT(gc3.d_latitude_index_top == 1);
+            CPPUNIT_ASSERT(gc3.d_latitude_index_bottom == 2);
+
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in set_bounding_box_test.");
+        }
+    }
+
+    void set_bounding_box_test4()
+    {
+        // lon: { 160, 200, 240, 280, 320 }
+        // lat: { 40, 30, 20, 10, 0 }
+        try {
+            Grid *g3 = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g3);
+            GridGeoConstraint gc3(g3);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            gc3.set_bounding_box(30.0, 0, 20.0, 150);
+            CPPUNIT_ASSERT(!"Should fail since the BB box contains no data");
+
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT("Caught Error.");
+        }
+    }
+
+    void set_bounding_box_test5()
+    {
+        // lon: { 160, 200, 240, 280, 320 }
+        // lat: { 40, 30, 20, 10, 0 }
+        try {
+            Grid *g3 = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g3);
+            GridGeoConstraint gc3(g3);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            gc3.set_bounding_box(30.0, 0, 20.0, 170);
+            CPPUNIT_ASSERT("Should not fail since the BB box contains data");
+
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Should not throw Error.");
+        }
+    }
+
+    void set_bounding_box_test6()
+    {
+        // lon: { 160, 200, 240, 280, 320 }
+        // lat: { 40, 30, 20, 10, 0 }
+        try {
+            Grid *g3 = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g3);
+            GridGeoConstraint gc3(g3);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            gc3.set_bounding_box(60.0, 170, 50.0, 270);
+            CPPUNIT_FAIL("Should fail since the BB box contains no data");
+
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Cought Error.");
+        }
+    }
+
+    void set_bounding_box_test7()
+    {
+        // lon: 20 --> 359
+        // lat: { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+        try {
+            Grid *g3 = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+            CPPUNIT_ASSERT(g3);
+            GridGeoConstraint gc3(g3);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            gc3.set_bounding_box(70.0, 170, 60.0, 270);
+            CPPUNIT_ASSERT(!"Should fail since the BB box contains no data");
+
+        }
+        catch (Error &e) {
+            DBG(cerr << "Error: " << e.get_error_message() << endl);
+            CPPUNIT_ASSERT("Cought Error.");
+        }
+    }
+
+    void apply_constriant_to_data_test()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g2);
+            g2->set_send_p(true);
+
+            DBG(g2->print_decl(cerr, "    ", true, false, true));
+            DBG(g2->print_val(cerr, "    ", false));
+            DBG(cerr << endl << endl);
+
+            GridGeoConstraint gc2(g2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint lat from 5 to 8 and
+            // from lon 1 to 5
+            gc2.set_bounding_box(30, 40, 10, 120);
+
+            /* lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+               lon: { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+
+               Data values for Grid SST1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+
+            gc2.apply_constraint_to_data();
+
+            CPPUNIT_ASSERT(gc2.d_latitude->length() == 3);
+            CPPUNIT_ASSERT(gc2.d_longitude->length() == 3);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc2.d_latitude->buf2val((void**)lats_ptr);
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+            CPPUNIT_ASSERT(lats[2] == 10.0);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc2.d_longitude->buf2val((void**)lons_ptr);
+            CPPUNIT_ASSERT(lons[0] == 40.0);
+            CPPUNIT_ASSERT(lons[2] == 120.0);
+
+            DBG(gc2.get_constrained_grid()->print_decl(cerr, "    ", true, false, true));
+            DBG(gc2.get_constrained_grid()->print_val(cerr, "    ", false));
+            DBG(cerr << endl << endl);
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+    }
+
+    void apply_constriant_to_data_test_three_arg()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST1"));
+            CPPUNIT_ASSERT(g2);
+            g2->set_send_p(true);
+
+            DBG(g2->print_decl(cerr, "    ", true, false, true));
+            DBG(g2->print_val(cerr, "    ", false));
+            DBG(cerr << endl << endl);
+
+            Array *lat2 = dynamic_cast<Array*>(geo_dds->var("SST1.lat"));
+            CPPUNIT_ASSERT(lat2);
+            Array *lon2 = dynamic_cast<Array*>(geo_dds->var("SST1.lon"));
+            CPPUNIT_ASSERT(lon2);
+
+            GridGeoConstraint gc2(g2, lat2, lon2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint lat from 5 to 8 and
+            // from lon 1 to 5
+            gc2.set_bounding_box(30, 40, 10, 120);
+
+            /* lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+               lon: { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+
+               Data values for Grid SST1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+
+            gc2.apply_constraint_to_data();
+
+            CPPUNIT_ASSERT(gc2.d_latitude->length() == 3);
+            CPPUNIT_ASSERT(gc2.d_longitude->length() == 3);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc2.d_latitude->buf2val((void**)lats_ptr);
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+            CPPUNIT_ASSERT(lats[2] == 10.0);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc2.d_longitude->buf2val((void**)lons_ptr);
+            CPPUNIT_ASSERT(lons[0] == 40.0);
+            CPPUNIT_ASSERT(lons[2] == 120.0);
+
+            DBG(gc2.get_constrained_grid()->print_decl(cerr, "    ", true, false, true));
+            DBG(gc2.get_constrained_grid()->print_val(cerr, "    ", false));
+            DBG(cerr << endl << endl);
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+    }
+
+    void apply_constriant_to_data_test2()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g);
+            g->set_send_p(true);
+
+            GridGeoConstraint gc(g);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint from lon 1 to 5 and lat from
+            // 5 to 8
+            gc.set_bounding_box(30.0, 200.0, 20.0, 280.0);
+
+            /* time[3] = { 0, 1, 2 };
+               lon4[5] = { 160, 200, 240, 280, 320 };
+               lat4[5] = { 40, 30, 20, 10, 0 };
+                dods_byte tmp_data4[3][5][5] =
+                    {
+                      { { 0, 1, 2, 3, 4},
+                        { 10,11,12,13,14},
+                        { 20,21,22,23,24},
+                        { 30,31,32,33,34},
+                        { 40,41,42,43,44}  },
+                      { { 100, 101, 102, 103, 104},
+                        { 110, 111, 112, 113, 114},
+                        { 120, 121, 122, 123, 124},
+                        { 130, 131, 132, 133, 134},
+                        { 140, 141, 142, 143, 144}  },
+                      { { 200, 201, 202, 203, 204},
+                        { 210, 211, 212, 213, 214},
+                        { 220, 221, 222, 223, 224},
+                        { 230, 231, 232, 233, 234},
+                        { 240, 241, 242, 243, 244}  }
+                    };
+            */
+
+            gc.apply_constraint_to_data();
+
+            CPPUNIT_ASSERT(gc.d_latitude->length() == 2);
+            CPPUNIT_ASSERT(gc.d_longitude->length() == 3);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc.d_latitude->buf2val((void**)lats_ptr);
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+            CPPUNIT_ASSERT(lats[1] == 20.0);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc.d_longitude->buf2val((void**)lons_ptr);
+            CPPUNIT_ASSERT(lons[0] == 200.0);
+            CPPUNIT_ASSERT(lons[2] == 280.0);
+#ifdef DODS_DEBUG
+            gc.get_constrained_grid()->print_decl(cerr, "    ", true, false, true);
+            gc.get_constrained_grid()->print_val(cerr, "    ", false);
+            cerr << endl << endl;
+#endif
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"apply_constriant_to_data_test caught Error");
+        }
+    }
+
+    void apply_constriant_to_data_test2_three_arg()
+    {
+        try {
+            Grid *g = dynamic_cast<Grid*>(geo_dds_3d->var("SST4"));
+            CPPUNIT_ASSERT(g);
+            g->set_send_p(true);
+
+            Array *lat = dynamic_cast<Array*>(geo_dds_3d->var("SST4.lat"));
+            CPPUNIT_ASSERT(lat);
+            Array *lon = dynamic_cast<Array*>(geo_dds_3d->var("SST4.lon"));
+            CPPUNIT_ASSERT(lon);
+
+            GridGeoConstraint gc(g, lat, lon);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint from lon 1 to 5 and lat from
+            // 5 to 8
+            gc.set_bounding_box(30.0, 200.0, 20.0, 280.0);
+
+            /* time[3] = { 0, 1, 2 };
+               lon4[5] = { 160, 200, 240, 280, 320 };
+               lat4[5] = { 40, 30, 20, 10, 0 };
+                dods_byte tmp_data4[3][5][5] =
+                    {
+                      { { 0, 1, 2, 3, 4},
+                        { 10,11,12,13,14},
+                        { 20,21,22,23,24},
+                        { 30,31,32,33,34},
+                        { 40,41,42,43,44}  },
+                      { { 100, 101, 102, 103, 104},
+                        { 110, 111, 112, 113, 114},
+                        { 120, 121, 122, 123, 124},
+                        { 130, 131, 132, 133, 134},
+                        { 140, 141, 142, 143, 144}  },
+                      { { 200, 201, 202, 203, 204},
+                        { 210, 211, 212, 213, 214},
+                        { 220, 221, 222, 223, 224},
+                        { 230, 231, 232, 233, 234},
+                        { 240, 241, 242, 243, 244}  }
+                    };
+            */
+
+            gc.apply_constraint_to_data();
+
+            CPPUNIT_ASSERT(gc.d_latitude->length() == 2);
+            CPPUNIT_ASSERT(gc.d_longitude->length() == 3);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc.d_latitude->buf2val((void**)lats_ptr);
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+            CPPUNIT_ASSERT(lats[1] == 20.0);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc.d_longitude->buf2val((void**)lons_ptr);
+            CPPUNIT_ASSERT(lons[0] == 200.0);
+            CPPUNIT_ASSERT(lons[2] == 280.0);
+#ifdef DODS_DEBUG
+            gc.get_constrained_grid()->print_decl(cerr, "    ", true, false, true);
+            gc.get_constrained_grid()->print_val(cerr, "    ", false);
+            cerr << endl << endl;
+#endif
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"apply_constriant_to_data_test caught Error");
+        }
+    }
+
+    // This tests the 'stitch' feature of the GridGeoConstraint/GeoConstraint
+    void apply_constriant_to_data_test3()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+            CPPUNIT_ASSERT(g2);
+            g2->set_send_p(true);
+
+            GridGeoConstraint gc2(g2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint lat from 5 to 8 and
+            // from lon 1 to 5
+            gc2.set_bounding_box(30, 300, 30, 60);
+
+            /* lat:  { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+               lon: { 20, 60, 100, 140, 180, 220, 260, 300, 340, 379 };
+
+               Data values for Grid SST1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+
+            gc2.apply_constraint_to_data();
+
+            DBG(cerr << "gc2.d_latitude->length(): " << gc2.d_latitude->length() << endl);
+            DBG(cerr << "gc2.d_longitude->length(): " << gc2.d_longitude->length() << endl);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc2.d_latitude->buf2val((void**)lats_ptr);
+            DBG(cerr << "lats[0]: " << lats[0] << endl);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc2.d_longitude->buf2val((void**)lons_ptr);
+            DBG(cerr << "lons[0]: " << lons[0] << endl);
+            DBG(cerr << "lons[gc2.d_longitude->length()-1]: " << lons[gc2.d_longitude->length()-1] << endl);
+            //CPPUNIT_ASSERT(lons[0] == 260.0);
+            //CPPUNIT_ASSERT(lons[4] == 20.0);
+
+            CPPUNIT_ASSERT(gc2.d_latitude->length() == 1);
+            CPPUNIT_ASSERT(gc2.d_longitude->length() == 5);
+
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+
+            CPPUNIT_ASSERT(lons[0] == 300.0);
+            CPPUNIT_ASSERT(lons[4] == 60.0);
+#ifdef DODS_DEBUG
+            gc2.get_constrained_grid()->print_decl(cerr, "    ", true, false, true);
+            gc2.get_constrained_grid()->print_val(cerr, "    ", false);
+            cerr << endl << endl;
+#endif
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+    }
+
+    // This tests the 'stitch' feature of the GridGeoConstraint/GeoConstraint
+    void apply_constriant_to_data_test3_three_arg()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST3"));
+            CPPUNIT_ASSERT(g2);
+            g2->set_send_p(true);
+
+            Array *lat2 = dynamic_cast<Array*>(geo_dds->var("SST3.lat"));
+            CPPUNIT_ASSERT(lat2);
+            Array *lon2 = dynamic_cast<Array*>(geo_dds->var("SST3.lon"));
+            CPPUNIT_ASSERT(lon2);
+
+            GridGeoConstraint gc2(g2, lat2, lon2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint lat from 5 to 8 and
+            // from lon 1 to 5
+            gc2.set_bounding_box(30, 300, 30, 60);
+
+            /* lat:  { -40, -30, -20, -10, 0, 10, 20, 30, 40, 50 };
+               lon: { 20, 60, 100, 140, 180, 220, 260, 300, 340, 379 };
+
+               Data values for Grid SST1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+
+            gc2.apply_constraint_to_data();
+
+            DBG(cerr << "gc2.d_latitude->length(): " << gc2.d_latitude->length() << endl);
+            DBG(cerr << "gc2.d_longitude->length(): " << gc2.d_longitude->length() << endl);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc2.d_latitude->buf2val((void**)lats_ptr);
+            DBG(cerr << "lats[0]: " << lats[0] << endl);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc2.d_longitude->buf2val((void**)lons_ptr);
+            DBG(cerr << "lons[0]: " << lons[0] << endl);
+            DBG(cerr << "lons[gc2.d_longitude->length()-1]: " << lons[gc2.d_longitude->length()-1] << endl);
+            //CPPUNIT_ASSERT(lons[0] == 260.0);
+            //CPPUNIT_ASSERT(lons[4] == 20.0);
+
+            CPPUNIT_ASSERT(gc2.d_latitude->length() == 1);
+            CPPUNIT_ASSERT(gc2.d_longitude->length() == 5);
+
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+
+            CPPUNIT_ASSERT(lons[0] == 300.0);
+            CPPUNIT_ASSERT(lons[4] == 60.0);
+#ifdef DODS_DEBUG
+            gc2.get_constrained_grid()->print_decl(cerr, "    ", true, false, true);
+            gc2.get_constrained_grid()->print_val(cerr, "    ", false);
+            cerr << endl << endl;
+#endif
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+    }
+
+    // This tests the 'stitch' feature of the GridGeoConstraint/GeoConstraint
+    void apply_constriant_to_data_test4()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST1_1"));
+            CPPUNIT_ASSERT(g2);
+            g2->set_send_p(true);
+
+            GridGeoConstraint gc2(g2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint lat from 5 to 8 and
+            // from lon 1 to 5
+            gc2.set_bounding_box(30, 280, 30, 40);
+
+            /* lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+	       lon: { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+               Data values for Grid SST1_1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+
+            gc2.apply_constraint_to_data();
+
+            DBG(cerr << "gc2.d_latitude->length(): " << gc2.d_latitude->length() << endl);
+            DBG(cerr << "gc2.d_longitude->length(): " << gc2.d_longitude->length() << endl);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc2.d_latitude->buf2val((void**)lats_ptr);
+            DBG(cerr << "lats[0]: " << lats[0] << endl);
+            //CPPUNIT_ASSERT(lats[3] == -40.0);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc2.d_longitude->buf2val((void**)lons_ptr);
+            DBG(cerr << "lons[0]: " << lons[0] << endl);
+            DBG(cerr << "lons[3]: " << lons[4] << endl);
+            //CPPUNIT_ASSERT(lons[0] == 260.0);
+            //CPPUNIT_ASSERT(lons[4] == 20.0);
+
+            CPPUNIT_ASSERT(gc2.d_latitude->length() == 1);
+            CPPUNIT_ASSERT(gc2.d_longitude->length() == 5);
+
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+            //CPPUNIT_ASSERT(lats[3] == -40.0);
+
+            CPPUNIT_ASSERT(lons[0] == 280.0);
+            CPPUNIT_ASSERT(lons[4] == 40.0);
+#ifdef DODS_DEBUG
+            gc2.get_constrained_grid()->print_decl(cerr, "    ", true, false, true);
+            gc2.get_constrained_grid()->print_val(cerr, "    ", false);
+            cerr << endl << endl;
+#endif
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+    }
+
+    void apply_constriant_to_data_test4_three_arg()
+    {
+        try {
+            Grid *g2 = dynamic_cast<Grid*>(geo_dds->var("SST1_1"));
+            CPPUNIT_ASSERT(g2);
+            g2->set_send_p(true);
+
+            Array *lat2 = dynamic_cast<Array*>(geo_dds->var("SST1_1.lat"));
+            CPPUNIT_ASSERT(lat2);
+            Array *lon2 = dynamic_cast<Array*>(geo_dds->var("SST1_1.lon"));
+            CPPUNIT_ASSERT(lon2);
+
+            GridGeoConstraint gc2(g2, lat2, lon2);
+            // SST1 with a constraint that uses neg_pos notation for lon
+            // This should result in a constraint lat from 5 to 8 and
+            // from lon 1 to 5
+            gc2.set_bounding_box(30, 280, 30, 40);
+
+            /* lat: { 40, 30, 20, 10, 0, -10, -20, -30, -40, -50 };
+	       lon: { 0, 40, 80, 120, 160, 200, 240, 280, 320, 359 };
+               Data values for Grid SST1_1:
+                    { { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
+                      { 10,11,12,13,14,15,16,17,18,19},
+                      { 20,21,22,23,24,25,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} };
+            */
+
+            gc2.apply_constraint_to_data();
+
+            DBG(cerr << "gc2.d_latitude->length(): " << gc2.d_latitude->length() << endl);
+            DBG(cerr << "gc2.d_longitude->length(): " << gc2.d_longitude->length() << endl);
+
+            double *lats = 0;
+            double **lats_ptr = &lats;
+            gc2.d_latitude->buf2val((void**)lats_ptr);
+            DBG(cerr << "lats[0]: " << lats[0] << endl);
+            //CPPUNIT_ASSERT(lats[3] == -40.0);
+
+            double *lons = 0;
+            double **lons_ptr = &lons;
+            gc2.d_longitude->buf2val((void**)lons_ptr);
+            DBG(cerr << "lons[0]: " << lons[0] << endl);
+            DBG(cerr << "lons[3]: " << lons[4] << endl);
+            //CPPUNIT_ASSERT(lons[0] == 260.0);
+            //CPPUNIT_ASSERT(lons[4] == 20.0);
+
+            CPPUNIT_ASSERT(gc2.d_latitude->length() == 1);
+            CPPUNIT_ASSERT(gc2.d_longitude->length() == 5);
+
+            CPPUNIT_ASSERT(lats[0] == 30.0);
+            //CPPUNIT_ASSERT(lats[3] == -40.0);
+
+            CPPUNIT_ASSERT(lons[0] == 280.0);
+            CPPUNIT_ASSERT(lons[4] == 40.0);
+#ifdef DODS_DEBUG
+            gc2.get_constrained_grid()->print_decl(cerr, "    ", true, false, true);
+            gc2.get_constrained_grid()->print_val(cerr, "    ", false);
+            cerr << endl << endl;
+#endif
+        }
+        catch (Error &e) {
+            CPPUNIT_FAIL(e.get_error_message());
+        }
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(GridGeoConstraintTest);
+
+} // namespace libdap
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/HTTPCacheTest.cc b/unit-tests/HTTPCacheTest.cc
new file mode 100644
index 0000000..2241cb6
--- /dev/null
+++ b/unit-tests/HTTPCacheTest.cc
@@ -0,0 +1,875 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <unistd.h>   // for access stat
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <cstdio>     // for create_cache_root_test
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <memory>
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "HTTPCache.h"
+#include "HTTPConnect.h"	// Used to generate a response to cache.
+#ifndef WIN32			// Signals are exquisitely non-portable.
+#include "SignalHandler.h"	// Needed to clean up this singleton.
+#endif
+#include "RCReader.h"		// ditto
+
+//#define DODS_DEBUG 1
+#include "debug.h"
+
+#if defined(DODS_DEBUG) || defined(DODS_DEBUG2)
+#include <iterator>
+#endif
+
+using namespace CppUnit;
+using namespace std;
+
+#ifdef WIN32
+#define F_OK 0
+#define W_OK 2
+#endif
+
+namespace libdap
+{
+
+inline static int
+file_size(string name)
+{
+    struct stat s;
+    stat(name.c_str(), &s);
+    return s.st_size;
+}
+
+inline static void
+print_entry(HTTPCache *, HTTPCacheTable::CacheEntry **e)
+{
+    cerr << "Entry: " << (*e)->get_cachename() << endl;
+}
+
+// Note that because this test class uses the fixture 'hc' we must always
+// force access to the single user/process lock for the cache. This is
+// because a fixture is always created (by setUp) *before* the body of the
+// test is run. So by the time we're at the first line of the test, The
+// persistent store's lock has already been grabbed. 10/14/02 jhrg
+
+class HTTPCacheTest : public TestFixture {
+private:
+    HTTPCache *hc;
+    HTTPConnect *http_conn;
+    string index_file_line;
+    string localhost_url;
+    string expired;
+    int hash_value;
+    vector<string> h;
+
+protected:
+
+public:
+    HTTPCacheTest() : http_conn(0) {
+	putenv((char*)"DODS_CONF=./cache-testsuite/dodsrc");
+	http_conn = new HTTPConnect(RCReader::instance());
+
+	DBG2(cerr << "Entring HTTPCacheTest ctor... ");
+	hash_value = 656;
+	localhost_url = "http://test.opendap.org/test-304.html";
+	index_file_line = "http://test.opendap.org/test-304.html cache-testsuite/dods_cache/656/dodsKbcD0h \"3f62c-157-139c2680\" 1121283146 -1 343 0 656 1 7351 1121360379 3723 0";
+
+	expired = "http://test.opendap.org/cgi-bin/expires.sh";
+
+	h.push_back("ETag: jhrgjhrgjhrg");
+	h.push_back("Last-Modified: Sat, 05 Nov 1994 08:49:37 GMT");
+	h.push_back("Expires: Mon, 07 Nov 1994 08:49:37 GMT");
+	h.push_back("Date: Sun, 06 Nov 1994 08:49:37 GMT");
+	DBG2(cerr << "exiting." << endl);
+    }
+
+    ~HTTPCacheTest() {
+	delete http_conn; http_conn = 0;
+	DBG2(cerr << "Entering the HTTPCacheTest dtor... ");
+	DBG2(cerr << "exiting." << endl);
+    }
+#if 0
+    static inline bool
+    is_hop_by_hop_header(const string &header) {
+	return header.find("Connection") != string::npos
+	    || header.find("Keep-Alive") != string::npos
+	    || header.find("Proxy-Authenticate") != string::npos
+	    || header.find("Proxy-Authorization") != string::npos
+	    || header.find("Transfer-Encoding") != string::npos
+	    || header.find("Upgrade") != string::npos;
+    }
+#endif
+    void setUp () {
+	// Called before every test.
+	DBG2(cerr << "Entering HTTPCacheTest::setUp... " << endl);
+	hc = new HTTPCache("cache-testsuite/dods_cache/", true);
+	DBG2(cerr << "exiting setUp" << endl);
+    }
+
+    void tearDown() {
+	// Called after every test.
+	DBG2(cerr << "Entering HTTPCacheTest::tearDown... " << endl);
+	delete hc; hc = 0;
+	DBG2(cerr << "exiting tearDown" << endl);
+    }
+
+    CPPUNIT_TEST_SUITE(HTTPCacheTest);
+#if 1
+    CPPUNIT_TEST(constructor_test);
+    CPPUNIT_TEST(cache_index_read_test);
+    CPPUNIT_TEST(cache_index_parse_line_test);
+    CPPUNIT_TEST(get_entry_from_cache_table_test);
+    CPPUNIT_TEST(cache_index_write_test);
+    CPPUNIT_TEST(create_cache_root_test);
+    CPPUNIT_TEST(set_cache_root_test);
+#endif
+    CPPUNIT_TEST(get_single_user_lock_test);
+#if 1
+    CPPUNIT_TEST(release_single_user_lock_test);
+    CPPUNIT_TEST(create_hash_directory_test);
+    CPPUNIT_TEST(create_location_test);
+    CPPUNIT_TEST(parse_headers_test);
+
+    CPPUNIT_TEST(calculate_time_test);
+    CPPUNIT_TEST(write_metadata_test);
+    CPPUNIT_TEST(cache_response_test);
+
+    CPPUNIT_TEST(is_url_valid_test);
+    CPPUNIT_TEST(get_cached_response_test);
+
+    CPPUNIT_TEST(perform_garbage_collection_test);
+    CPPUNIT_TEST(purge_cache_and_release_cached_response_test);
+    CPPUNIT_TEST(instance_test);
+    CPPUNIT_TEST(get_conditional_response_headers_test);
+    CPPUNIT_TEST(update_response_test);
+    CPPUNIT_TEST(cache_gc_test);
+#endif
+#if 0
+    CPPUNIT_TEST(interrupt_test);
+#endif
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void constructor_test() {
+		DBG(cerr << "hc->cache_index: " << hc->d_http_cache_table->d_cache_index << endl);
+		CPPUNIT_ASSERT(hc->d_http_cache_table->d_cache_index=="cache-testsuite/dods_cache/.index");
+		CPPUNIT_ASSERT(hc->d_cache_root == "cache-testsuite/dods_cache/");
+		DBG(cerr << "Current size: " << hc->d_http_cache_table->d_current_size << endl);
+		DBG(cerr << "Block size: " << hc->d_http_cache_table->d_block_size << endl);
+		CPPUNIT_ASSERT(hc->d_http_cache_table->d_current_size == hc->d_http_cache_table->d_block_size);
+	}
+
+    void cache_index_read_test() {
+		CPPUNIT_ASSERT(hc->d_http_cache_table->cache_index_read());
+
+		HTTPCacheTable::CacheEntry *e =
+				hc->d_http_cache_table->get_locked_entry_from_cache_table(localhost_url);
+
+		CPPUNIT_ASSERT(e);
+		CPPUNIT_ASSERT(e->url == localhost_url);
+		e->unlock_read_response();
+	}
+
+	void cache_index_parse_line_test() {
+		HTTPCacheTable::CacheEntry *e =
+				hc->d_http_cache_table->cache_index_parse_line(index_file_line.c_str());
+
+		CPPUNIT_ASSERT(e->url == localhost_url);
+		CPPUNIT_ASSERT(e->cachename
+				== "cache-testsuite/dods_cache/656/dodsKbcD0h");
+#ifdef WIN32
+		char *tmpstr = "\"3f62c-157-139c2680\"";
+		CPPUNIT_ASSERT(e->etag == tmpstr);
+#else
+		CPPUNIT_ASSERT(e->etag == "\"3f62c-157-139c2680\"");
+#endif
+		CPPUNIT_ASSERT(e->lm == 1121283146);
+		// Skip ahead ...
+		CPPUNIT_ASSERT(e->must_revalidate == false);
+
+		delete e;
+		e = 0;
+	}
+
+	// This will also test the add_entry_to_cache_table() method.
+	void get_entry_from_cache_table_test() {
+		HTTPCacheTable::CacheEntry *e =
+				hc->d_http_cache_table->cache_index_parse_line(index_file_line.c_str());
+
+		// Test adding an entry and getting it back.
+		hc->d_http_cache_table->add_entry_to_cache_table(e);
+
+		HTTPCacheTable::CacheEntry *e2 =
+				hc->d_http_cache_table->get_locked_entry_from_cache_table(localhost_url);
+		CPPUNIT_ASSERT(e2);
+		CPPUNIT_ASSERT(e2->url == localhost_url);
+#if 0
+		e2->unlock();
+#endif
+		e2->unlock_read_response();
+
+		// Now test what happens when two entries collide.
+		HTTPCacheTable::CacheEntry *e3 =
+				hc->d_http_cache_table->cache_index_parse_line(index_file_line.c_str());
+
+		// Change the url so we can tell the difference (the hash is the same)
+		e3->url = "http://new.url.same.hash/test/collisions.gif";
+
+		hc->d_http_cache_table->add_entry_to_cache_table(e3);
+
+		// Use the version of get_entry... that lets us pass in the hash
+		// value (as opposed to the normal version which calculates the hash
+		// from the url. 10/01/02 jhrg
+		HTTPCacheTable::CacheEntry *g = hc->d_http_cache_table->get_locked_entry_from_cache_table(
+				hash_value, e3->url);
+		CPPUNIT_ASSERT(g);
+		CPPUNIT_ASSERT(g->url == e3->url);
+#if 0
+		g->unlock();
+#endif
+		g->unlock_read_response();
+
+		g = hc->d_http_cache_table->get_locked_entry_from_cache_table("http://not.in.table/never.x");
+		CPPUNIT_ASSERT(g == 0);
+	}
+
+	void cache_index_write_test() {
+		HTTPCache *hc_3 = new HTTPCache("cache-testsuite/dods_cache/", true);
+		hc_3->d_http_cache_table->add_entry_to_cache_table(hc->d_http_cache_table->cache_index_parse_line(index_file_line.c_str()));
+
+		hc_3->d_http_cache_table->d_cache_index = hc->d_cache_root + "test_index";
+		hc_3->d_http_cache_table->cache_index_write();
+
+		HTTPCache *hc_4 = new HTTPCache("cache-testsuite/dods_cache/", true);
+		hc_4->d_http_cache_table->d_cache_index = hc_3->d_cache_root + "test_index";
+		hc_4->d_http_cache_table->cache_index_read();
+
+		HTTPCacheTable::CacheEntry *e =
+				hc_4->d_http_cache_table->get_locked_entry_from_cache_table(localhost_url);
+		CPPUNIT_ASSERT(e);
+		CPPUNIT_ASSERT(e->url == localhost_url);
+		e->unlock_read_response();
+
+		delete hc_3;
+		hc = 0;
+		delete hc_4;
+		hc = 0;
+	}
+
+	void create_cache_root_test() {
+		hc->create_cache_root("/tmp/silly/");
+		CPPUNIT_ASSERT(access("/tmp/silly/", F_OK) == 0);
+		remove("/tmp/silly");
+#if 0
+		// This test doesn't work on some machines where the build is
+		// run as root or where /root is owned by some other user (as is
+		// the case with OS/X.
+		try {
+			hc->create_cache_root("/root/very_silly/");
+			access("/root/very_silly/", F_OK);
+			remove("/root/very_silly/");
+			CPPUNIT_ASSERT(!"Should not be able to do this...");
+		}
+		catch (Error &e) {
+			CPPUNIT_ASSERT("This is where we want to be");
+			CPPUNIT_ASSERT(access("/root/very_silly/", F_OK) != 0);
+		}
+#endif
+	}
+
+	void set_cache_root_test() {
+#if 0
+	    // env var support removed 3/22/11 jhrg
+	    putenv("DODS_CACHE=/home/jimg");
+		hc->set_cache_root();
+		CPPUNIT_ASSERT(hc->d_cache_root == "/home/jimg/dods-cache/");
+		remove("/home/jimg/w3c-cache/");
+#endif
+		hc->set_cache_root("/home/jimg/test_cache");
+		CPPUNIT_ASSERT(hc->d_cache_root == "/home/jimg/test_cache/");
+		remove("/home/jimg/test_cache/");
+	}
+
+	void get_single_user_lock_test() {
+		hc->set_cache_root("/tmp/dods_test_cache");
+		hc->release_single_user_lock();
+
+		CPPUNIT_ASSERT(hc->get_single_user_lock());
+		CPPUNIT_ASSERT(access("/tmp/dods_test_cache/.lock", F_OK) == 0);
+
+		// Second time should fail
+		CPPUNIT_ASSERT(!hc->get_single_user_lock());
+	}
+
+	void release_single_user_lock_test() {
+		hc->set_cache_root("/tmp/dods_test_cache");
+		remove("/tmp/dods_test_cache/.lock"); // in case prev. test fails
+		hc->d_locked_open_file = 0;
+
+		CPPUNIT_ASSERT(hc->get_single_user_lock());
+		CPPUNIT_ASSERT(access("/tmp/dods_test_cache/.lock", F_OK) == 0);
+
+		hc->release_single_user_lock();
+		CPPUNIT_ASSERT(hc->get_single_user_lock());
+		CPPUNIT_ASSERT(access("/tmp/dods_test_cache/.lock", F_OK) == 0);
+
+		CPPUNIT_ASSERT(!hc->get_single_user_lock());
+
+		remove("/tmp/dods_test_cache/.lock");
+	}
+
+	void create_hash_directory_test() {
+		hc->set_cache_root("/tmp/dods_test_cache");
+		CPPUNIT_ASSERT(hc->d_http_cache_table->create_hash_directory(391)
+				== "/tmp/dods_test_cache/391");
+		CPPUNIT_ASSERT(access("/tmp/dods_test_cache/391", W_OK) == 0);
+#if 0
+		// This test doesn't work on some machines where the build is
+		// run as root or where /root is owned by some other user (as is
+		// the case with OS/X.
+		hc->set_cache_root("/root/");
+		try {
+			hc->create_hash_directory(391);
+			CPPUNIT_ASSERT(!"Create in bad directory");
+		}
+		catch (Error &e) {
+		}
+#endif
+		remove("/tmp/dods_test_cache/391");
+
+	}
+
+	void create_location_test() {
+		hc->set_cache_root("/tmp/dods_test_cache");
+		HTTPCacheTable::CacheEntry *e = new HTTPCacheTable::CacheEntry;
+		e->url = localhost_url;
+		e->hash = hash_value;
+		try {
+			hc->d_http_cache_table->create_location(e);
+			CPPUNIT_ASSERT(e->cachename != "");
+		}
+		catch (Error &e) {
+			CPPUNIT_ASSERT(true && "could not create entry file");
+		}
+		remove(e->cachename.c_str());
+
+		delete e;
+		e = 0;
+	}
+
+	void parse_headers_test() {
+		HTTPCacheTable::CacheEntry *e = new HTTPCacheTable::CacheEntry;
+
+		hc->d_http_cache_table->parse_headers(e, hc->d_max_entry_size, h);
+		CPPUNIT_ASSERT(e->lm == 784025377);
+
+		delete e;
+		e = 0;
+	}
+
+	void calculate_time_test() {
+		HTTPCacheTable::CacheEntry *e = new HTTPCacheTable::CacheEntry;
+
+		hc->d_http_cache_table->parse_headers(e, hc->d_max_entry_size, h);
+		hc->d_http_cache_table->calculate_time(e, hc->d_default_expiration, time(0));
+		CPPUNIT_ASSERT(e->corrected_initial_age > 249300571);
+		CPPUNIT_ASSERT(e->freshness_lifetime == 86400);
+
+		delete e;
+		e = 0;
+	}
+
+	void write_metadata_test() {
+		hc->set_cache_root("/tmp/dods_test_cache");
+		HTTPCacheTable::CacheEntry *e = new HTTPCacheTable::CacheEntry;
+		try {
+			e->hash = 101;
+			hc->d_http_cache_table->create_location(e);
+			CPPUNIT_ASSERT(e->cachename != "");
+		}
+		catch (Error &e) {
+			CPPUNIT_ASSERT(true && "could not create entry file");
+		}
+
+		hc->write_metadata(e->cachename, h);
+		vector<string> headers;
+		hc->read_metadata(e->cachename, headers);
+
+		vector<string>::iterator i, j;
+		for (i = headers.begin(), j = h.begin(); i != headers.end() && j
+				!= h.end(); ++i, ++j) {
+			CPPUNIT_ASSERT(*i == *j);
+		}
+
+		remove(e->cachename.c_str());
+		remove(string(e->cachename + ".meta").c_str());
+		delete e;
+		e = 0;
+	}
+
+	void cache_response_test() {
+		HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+		try {
+			time_t now = time(0);
+			vector<string> *headers = rs->get_headers();
+			hc->cache_response(localhost_url, now, *headers, rs->get_stream());
+
+			CPPUNIT_ASSERT(hc->is_url_in_cache(localhost_url));
+
+			HTTPCacheTable::CacheEntry *e = hc->d_http_cache_table->get_locked_entry_from_cache_table(localhost_url);
+			CPPUNIT_ASSERT(file_size(e->cachename) == 343);
+			e->unlock_read_response();
+			delete rs; rs = 0;
+		}
+		catch (Error &e) {
+			delete rs; rs = 0;
+			cerr << "Error: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(!"Caught unexpected Error/InternalErr");
+		}
+	}
+
+	void is_url_valid_test() {
+		cache_response_test(); // This should get a response into the cache.
+		CPPUNIT_ASSERT(hc->is_url_valid(localhost_url));
+	}
+
+	void get_cached_response_test() {
+		cache_response_test(); // Get a response into the cache.
+		vector<string> cached_headers;
+		FILE *cached_body = hc->get_cached_response(localhost_url,
+				cached_headers);
+
+		HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+		vector<string> *headers = rs->get_headers();
+
+		// headers and cached_headers should match, except for the values.
+		vector<string>::iterator i, j;
+		for (i = cached_headers.begin(), j = headers->begin(); i
+				!= cached_headers.end() && j != headers->end(); ++i, ++j) {
+			string ch = (*i).substr(0, (*i).find(": "));
+			// Skip over headers that won't be cached. jhrg 7/4/05
+			while (is_hop_by_hop_header(*j))
+				++j;
+			string h = (*j).substr(0, (*j).find(": "));
+			DBG(cerr << "cached: " << ch << ", header: " << h << endl);
+			CPPUNIT_ASSERT(ch == h);
+		}
+
+		CPPUNIT_ASSERT(i == cached_headers.end() && j == headers->end());
+
+		// every byte of the cached_body and response body should match.
+		while (!feof(rs->get_stream()) && !feof(cached_body)
+				&& !ferror(rs->get_stream()) && !ferror(cached_body)) {
+			char cb, b;
+			int cn = fread(&cb, 1, 1, cached_body);
+			int n = fread(&b, 1, 1, rs->get_stream());
+			CPPUNIT_ASSERT(cn == n);
+			if (cn == 1)
+				CPPUNIT_ASSERT(cb == b);
+		}
+		CPPUNIT_ASSERT(feof(rs->get_stream()) && feof(cached_body));
+
+		hc->release_cached_response(cached_body);
+		delete rs;
+		rs = 0;
+	}
+
+	void perform_garbage_collection_test() {
+		try {
+			delete hc; hc = 0;
+			auto_ptr<HTTPCache> gc(new HTTPCache("cache-testsuite/gc_cache", true));
+
+			HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+			gc->cache_response(localhost_url, time(0), *(rs->get_headers()),
+					rs->get_stream());
+			CPPUNIT_ASSERT(gc->is_url_in_cache(localhost_url));
+			delete rs; rs = 0;
+
+			rs = http_conn->fetch_url(expired);
+			gc->cache_response(expired, time(0), *(rs->get_headers()),
+					rs->get_stream());
+			CPPUNIT_ASSERT(gc->is_url_in_cache(expired));
+			delete rs; rs = 0;
+
+			sleep(2);
+
+			gc->perform_garbage_collection();
+			gc->d_http_cache_table->cache_index_write();
+
+			CPPUNIT_ASSERT(!gc->is_url_in_cache(expired)
+					&& "This may fail if sleep is not long enough before gc above");
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+	}
+
+	void purge_cache_and_release_cached_response_test() {
+		try {
+			auto_ptr<HTTPCache> pc(new HTTPCache("cache-testsuite/purge_cache", true));
+
+			time_t now = time(0);
+			HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+			pc->cache_response(localhost_url, now, *(rs->get_headers()),
+					rs->get_stream());
+
+			CPPUNIT_ASSERT(pc->is_url_in_cache(localhost_url));
+			delete rs; rs = 0;
+
+			string expired = "http://test.opendap.org/cgi-bin/expires.sh";
+			now = time(0);
+			rs = http_conn->fetch_url(expired);
+			pc->cache_response(expired, now, *(rs->get_headers()),
+					rs->get_stream());
+
+			CPPUNIT_ASSERT(pc->is_url_in_cache(expired));
+			delete rs; rs = 0;
+
+			HTTPCacheTable::CacheEntry *e1 = pc->d_http_cache_table->get_locked_entry_from_cache_table(expired);
+			HTTPCacheTable::CacheEntry *e2 = pc->d_http_cache_table->get_locked_entry_from_cache_table(localhost_url);
+			string e1_file = e1->cachename;
+			string e2_file = e2->cachename;
+#if 0
+			e1->unlock();
+#endif
+			e1->unlock_read_response();
+#if 0
+			e2->unlock();
+#endif
+			e2->unlock_read_response();
+
+			vector<string> headers;
+			FILE *b = pc->get_cached_response(expired, headers);
+
+			try {
+				pc->purge_cache();
+				CPPUNIT_ASSERT(!"This call should throw Error");
+			}
+			catch(Error &e) {
+				CPPUNIT_ASSERT("Caught Error as expected");
+			}
+
+			pc->release_cached_response(b);
+
+			pc->purge_cache();
+
+			CPPUNIT_ASSERT(!pc->is_url_in_cache(localhost_url));
+			CPPUNIT_ASSERT(!pc->is_url_in_cache(expired));
+			CPPUNIT_ASSERT(access(e1_file.c_str(), F_OK) != 0);
+			CPPUNIT_ASSERT(access(e2_file.c_str(), F_OK) != 0);
+			CPPUNIT_ASSERT(pc->d_http_cache_table->d_current_size == 0);
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+	}
+
+	void instance_test() {
+		try {
+			HTTPCache *c = HTTPCache::instance("cache-testsuite/singleton_cache", true);
+
+			if (!c->is_url_in_cache(localhost_url)) {
+				HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+				c->cache_response(localhost_url, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				delete rs; rs = 0;
+			}
+			CPPUNIT_ASSERT(c->is_url_in_cache(localhost_url));
+
+			if (!c->is_url_in_cache(expired)) {
+				HTTPResponse *rs = http_conn->fetch_url(expired);
+				c->cache_response(expired, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				delete rs; rs = 0;
+			}
+			CPPUNIT_ASSERT(c->is_url_in_cache(expired));
+
+			HTTPCacheTable::CacheEntry *e1 = c->d_http_cache_table->get_locked_entry_from_cache_table(expired);
+			HTTPCacheTable::CacheEntry *e2 = c->d_http_cache_table->get_locked_entry_from_cache_table(localhost_url);
+			string e1_file = e1->cachename;
+			string e2_file = e2->cachename;
+#if 0
+			e1->unlock();
+#endif
+			e1->unlock_read_response();
+#if 0
+			e2->unlock();
+#endif
+			e2->unlock_read_response();
+
+			c->purge_cache();
+
+			CPPUNIT_ASSERT(!c->is_url_in_cache(localhost_url));
+			CPPUNIT_ASSERT(!c->is_url_in_cache(expired));
+			CPPUNIT_ASSERT(access(e1_file.c_str(), F_OK) != 0);
+			CPPUNIT_ASSERT(access(e2_file.c_str(), F_OK) != 0);
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+
+		// Call this here to simulate exiting the program. This ensures that
+		// the next test's call to instance() gets a fresh cache. The static
+		// method will still be run at exit, but that's OK since it tests the
+		// value of _instance and simply returns with it's zero.
+		HTTPCache::delete_instance();
+#ifndef WIN32
+		SignalHandler::delete_instance();
+#endif
+	}
+
+	void get_conditional_response_headers_test() {
+		try {
+			HTTPCache *c = HTTPCache::instance("cache-testsuite/header_cache",
+					true);
+			CPPUNIT_ASSERT(c->get_cache_root()
+					== "cache-testsuite/header_cache/");
+			if (!c->is_url_in_cache(localhost_url)) {
+				HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+				c->cache_response(localhost_url, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				delete rs; rs = 0;
+			}
+			CPPUNIT_ASSERT(c->is_url_in_cache(localhost_url));
+
+			if (!c->is_url_in_cache(expired)) {
+				HTTPResponse *rs = http_conn->fetch_url(expired);
+				c->cache_response(expired, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				delete rs; rs = 0;
+			}
+			CPPUNIT_ASSERT(c->is_url_in_cache(expired));
+
+			vector<string> h = c->get_conditional_request_headers(localhost_url);
+			DBG(copy(h.begin(), h.end(),
+							ostream_iterator<string>(cout, "\n")));
+			DBG(cerr << "if none match location: " <<
+					h[0].find("If-None-Match: ") << endl);
+			// I know what the strings should start with...
+			CPPUNIT_ASSERT(h[0].find("If-None-Match: ") == 0);
+
+			h = c->get_conditional_request_headers(expired);
+			DBG(cerr << "Number of headers: " << h.size() << endl);
+			DBG(copy(h.begin(), h.end(),
+							ostream_iterator<string>(cout, "\n")));
+			CPPUNIT_ASSERT(h[0].find("If-Modified-Since: ") == 0);
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+
+		HTTPCache::delete_instance();
+	}
+
+	void update_response_test() {
+		try {
+			HTTPCache *c = new HTTPCache("cache-testsuite/singleton_cache", true);
+
+			if (!c->is_url_in_cache(localhost_url)) {
+				HTTPResponse *rs = http_conn->fetch_url(localhost_url);
+				c->cache_response(localhost_url, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				delete rs; rs = 0;
+			}
+
+			if (!c->is_url_in_cache(expired)) {
+				HTTPResponse *rs = http_conn->fetch_url(expired);
+				c->cache_response(expired, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				delete rs; rs = 0;
+			}
+
+			// Yes, there's stuff here.
+			CPPUNIT_ASSERT(c->is_url_in_cache(localhost_url));
+			CPPUNIT_ASSERT(c->is_url_in_cache(expired));
+
+			vector<string> orig_h;
+			FILE *cr = c->get_cached_response(localhost_url, orig_h);
+			DBG(copy(orig_h.begin(), orig_h.end(),
+							ostream_iterator<string>(cerr, "\n")));
+
+			// Before we merge, et c., check that the headers we're going to
+			// poke in aren't already there.
+			CPPUNIT_ASSERT(find(orig_h.begin(), orig_h.end(),
+							"XHTTPCache: 123456789") == orig_h.end());
+			CPPUNIT_ASSERT(find(orig_h.begin(), orig_h.end(),
+							"Date: <invalid date>") == orig_h.end());
+
+			// Make up some new headers.
+			vector<string> new_h;
+			new_h.push_back("XHTTPCache: 123456789");
+			new_h.push_back("Date: <invalid date>");
+
+			c->release_cached_response(cr);
+
+			c->update_response(localhost_url, time(0), new_h);
+
+			vector<string> updated_h;
+			cr = c->get_cached_response(localhost_url, updated_h);
+			c->release_cached_response(cr);
+			DBG(copy(updated_h.begin(), updated_h.end(),
+							ostream_iterator<string>(cerr, "\n")));
+
+			// The XHTTPCacheTest header should be new, Date should replace the
+			// existing Date header.
+			CPPUNIT_ASSERT(orig_h.size() + 1 == updated_h.size());
+			CPPUNIT_ASSERT(find(updated_h.begin(), updated_h.end(),
+							"XHTTPCache: 123456789") != updated_h.end());
+			CPPUNIT_ASSERT(find(updated_h.begin(), updated_h.end(),
+							"Date: <invalid date>") != updated_h.end());
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+
+		HTTPCache::delete_instance();
+	}
+
+	// Only run this interactively since you need to hit Ctrl-c to generate
+	// SIGINT while the cache is doing its thing. 02/10/04 jhrg
+	void interrupt_test() {
+		try {
+			HTTPCache *c = new HTTPCache("cache-testsuite/singleton_cache", true);
+			string coads = "http://test.opendap.org/dap/data/nc/coads_climatology.nc";
+			if (!c->is_url_in_cache(coads)) {
+				HTTPResponse *rs = http_conn->fetch_url(coads);
+				cerr << "In interrupt test, hit ctrl-c now... ";
+				c->cache_response(coads, time(0),
+						*(rs->get_headers()), rs->get_stream());
+				cerr << "to late.";
+				delete rs; rs = 0;
+			}
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+
+		// Call this here to simulate exiting the program. This ensures that
+		// the next test's call to instance() gets a fresh cache. The static
+		// method will still be run at exit, but that's OK since it tests the
+		// value of _instance and simply returns with it's zero.
+		HTTPCache::delete_instance();
+	}
+
+	void cache_gc_test() {
+		string fnoc1 =
+				"http://test.opendap.org/dap/data/nc/fnoc1.nc.dds";
+		string fnoc2 =
+				"http://test.opendap.org/dap/data/nc/fnoc2.nc.dds";
+		string fnoc3 =
+				"http://test.opendap.org/dap/data/nc/fnoc3.nc.dds";
+		try {
+			auto_ptr<HTTPCache> pc(new HTTPCache("cache-testsuite/purge_cache", true));
+
+			CPPUNIT_ASSERT(pc->d_http_cache_table->d_block_size == 4096);
+
+			// Change the size parameters so that we can run some tests
+			pc->d_total_size = 12288; // bytes
+			pc->d_folder_size = pc->d_total_size/10;
+			pc->d_gc_buffer = pc->d_total_size/10;
+
+			// Thie cache should start empty
+			CPPUNIT_ASSERT(pc->d_http_cache_table->d_current_size == 0);
+
+			// Get a url
+			HTTPResponse *rs = http_conn->fetch_url(fnoc1);
+			pc->cache_response(fnoc1, time(0), *(rs->get_headers()),
+					rs->get_stream());
+			CPPUNIT_ASSERT(pc->is_url_in_cache(fnoc1));
+			delete rs; rs = 0;
+			// trigger a hit for fnoc1
+			vector<string> h;
+			FILE *f = pc->get_cached_response(fnoc1, h);
+			pc->release_cached_response(f);
+
+			rs = http_conn->fetch_url(fnoc2);
+			pc->cache_response(fnoc2, time(0), *(rs->get_headers()),
+					rs->get_stream());
+			CPPUNIT_ASSERT(pc->is_url_in_cache(fnoc2));
+			delete rs; rs = 0;
+			// trigger two hits for fnoc2
+			f = pc->get_cached_response(fnoc2, h);
+			pc->release_cached_response(f);
+			f = pc->get_cached_response(fnoc2, h);
+			pc->release_cached_response(f);
+
+			rs = http_conn->fetch_url(fnoc3);
+			pc->cache_response(fnoc3, time(0), *(rs->get_headers()),
+					rs->get_stream());
+			CPPUNIT_ASSERT(pc->is_url_in_cache(fnoc3));
+			delete rs; rs = 0;
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+
+		// now that pc is out of scope, its dtor has been run and GC
+		// performed. The fnoc3 URL should have been deleted.
+
+		try {
+			auto_ptr<HTTPCache> pc(new HTTPCache("cache-testsuite/purge_cache", true));
+			CPPUNIT_ASSERT(!pc->is_url_in_cache(fnoc3));
+		}
+		catch(Error &e) {
+			cerr << "Exception: " << e.get_error_message() << endl;
+			CPPUNIT_ASSERT(false);
+		}
+	}
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HTTPCacheTest);
+
+} // namespace libdap
+
+int main(int, char**) {
+	// Run cleanup here, so that the first run works (since this code now
+	// sets up the tests).
+	system("cd cache-testsuite && ./cleanup.sh");
+
+	CppUnit::TextTestRunner runner;
+	runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+	bool wasSuccessful = runner.run("", false) ;
+
+	cerr.flush();
+
+	return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/HTTPConnectTest.cc b/unit-tests/HTTPConnectTest.cc
new file mode 100644
index 0000000..377d7f8
--- /dev/null
+++ b/unit-tests/HTTPConnectTest.cc
@@ -0,0 +1,545 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <cstring>
+#include <iterator>
+#include <string>
+#include <algorithm>
+#include <functional>
+
+//#define DODS_DEBUG
+
+#include "GNURegex.h"
+#include "HTTPConnect.h"
+#include "RCReader.h"
+
+#include "debug.h"
+
+#include "test_config.h"
+
+using namespace CppUnit;
+using namespace std;
+
+namespace libdap
+{
+
+class HTTPConnectTest: public TestFixture {
+  private:
+    HTTPConnect * http;
+    string localhost_url, localhost_pw_url, localhost_digest_pw_url;
+    string etag;
+    string lm;
+    string netcdf_das_url;
+
+  protected:
+    bool re_match(Regex & r, const char *s) {
+        return r.match(s, strlen(s)) == (int) strlen(s);
+    }
+
+    struct REMatch: public unary_function<const string &, bool> {
+        Regex &d_re;
+        REMatch(Regex &re) : d_re(re) {}
+        ~REMatch() {}
+        bool operator()(const string &str) {
+            const char *s = str.c_str();
+            return d_re.match(s, strlen(s)) == (int) strlen(s);
+        }
+    };
+
+    // This is defined in HTTPConnect.cc but has to be defined here as well.
+    // Don't know why... jhrg
+    class HeaderMatch : public unary_function<const string &, bool> {
+        const string &d_header;
+        public:
+            HeaderMatch(const string &header) : d_header(header) {}
+            bool operator()(const string &arg) { return arg.find(d_header) == 0; }
+    };
+
+  public:
+     HTTPConnectTest() {
+    }
+    ~HTTPConnectTest() {
+    }
+
+    void setUp() {
+        putenv((char*)"DODS_CONF=cache-testsuite/dodsrc");
+        http = new HTTPConnect(RCReader::instance());
+
+        localhost_url = "http://test.opendap.org/test-304.html";
+
+        // Two request header values that will generate a 304 response to the
+        // above URL. The values below much match the etag and last-modified
+        // time returned by the server. Run this test with DODS_DEBUG defined
+        // to see the values it's returning.
+        etag = "\"a10df-157-139c2680\""; // a10df-157-139c2680a
+        lm = "Wed, 13 Jul 2005 19:32:26 GMT";
+
+        localhost_pw_url =
+            "http://jimg:dods_test@test.opendap.org/basic/page.txt";
+        localhost_digest_pw_url =
+            "http://jimg:dods_digest@test.opendap.org/digest/page.txt";
+        netcdf_das_url =
+            "http://test.opendap.org/dap/data/nc/fnoc1.nc.das";
+    }
+
+    void tearDown() {
+        delete http;
+        http = 0;
+    }
+
+    CPPUNIT_TEST_SUITE(HTTPConnectTest);
+#if 1
+    CPPUNIT_TEST(read_url_test);
+    CPPUNIT_TEST(fetch_url_test);
+    CPPUNIT_TEST(get_response_headers_test);
+    CPPUNIT_TEST(server_version_test);
+    CPPUNIT_TEST(type_test);
+#endif
+    CPPUNIT_TEST(cache_test);
+#if 1
+    CPPUNIT_TEST(set_accept_deflate_test);
+    CPPUNIT_TEST(set_xdap_protocol_test);
+    CPPUNIT_TEST(read_url_password_test);
+    CPPUNIT_TEST(read_url_password_test2);
+#endif
+#if 0
+    CPPUNIT_TEST(read_url_password_proxy_test);
+#endif
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void read_url_test() {
+        vector < string > *resp_h = new vector < string >;;
+
+        try {
+            FILE *dump = fopen("/dev/null", "w");
+            long status = http->read_url(localhost_url, dump, resp_h);
+            CPPUNIT_ASSERT(status == 200);
+
+            vector < string > request_h;
+
+            // First test using a time with if-modified-since
+            request_h.push_back(string("If-Modified-Since: ") + lm);
+            status =
+                http->read_url(localhost_url, dump, resp_h, &request_h);
+            DBG(cerr << "If modified since test, status: " << status << endl);
+            DBG(copy(resp_h->begin(), resp_h->end(),
+                     ostream_iterator < string > (cerr, "\n")));
+            CPPUNIT_ASSERT(status == 304);
+
+            // Now test an etag
+            resp_h->clear();
+            request_h.clear();
+            request_h.push_back(string("If-None-Match: ") + etag);
+            status =
+                http->read_url(localhost_url, dump, resp_h, &request_h);
+            DBG(cerr << "If none match test, status: " << status << endl);
+            DBG(copy(resp_h->begin(), resp_h->end(),
+                     ostream_iterator < string > (cerr, "\n")));
+            CPPUNIT_ASSERT(status == 304);
+
+            // now test a combined etag and time4
+            resp_h->clear();
+            request_h.clear();
+            request_h.push_back(string("If-None-Match: ") + etag);
+            request_h.push_back(string("If-Modified-Since: ") + lm);
+            status =
+                http->read_url(localhost_url, dump, resp_h, &request_h);
+            DBG(cerr << "Combined test, status: " << status << endl);
+            DBG(copy(resp_h->begin(), resp_h->end(),
+                     ostream_iterator < string > (cerr, "\n")));
+            CPPUNIT_ASSERT(status == 304);
+
+            delete resp_h;
+            resp_h = 0;
+
+        }
+        catch(Error & e) {
+            delete resp_h;
+            resp_h = 0;
+            CPPUNIT_FAIL("Error: " + e.get_error_message() );
+        }
+    }
+
+    void fetch_url_test() {
+        HTTPResponse *stuff = 0;
+        char c;
+        try {
+            stuff = http->fetch_url(localhost_url);
+            CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
+                           && !ferror(stuff->get_stream())
+                           && !feof(stuff->get_stream()));
+            delete stuff;
+            stuff = 0;
+
+        }
+        catch(InternalErr & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
+        }
+        catch(Error & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
+        }
+        // Catch the exception from a failed ASSERT and clean up. Deleting a
+        // Response object also unlocks the HTTPCache in some cases. If delete
+        // is not called, then a failed test can leave the cache with locked
+        // entries
+        catch (...) {
+            delete stuff; stuff = 0;
+            throw;
+        }
+
+        try {
+            stuff = http->fetch_url(netcdf_das_url);
+            DBG2(char ln[1024]; while (!feof(stuff->get_stream())) {
+                 fgets(ln, 1024, stuff->get_stream()); cerr << ln;}
+                 rewind(stuff->get_stream()));
+
+            CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
+                           && !ferror(stuff->get_stream())
+                           && !feof(stuff->get_stream()));
+            delete stuff;
+            stuff = 0;
+        }
+        catch(InternalErr & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an InternalErr from fetch_url: " + e.get_error_message());
+        }
+        catch(Error & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
+        }
+        // Catch the exception from a failed ASSERT and clean up. Deleting a
+        // Response object also unlocks the HTTPCache in some cases. If delete
+        // is not called, then a failed test can leave the cache with locked
+        // entries
+        catch (...) {
+            delete stuff; stuff = 0;
+            throw;
+        }
+
+        try {
+            stuff = http->fetch_url("file:///etc/passwd");
+            CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
+                           && !ferror(stuff->get_stream())
+                           && !feof(stuff->get_stream()));
+            delete stuff;
+            stuff = 0;
+        }
+        catch(InternalErr & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an InternalErr from fetch_url" + e.get_error_message());
+        }
+        catch(Error & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
+        }
+        // Catch the exception from a failed ASSERT and clean up. Deleting a
+        // Response object also unlocks the HTTPCache in some cases. If delete
+        // is not called, then a failed test can leave the cache with locked
+        // entries
+        catch (...) {
+            delete stuff; stuff = 0;
+            throw;
+        }
+
+        try {
+	    string url = (string)"file://test_config.h" ;
+            stuff = http->fetch_url(url);
+            CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
+                           && !ferror(stuff->get_stream())
+                           && !feof(stuff->get_stream()));
+            delete stuff;
+            stuff = 0;
+        }
+        catch(InternalErr & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an InternalErr from fetch_url" + e.get_error_message());
+        }
+        catch(Error & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an Error from fetch_url: " + e.get_error_message());
+        }
+        // Catch the exception from a failed ASSERT and clean up. Deleting a
+        // Response object also unlocks the HTTPCache in some cases. If delete
+        // is not called, then a failed test can leave the cache with locked
+        // entries
+        catch (...) {
+            delete stuff; stuff = 0;
+            throw;
+        }
+    }
+
+    void get_response_headers_test() {
+        HTTPResponse *r = 0;
+
+        try {
+            r = http->fetch_url(netcdf_das_url);
+            vector < string > *h = r->get_headers();
+
+            DBG(copy(h->begin(), h->end(),
+                     ostream_iterator < string > (cerr, "\n")));
+
+            // Should get five or six headers back.
+            Regex header("X.*-Server: .*/.*");
+
+            CPPUNIT_ASSERT(find_if(h->begin(), h->end(), REMatch(header)) != h->end());
+
+            Regex protocol_header("XDAP: .*");
+            CPPUNIT_ASSERT(find_if(h->begin(), h->end(), REMatch(protocol_header)) != h->end());
+
+            delete r;
+            r = 0;
+        }
+        catch(InternalErr & e) {
+            delete r;
+            r = 0;
+            CPPUNIT_FAIL("Caught an InternalErr exception from get_response_headers: " + e.get_error_message() );
+        }
+        catch (...) {
+            delete r; r = 0;
+            throw;
+        }
+    }
+
+    void server_version_test() {
+        Response *r = 0;
+        Regex protocol("^[0-9]+\\.[0-9]+$");
+        try {
+            r = http->fetch_url(netcdf_das_url);
+
+            DBG(cerr << "r->get_version().c_str(): "
+                << r->get_protocol().c_str() << endl);
+
+            CPPUNIT_ASSERT(re_match(protocol, r->get_protocol().c_str()));
+            delete r;
+            r = 0;
+        }
+        catch(InternalErr & e) {
+            delete r;
+            r = 0;
+            CPPUNIT_FAIL("Caught an InternalErr exception from server_version: " + e.get_error_message() );
+        }
+        catch (...) {
+            delete r; r = 0;
+            throw;
+        }
+
+    }
+
+    void type_test() {
+        Response *r = 0;
+        try {
+            r = http->fetch_url(netcdf_das_url);
+            DBG(cerr << "r->get_type(): " << r->get_type() << endl);
+            CPPUNIT_ASSERT(r->get_type() == dods_das);
+            delete r;
+            r = 0;
+        }
+        catch(InternalErr & e) {
+            delete r;
+            r = 0;
+            CPPUNIT_FAIL("Caught an InternalErr exception from type(): " + e.get_error_message() );
+        }
+
+    }
+
+    void set_credentials_test() {
+        http->set_credentials("jimg", "was_quit");
+        Response *stuff = http->fetch_url("http://localhost/secret");
+
+        try {
+            char c;
+            CPPUNIT_ASSERT(fread(&c, 1, 1, stuff->get_stream()) == 1
+                           && !ferror(stuff->get_stream())
+                           && !feof(stuff->get_stream()));
+            delete stuff;
+            stuff = 0;
+        }
+        catch(InternalErr & e) {
+            delete stuff;
+            stuff = 0;
+            CPPUNIT_FAIL("Caught an InternalErrexception from output: " + e.get_error_message());
+        }
+    }
+
+    void cache_test() {
+        DBG(cerr << endl << "Entering Caching tests." << endl);
+	try {
+	    // The cache-testsuite/dodsrc file turns this off; all the other
+	    // params are set up. It used to be that HTTPConnect had an option to
+	    // turn caching on, but that no longer is present. This hack enables
+	    // caching for this test. 06/18/04 jhrg
+	    http->d_http_cache = HTTPCache::instance(http->d_rcr->get_dods_cache_root(), true);
+	    DBG(cerr << "Instantiate the cache" << endl);
+
+	    CPPUNIT_ASSERT(http->d_http_cache != 0);
+	    http->d_http_cache->set_cache_enabled(true);
+	    DBG(cerr << "Enable the cache" << endl);
+
+	    fetch_url_test();
+	    DBG(cerr << "fetch_url_test" << endl);
+	    get_response_headers_test();
+	    DBG(cerr << "get_response_headers_test" << endl);
+	    server_version_test();
+	    DBG(cerr << "server_version_test" << endl);
+	    type_test();
+	    DBG(cerr << "type_test" << endl);
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL((string)"Error: " + e.get_error_message());
+	}
+    }
+
+    void set_accept_deflate_test() {
+        http->set_accept_deflate(false);
+        CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             "Accept-Encoding: deflate, gzip, compress") == 0);
+
+        http->set_accept_deflate(true);
+        CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             "Accept-Encoding: deflate, gzip, compress") == 1);
+
+        http->set_accept_deflate(true);
+        CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             "Accept-Encoding: deflate, gzip, compress") == 1);
+
+        http->set_accept_deflate(false);
+        CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             "Accept-Encoding: deflate, gzip, compress") == 0);
+    }
+
+    void set_xdap_protocol_test() {
+        // Initially there should be no header and the protocol should be 2.0
+        CPPUNIT_ASSERT(http->d_dap_client_protocol_major == 2
+                       && http->d_dap_client_protocol_minor == 0);
+
+        CPPUNIT_ASSERT(count_if(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             HeaderMatch("XDAP-Accept:")) == 0);
+
+        http->set_xdap_protocol(8, 9);
+        CPPUNIT_ASSERT(http->d_dap_client_protocol_major == 8
+                       && http->d_dap_client_protocol_minor == 9);
+        CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             "XDAP-Accept: 8.9") == 1);
+
+        http->set_xdap_protocol(3, 2);
+        CPPUNIT_ASSERT(http->d_dap_client_protocol_major == 3
+                       && http->d_dap_client_protocol_minor == 2);
+        CPPUNIT_ASSERT(count(http->d_request_headers.begin(),
+                             http->d_request_headers.end(),
+                             "XDAP-Accept: 3.2") == 1);
+    }
+
+    void read_url_password_test() {
+        FILE *dump = fopen("/dev/null", "w");
+        vector < string > *resp_h = new vector < string >;
+        long status = http->read_url(localhost_pw_url, dump, resp_h);
+
+        DBG(cerr << endl << http->d_upstring << endl);
+        CPPUNIT_ASSERT(http->d_upstring == "jimg:dods_test");
+        DBG(cerr << "Status: " << status << endl);
+        CPPUNIT_ASSERT(status == 200);
+        delete resp_h;
+        resp_h = 0;
+    }
+
+    void read_url_password_test2() {
+        FILE *dump = fopen("/dev/null", "w");
+        vector < string > *resp_h = new vector < string >;
+        long status =
+            http->read_url(localhost_digest_pw_url, dump, resp_h);
+
+        DBG(cerr << endl << http->d_upstring << endl);
+        CPPUNIT_ASSERT(http->d_upstring == "jimg:dods_digest");
+        DBG(cerr << "Status: " << status << endl);
+        CPPUNIT_ASSERT(status == 200);
+        delete resp_h;
+        resp_h = 0;
+    }
+
+    // I'm going to remove this test. All of the other tests now work off of
+    // test.opendap.org. jhrg 7/13/05
+    void read_url_password_proxy_test() {
+        cerr << endl <<
+            "This test will fail if localhost is not configured as a proxy server\n\
+with authentication. The username must be jimg and the password must be\n\
+dods_test." << endl;
+
+        delete http;
+        http = 0;               // get rid of the default object; build a
+        // special one.
+        RCReader::delete_instance();
+        // this dodsrc directs all access through a proxy server. The
+        // localhost must be configured as such.
+        putenv((char*)"DODS_CONF=cache-testsuite/dodsrc_proxy");
+        try {
+            RCReader::initialize_instance();    // work-around pthreads for tests
+            http = new HTTPConnect(RCReader::instance());
+
+            fetch_url_test();
+        }
+        catch(Error & e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error");
+        }
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(HTTPConnectTest);
+
+}
+
+int main(int, char **)
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    cerr << "These tests require a working network connection." << endl;
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/Keywords2Test.cc b/unit-tests/Keywords2Test.cc
new file mode 100644
index 0000000..c15c67e
--- /dev/null
+++ b/unit-tests/Keywords2Test.cc
@@ -0,0 +1,217 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Tests for the AISResources class.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG
+
+#include "BaseType.h"
+#include "Int32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Array.h"
+#include "Grid.h"
+#include "DDS.h"
+#include "DAS.h"
+#include "ce_functions.h"
+#include "Keywords2.h"
+
+#include <test_config.h>
+
+#include "../tests/TestTypeFactory.h"
+
+#include "debug.h"
+
+using namespace CppUnit;
+using namespace libdap;
+using namespace std;
+
+int test_variable_sleep_interval = 0;
+
+class KeywordsTest:public TestFixture
+{
+private:
+    Keywords *k;
+public:
+    KeywordsTest()
+    {}
+
+    ~KeywordsTest()
+    {}
+
+    void setUp()
+    {
+	k = new Keywords();
+    }
+
+    void tearDown()
+    {
+        delete k; k = 0;
+    }
+
+    CPPUNIT_TEST_SUITE( KeywordsTest );
+
+    CPPUNIT_TEST(no_keywords_test_1);
+    CPPUNIT_TEST(no_keywords_test_2);
+
+    CPPUNIT_TEST(one_keyword_test_1);
+    CPPUNIT_TEST(one_keyword_test_2);
+
+    CPPUNIT_TEST(two_keyword_test_1);
+    CPPUNIT_TEST(two_keyword_test_2);
+
+    CPPUNIT_TEST(bad_keyword_test_1);
+    CPPUNIT_TEST(bad_keyword_test_2);
+    CPPUNIT_TEST(bad_keyword_test_3);
+    CPPUNIT_TEST(bad_keyword_test_4);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void no_keywords_test_1()
+    {
+	string ce = k->parse_keywords("");
+	CPPUNIT_ASSERT(!k->has_keyword("dap"));
+	CPPUNIT_ASSERT(ce == "");
+	CPPUNIT_ASSERT(k->get_keywords().size() == 0);
+    }
+
+    void no_keywords_test_2()
+    {
+	string ce = k->parse_keywords("u,v");
+	CPPUNIT_ASSERT(!k->has_keyword("dap"));
+	CPPUNIT_ASSERT(ce == "u,v");
+	CPPUNIT_ASSERT(k->get_keywords().size() == 0);
+    }
+
+    void one_keyword_test_1()
+    {
+	CPPUNIT_ASSERT(k->is_known_keyword("dap"));
+
+	string ce = k->parse_keywords("dap(2)");
+	CPPUNIT_ASSERT(ce == "");
+	CPPUNIT_ASSERT(k->has_keyword("dap"));
+	CPPUNIT_ASSERT(k->get_keyword_value("dap") == "2");
+	CPPUNIT_ASSERT(k->get_keywords().size() == 1);
+    }
+
+    void one_keyword_test_2()
+    {
+	string ce = k->parse_keywords("dap(2),u,v&v<7");
+	CPPUNIT_ASSERT(ce == "u,v&v<7");
+	CPPUNIT_ASSERT(k->has_keyword("dap"));
+	CPPUNIT_ASSERT(k->get_keyword_value("dap") == "2");
+	CPPUNIT_ASSERT(k->get_keywords().size() == 1);
+    }
+
+    void two_keyword_test_1()
+    {
+	string ce = k->parse_keywords("dap(2),dap(3.2)");
+	CPPUNIT_ASSERT(ce == "");
+	CPPUNIT_ASSERT(k->has_keyword("dap"));
+	CPPUNIT_ASSERT(k->get_keyword_value("dap") == "3.2");
+	CPPUNIT_ASSERT(k->get_keywords().size() == 1);
+
+	CPPUNIT_ASSERT(k->is_known_keyword("dap"));
+    }
+
+    void two_keyword_test_2()
+    {
+	string ce = k->parse_keywords("dap(2),dap(3.2),u,v&v<7");
+	CPPUNIT_ASSERT(ce == "u,v&v<7");
+	CPPUNIT_ASSERT(k->has_keyword("dap"));
+	CPPUNIT_ASSERT(k->get_keyword_value("dap") == "3.2");
+	CPPUNIT_ASSERT(k->get_keywords().size() == 1);
+    }
+
+    void bad_keyword_test_1()
+    {
+	try {
+	    string ce = k->parse_keywords("dap7");
+	    // Even though this is pretty obviously wrong, we soldier on because
+	    // The keyword processing code has no way of knowing what will be
+	    // valid variable names.
+	    CPPUNIT_ASSERT(ce == "dap7");
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL("Should not get here");
+	}
+    }
+    void bad_keyword_test_2()
+    {
+	try {
+	    string ce = k->parse_keywords("dap(7");
+	    // Even though this is pretty obviously wrong, we soldier on because
+	    // The keyword processing code has no way of knowing what will be
+	    // valid variable names.
+	    CPPUNIT_ASSERT(ce == "dap(7");
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL("Should not get here");
+	}
+    }
+    void bad_keyword_test_3()
+    {
+	try {
+	    string ce = k->parse_keywords("dap7)");
+	    // Even though this is pretty obviously wrong, we soldier on because
+	    // The keyword processing code has no way of knowing what will be
+	    // valid variable names.
+	    CPPUNIT_ASSERT(ce == "dap7)");
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL("Should not get here");
+	}
+    }
+    void bad_keyword_test_4()
+    {
+	try {
+	    string ce = k->parse_keywords("dap(7)");
+	    // Even though this is pretty obviously wrong, we soldier on because
+	    // The keyword processing code has no way of knowing what will be
+	    // valid variable names.
+	    CPPUNIT_FAIL("Should throw - bad value to keyword/function");
+	}
+	catch (Error &e) {
+	    CPPUNIT_ASSERT("Should throw - bad value to keyword/function");
+	}
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(KeywordsTest);
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/MIMEUtilTest.cc b/unit-tests/MIMEUtilTest.cc
new file mode 100644
index 0000000..ebe7bcf
--- /dev/null
+++ b/unit-tests/MIMEUtilTest.cc
@@ -0,0 +1,236 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#ifndef TM_IN_SYS_TIME
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>   // for stat
+#include <string>
+#include <sstream>
+
+//#define DODS_DEBUG
+
+#include "GNURegex.h"
+
+#include "mime_util.h"
+#include "debug.h"
+#include <test_config.h>
+
+//#include "testFile.cc"
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+class cgiUtilTest: public TestFixture {
+private:
+
+protected:
+    bool re_match(Regex &r, const string &s)
+    {
+	int match = r.match(s.c_str(), s.length());
+	DBG(cerr << "RE Match: " << match << endl);
+	return match == (int) s.length();
+    }
+
+public:
+    cgiUtilTest()
+    {
+    }
+    ~cgiUtilTest()
+    {
+    }
+
+    void setUp()
+    {
+    }
+
+    void tearDown()
+    {
+    }
+
+CPPUNIT_TEST_SUITE( cgiUtilTest );
+#if 1
+	CPPUNIT_TEST(name_path_test);
+	CPPUNIT_TEST(set_mime_text_test);
+	CPPUNIT_TEST(rfc822_date_test);
+	CPPUNIT_TEST(last_modified_time_test);
+	CPPUNIT_TEST(read_multipart_headers_test);
+#endif
+	CPPUNIT_TEST(get_next_mime_header_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void name_path_test()
+    {
+	CPPUNIT_ASSERT(name_path(string("stuff")) == "stuff");
+	CPPUNIT_ASSERT(name_path(string("stuff.Z")) == "stuff.Z");
+	CPPUNIT_ASSERT(name_path(string("/usr/local/src/stuff.Z")) == "stuff.Z");
+	CPPUNIT_ASSERT(name_path(string("/usr/local/src/stuff.tar.Z")) == "stuff.tar.Z");
+	CPPUNIT_ASSERT(name_path(string("/usr/local/src/stuff")) == "stuff");
+	CPPUNIT_ASSERT(name_path(string("/usr/local/src/#usr#local#src#stuff")) == "stuff");
+	CPPUNIT_ASSERT(name_path(string("/usr/local/src/#usr#local#src#stuff.hdf")) == "stuff.hdf");
+	CPPUNIT_ASSERT(name_path(string("")) == "");
+    }
+
+    // See note above. jhrg 1/18/06
+    void set_mime_text_test()
+    {
+	Regex
+		r1(
+			"HTTP/1.0 200 OK\r\n\
+XDODS-Server: dods-test/0.00\r\n\
+XOPeNDAP-Server: dods-test/0.00\r\n\
+XDAP: .*\r\n\
+Date: (.*)\r\n\
+Last-Modified: \\1\r\n\
+Content-Type: text/plain\r\n\
+Content-Description: dods_das\r\n\
+\r\n.*");
+	ostringstream oss;
+	set_mime_text(oss, dods_das, "dods-test/0.00");
+	DBG(cerr << "DODS DAS" << endl << oss.str());
+	CPPUNIT_ASSERT(re_match(r1, oss.str()));
+
+	Regex
+		r2(
+			"HTTP/1.0 200 OK\r\n\
+XDODS-Server: dods-test/0.00\r\n\
+XOPeNDAP-Server: dods-test/0.00\r\n\
+XDAP: .*\r\n\
+Date: (.*)\r\n\
+Last-Modified: \\1\r\n\
+Content-Type: text/plain\r\n\
+Content-Description: dods_dds\r\n\
+\r\n.*");
+
+	oss.str("");
+	set_mime_text(oss, dods_dds, "dods-test/0.00");
+	DBG(cerr << "DODS DDS" << endl << oss);
+	CPPUNIT_ASSERT(re_match(r2, oss.str()));
+
+	struct tm tm = { 0, 0, 0, 1, 0, 100, 0, 0, 0, 0, 0 }; // 1 Jan 2000
+	time_t t = mktime(&tm);
+	Regex
+		r3(
+			"HTTP/1.0 200 OK\r\n\
+XDODS-Server: dods-test/0.00\r\n\
+XOPeNDAP-Server: dods-test/0.00\r\n\
+XDAP: .*\r\n\
+Date: .*\r\n\
+Last-Modified: Sat, 01 Jan 2000 ..:00:00 GMT\r\n\
+Content-Type: text/plain\r\n\
+Content-Description: dods_dds\r\n\
+\r\n.*");
+
+	oss.str("");
+	set_mime_text(oss, dods_dds, "dods-test/0.00", x_plain, t);
+	CPPUNIT_ASSERT(re_match(r3, oss.str()));
+    }
+
+    void rfc822_date_test()
+    {
+	time_t t = 0;
+	CPPUNIT_ASSERT(rfc822_date(t) == "Thu, 01 Jan 1970 00:00:00 GMT");
+	struct tm tm = { 0, 0, 0, 1, 0, 100, 0, 0, 0, 0, 0 }; // 1 Jan 2000
+	t = mktime(&tm);
+	// This test may fail for some locations since mktime interprets t as
+	// the local time and returns the corresponding GMT time.
+	Regex r1("Sat, 01 Jan 2000 ..:00:00 GMT");
+	CPPUNIT_ASSERT(re_match(r1, rfc822_date(t)));
+    }
+
+    void last_modified_time_test()
+    {
+	time_t t = time(0);
+	CPPUNIT_ASSERT(last_modified_time("no-such-file") == t);
+	struct stat st;
+	stat("test_config.h", &st);
+	CPPUNIT_ASSERT(last_modified_time("test_config.h") == st.st_mtime);
+	stat("/etc/passwd", &st);
+	CPPUNIT_ASSERT(last_modified_time("/etc/passwd") == st.st_mtime);
+    }
+
+    void get_next_mime_header_test()
+    {
+	string test_file = (string) TEST_SRC_DIR
+		+ "/cgi-util-tests/multipart_mime_header1.txt";
+	FILE *in = fopen(test_file.c_str(), "r");
+	if (!in)
+	    CPPUNIT_FAIL("Could not open the mime header file.");
+
+	try {
+	    CPPUNIT_ASSERT(get_next_mime_header(in) == "--my_boundary");
+	    CPPUNIT_ASSERT(get_next_mime_header(in) == "Content-Type: Text/xml; charset=iso-8859-1");
+	    CPPUNIT_ASSERT(get_next_mime_header(in) == "Content-Description: dap4-ddx");
+	    CPPUNIT_ASSERT(get_next_mime_header(in) == "Content-Id: <1234 at opendap.org>");
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL(e.get_error_message());
+	}
+
+	fclose(in);
+    }
+
+    void read_multipart_headers_test()
+    {
+	string test_file = (string) TEST_SRC_DIR
+		+ "/cgi-util-tests/multipart_mime_header1.txt";
+	FILE *in = fopen(test_file.c_str(), "r");
+	if (!in)
+	    CPPUNIT_FAIL("Could not open the mime header file.");
+
+	try {
+	    read_multipart_headers(in, "text/xml", dap4_ddx);
+	    CPPUNIT_ASSERT(true);
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL(e.get_error_message());
+	}
+
+	fclose(in);
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(cgiUtilTest);
+
+int main(int, char**)
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/Makefile.am b/unit-tests/Makefile.am
new file mode 100644
index 0000000..4ff0c7a
--- /dev/null
+++ b/unit-tests/Makefile.am
@@ -0,0 +1,166 @@
+
+SUBDIRS = cache-testsuite
+
+# Tests
+
+AUTOMAKE_OPTIONS = foreign
+
+# Headers in 'tests' are used by the arrayT unit tests.
+
+AM_CPPFLAGS = -I$(top_srcdir)/GNU -I$(top_srcdir) -I$(top_srcdir)/tests
+AM_LDADD =
+if CPPUNIT
+AM_CPPFLAGS += $(CPPUNIT_CFLAGS)
+AM_LDADD += $(CPPUNIT_LIBS)
+endif
+
+# These are not used by automake but are often useful for certain types of
+# debugging. Set CXXFLAGS to this in the nightly build using export ...
+CXXFLAGS_DEBUG = -g3 -O0 -fno-defer-pop -Wall -W -Wcast-align -Werror
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+
+# This determines what gets built by make check
+check_PROGRAMS = $(UNIT_TESTS)
+
+# This determines what gets run by 'make check.'
+TESTS = $(UNIT_TESTS)
+
+noinst_HEADERS = test_config.h
+
+DIRS_EXTRA = das-testsuite dds-testsuite ddx-testsuite		\
+	rcreader-testsuite server-testsuite cgi-util-tests	\
+	ce-functions-testsuite
+
+EXTRA_DIST = $(DIRS_EXTRA) testFile.cc test_config.h.in
+
+CLEANFILES = testout .dodsrc  *.gcda *.gcno
+
+DISTCLEANFILES = test_config.h *.strm *.file tmp.txt
+
+test_config.h: test_config.h.in Makefile
+	sed -e "s%[@]abs_srcdir[@]%${abs_srcdir}%" $< > test_config.h
+
+############################################################################
+# Unit Tests
+#
+
+if CPPUNIT
+UNIT_TESTS = marshT arrayT attrTableT structT sequenceT ddsT dasT	\
+	RegexTest                                                       \
+	ArrayTest AttrTableTest ByteTest MIMEUtilTest ancT DASTest 	\
+	DDSTest	DDXParserTest DODSFilterTest generalUtilTest 		\
+	HTTPCacheTest HTTPConnectTest parserUtilTest RCReaderTest 	\
+	SequenceTest SignalHandlerTest CEFunctionsTest 			\
+	GridGeoConstraintTest ArrayGeoConstraintTest MarshallerTest \
+	ResponseBuilderTest Keywords2Test
+
+#	fdiostreamTest
+
+else
+UNIT_TESTS =
+
+check-local:
+	@echo ""
+	@echo "**********************************************************"
+	@echo "You must have cppunit 1.12.x or greater installed to run *"
+	@echo "check target in unit-tests directory                     *"
+	@echo "**********************************************************"
+	@echo ""
+	
+endif
+
+RegexTest_SOURCES = RegexTest.cc
+RegexTest_LDADD = ../libdap.la $(AM_LDADD)
+
+ArrayTest_SOURCES = ArrayTest.cc
+ArrayTest_LDADD = ../libdap.la $(AM_LDADD)
+
+AttrTableTest_SOURCES = AttrTableTest.cc
+AttrTableTest_LDADD = ../libdap.la $(AM_LDADD)
+
+ByteTest_SOURCES = ByteTest.cc
+ByteTest_LDADD = ../libdap.la $(AM_LDADD)
+
+MIMEUtilTest_SOURCES = MIMEUtilTest.cc
+MIMEUtilTest_LDADD = ../libdap.la $(AM_LDADD)
+
+ancT_SOURCES = ancT.cc
+ancT_LDADD = ../libdapserver.la ../libdap.la $(AM_LDADD)
+
+DASTest_SOURCES = DASTest.cc
+DASTest_LDADD = ../libdap.la $(AM_LDADD)
+
+DDSTest_SOURCES = DDSTest.cc
+DDSTest_LDADD = ../libdap.la $(AM_LDADD)
+
+DDXParserTest_SOURCES = DDXParserTest.cc
+DDXParserTest_CPPFLAGS = $(AM_CPPFLAGS) $(XML2_CFLAGS)
+DDXParserTest_LDADD = ../libdap.la $(AM_LDADD)
+
+DODSFilterTest_SOURCES = DODSFilterTest.cc
+DODSFilterTest_LDADD = ../libdapserver.la ../libdap.la \
+	../tests/libtest-types.a $(AM_LDADD)
+
+ResponseBuilderTest_SOURCES = ResponseBuilderTest.cc
+ResponseBuilderTest_LDADD = ../libdapserver.la ../libdap.la \
+	../tests/libtest-types.a $(AM_LDADD)
+
+Keywords2Test_SOURCES = Keywords2Test.cc
+Keywords2Test_LDADD = ../libdap.la $(AM_LDADD)
+
+generalUtilTest_SOURCES = generalUtilTest.cc
+generalUtilTest_LDADD = ../libdap.la $(AM_LDADD)
+
+HTTPCacheTest_SOURCES = HTTPCacheTest.cc
+HTTPCacheTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+
+HTTPConnectTest_SOURCES = HTTPConnectTest.cc
+HTTPConnectTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+
+parserUtilTest_SOURCES = parserUtilTest.cc
+parserUtilTest_LDADD = ../libdap.la $(AM_LDADD)
+
+RCReaderTest_SOURCES = RCReaderTest.cc
+RCReaderTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+
+SequenceTest_SOURCES = SequenceTest.cc
+SequenceTest_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+SignalHandlerTest_SOURCES = SignalHandlerTest.cc
+SignalHandlerTest_LDADD = ../libdap.la $(AM_LDADD)
+
+arrayT_SOURCES = arrayT.cc
+arrayT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+MarshallerTest_SOURCES = MarshallerTest.cc
+MarshallerTest_LDADD = ../tests/libtest-types.a ../libdapclient.la ../libdap.la $(AM_LDADD)
+
+marshT_SOURCES = marshT.cc
+marshT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+attrTableT_SOURCES = attrTableT.cc
+attrTableT_LDADD = ../tests/libtest-types.a  ../libdap.la $(AM_LDADD)
+
+structT_SOURCES = structT.cc
+structT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+sequenceT_SOURCES = sequenceT.cc
+sequenceT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+ddsT_SOURCES = ddsT.cc
+ddsT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+dasT_SOURCES = dasT.cc
+dasT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+CEFunctionsTest_SOURCES = CEFunctionsTest.cc
+CEFunctionsTest_LDADD = ../tests/libtest-types.a  ../libdap.la $(AM_LDADD)
+
+GridGeoConstraintTest_SOURCES = GridGeoConstraintTest.cc
+GridGeoConstraintTest_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+ArrayGeoConstraintTest_SOURCES = ArrayGeoConstraintTest.cc
+ArrayGeoConstraintTest_LDADD =  ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+
+# fdiostreamTest_SOURCES = fdiostreamTest.cc
+# fdiostreamTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
diff --git a/unit-tests/Makefile.in b/unit-tests/Makefile.in
new file mode 100644
index 0000000..388db7f
--- /dev/null
+++ b/unit-tests/Makefile.in
@@ -0,0 +1,1476 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+ at CPPUNIT_TRUE@am__append_1 = $(CPPUNIT_CFLAGS)
+ at CPPUNIT_TRUE@am__append_2 = $(CPPUNIT_LIBS)
+check_PROGRAMS = $(am__EXEEXT_1)
+TESTS = $(am__EXEEXT_1)
+subdir = unit-tests
+DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+	$(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
+	$(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/btowc.m4 \
+	$(top_srcdir)/gl/m4/codeset.m4 \
+	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/fcntl-o.m4 $(top_srcdir)/gl/m4/glibc21.m4 \
+	$(top_srcdir)/gl/m4/gnulib-common.m4 \
+	$(top_srcdir)/gl/m4/gnulib-comp.m4 \
+	$(top_srcdir)/gl/m4/gnulib-tool.m4 \
+	$(top_srcdir)/gl/m4/include_next.m4 \
+	$(top_srcdir)/gl/m4/langinfo_h.m4 \
+	$(top_srcdir)/gl/m4/localcharset.m4 \
+	$(top_srcdir)/gl/m4/locale-fr.m4 \
+	$(top_srcdir)/gl/m4/locale-ja.m4 \
+	$(top_srcdir)/gl/m4/locale-zh.m4 \
+	$(top_srcdir)/gl/m4/longlong.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+	$(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+	$(top_srcdir)/gl/m4/mbstate_t.m4 \
+	$(top_srcdir)/gl/m4/multiarch.m4 \
+	$(top_srcdir)/gl/m4/nl_langinfo.m4 \
+	$(top_srcdir)/gl/m4/regex.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+	$(top_srcdir)/gl/m4/stdbool.m4 $(top_srcdir)/gl/m4/stddef_h.m4 \
+	$(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/stdlib_h.m4 \
+	$(top_srcdir)/gl/m4/unistd_h.m4 \
+	$(top_srcdir)/gl/m4/warn-on-use.m4 \
+	$(top_srcdir)/gl/m4/wchar_h.m4 $(top_srcdir)/gl/m4/wchar_t.m4 \
+	$(top_srcdir)/gl/m4/wcrtomb.m4 $(top_srcdir)/gl/m4/wctype_h.m4 \
+	$(top_srcdir)/gl/m4/wint_t.m4 $(top_srcdir)/conf/acinclude.m4 \
+	$(top_srcdir)/conf/check_zlib.m4 $(top_srcdir)/conf/cppunit.m4 \
+	$(top_srcdir)/conf/libtool.m4 $(top_srcdir)/conf/ltoptions.m4 \
+	$(top_srcdir)/conf/ltsugar.m4 $(top_srcdir)/conf/ltversion.m4 \
+	$(top_srcdir)/conf/lt~obsolete.m4 $(top_srcdir)/conf/pkg.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+	$(top_builddir)/dods-datatypes-config.h \
+	$(top_builddir)/xdr-datatypes-config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+ at CPPUNIT_TRUE@am__EXEEXT_1 = marshT$(EXEEXT) arrayT$(EXEEXT) \
+ at CPPUNIT_TRUE@	attrTableT$(EXEEXT) structT$(EXEEXT) \
+ at CPPUNIT_TRUE@	sequenceT$(EXEEXT) ddsT$(EXEEXT) dasT$(EXEEXT) \
+ at CPPUNIT_TRUE@	RegexTest$(EXEEXT) ArrayTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	AttrTableTest$(EXEEXT) ByteTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	MIMEUtilTest$(EXEEXT) ancT$(EXEEXT) \
+ at CPPUNIT_TRUE@	DASTest$(EXEEXT) DDSTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	DDXParserTest$(EXEEXT) DODSFilterTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	generalUtilTest$(EXEEXT) HTTPCacheTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	HTTPConnectTest$(EXEEXT) parserUtilTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	RCReaderTest$(EXEEXT) SequenceTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	SignalHandlerTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	CEFunctionsTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	GridGeoConstraintTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	ArrayGeoConstraintTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	MarshallerTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	ResponseBuilderTest$(EXEEXT) \
+ at CPPUNIT_TRUE@	Keywords2Test$(EXEEXT)
+am_ArrayGeoConstraintTest_OBJECTS = ArrayGeoConstraintTest.$(OBJEXT)
+ArrayGeoConstraintTest_OBJECTS = $(am_ArrayGeoConstraintTest_OBJECTS)
+am__DEPENDENCIES_1 =
+ at CPPUNIT_TRUE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)
+ArrayGeoConstraintTest_DEPENDENCIES = ../tests/libtest-types.a \
+	../libdap.la $(am__DEPENDENCIES_3)
+am_ArrayTest_OBJECTS = ArrayTest.$(OBJEXT)
+ArrayTest_OBJECTS = $(am_ArrayTest_OBJECTS)
+ArrayTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_AttrTableTest_OBJECTS = AttrTableTest.$(OBJEXT)
+AttrTableTest_OBJECTS = $(am_AttrTableTest_OBJECTS)
+AttrTableTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_ByteTest_OBJECTS = ByteTest.$(OBJEXT)
+ByteTest_OBJECTS = $(am_ByteTest_OBJECTS)
+ByteTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_CEFunctionsTest_OBJECTS = CEFunctionsTest.$(OBJEXT)
+CEFunctionsTest_OBJECTS = $(am_CEFunctionsTest_OBJECTS)
+CEFunctionsTest_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_DASTest_OBJECTS = DASTest.$(OBJEXT)
+DASTest_OBJECTS = $(am_DASTest_OBJECTS)
+DASTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_DDSTest_OBJECTS = DDSTest.$(OBJEXT)
+DDSTest_OBJECTS = $(am_DDSTest_OBJECTS)
+DDSTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_DDXParserTest_OBJECTS = DDXParserTest-DDXParserTest.$(OBJEXT)
+DDXParserTest_OBJECTS = $(am_DDXParserTest_OBJECTS)
+DDXParserTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_DODSFilterTest_OBJECTS = DODSFilterTest.$(OBJEXT)
+DODSFilterTest_OBJECTS = $(am_DODSFilterTest_OBJECTS)
+DODSFilterTest_DEPENDENCIES = ../libdapserver.la ../libdap.la \
+	../tests/libtest-types.a $(am__DEPENDENCIES_3)
+am_GridGeoConstraintTest_OBJECTS = GridGeoConstraintTest.$(OBJEXT)
+GridGeoConstraintTest_OBJECTS = $(am_GridGeoConstraintTest_OBJECTS)
+GridGeoConstraintTest_DEPENDENCIES = ../tests/libtest-types.a \
+	../libdap.la $(am__DEPENDENCIES_3)
+am_HTTPCacheTest_OBJECTS = HTTPCacheTest.$(OBJEXT)
+HTTPCacheTest_OBJECTS = $(am_HTTPCacheTest_OBJECTS)
+HTTPCacheTest_DEPENDENCIES = ../libdapclient.la ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_HTTPConnectTest_OBJECTS = HTTPConnectTest.$(OBJEXT)
+HTTPConnectTest_OBJECTS = $(am_HTTPConnectTest_OBJECTS)
+HTTPConnectTest_DEPENDENCIES = ../libdapclient.la ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_Keywords2Test_OBJECTS = Keywords2Test.$(OBJEXT)
+Keywords2Test_OBJECTS = $(am_Keywords2Test_OBJECTS)
+Keywords2Test_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_MIMEUtilTest_OBJECTS = MIMEUtilTest.$(OBJEXT)
+MIMEUtilTest_OBJECTS = $(am_MIMEUtilTest_OBJECTS)
+MIMEUtilTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_MarshallerTest_OBJECTS = MarshallerTest.$(OBJEXT)
+MarshallerTest_OBJECTS = $(am_MarshallerTest_OBJECTS)
+MarshallerTest_DEPENDENCIES = ../tests/libtest-types.a \
+	../libdapclient.la ../libdap.la $(am__DEPENDENCIES_3)
+am_RCReaderTest_OBJECTS = RCReaderTest.$(OBJEXT)
+RCReaderTest_OBJECTS = $(am_RCReaderTest_OBJECTS)
+RCReaderTest_DEPENDENCIES = ../libdapclient.la ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_RegexTest_OBJECTS = RegexTest.$(OBJEXT)
+RegexTest_OBJECTS = $(am_RegexTest_OBJECTS)
+RegexTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_ResponseBuilderTest_OBJECTS = ResponseBuilderTest.$(OBJEXT)
+ResponseBuilderTest_OBJECTS = $(am_ResponseBuilderTest_OBJECTS)
+ResponseBuilderTest_DEPENDENCIES = ../libdapserver.la ../libdap.la \
+	../tests/libtest-types.a $(am__DEPENDENCIES_3)
+am_SequenceTest_OBJECTS = SequenceTest.$(OBJEXT)
+SequenceTest_OBJECTS = $(am_SequenceTest_OBJECTS)
+SequenceTest_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_SignalHandlerTest_OBJECTS = SignalHandlerTest.$(OBJEXT)
+SignalHandlerTest_OBJECTS = $(am_SignalHandlerTest_OBJECTS)
+SignalHandlerTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_ancT_OBJECTS = ancT.$(OBJEXT)
+ancT_OBJECTS = $(am_ancT_OBJECTS)
+ancT_DEPENDENCIES = ../libdapserver.la ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_arrayT_OBJECTS = arrayT.$(OBJEXT)
+arrayT_OBJECTS = $(am_arrayT_OBJECTS)
+arrayT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_attrTableT_OBJECTS = attrTableT.$(OBJEXT)
+attrTableT_OBJECTS = $(am_attrTableT_OBJECTS)
+attrTableT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_dasT_OBJECTS = dasT.$(OBJEXT)
+dasT_OBJECTS = $(am_dasT_OBJECTS)
+dasT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_ddsT_OBJECTS = ddsT.$(OBJEXT)
+ddsT_OBJECTS = $(am_ddsT_OBJECTS)
+ddsT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_generalUtilTest_OBJECTS = generalUtilTest.$(OBJEXT)
+generalUtilTest_OBJECTS = $(am_generalUtilTest_OBJECTS)
+generalUtilTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_marshT_OBJECTS = marshT.$(OBJEXT)
+marshT_OBJECTS = $(am_marshT_OBJECTS)
+marshT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_parserUtilTest_OBJECTS = parserUtilTest.$(OBJEXT)
+parserUtilTest_OBJECTS = $(am_parserUtilTest_OBJECTS)
+parserUtilTest_DEPENDENCIES = ../libdap.la $(am__DEPENDENCIES_3)
+am_sequenceT_OBJECTS = sequenceT.$(OBJEXT)
+sequenceT_OBJECTS = $(am_sequenceT_OBJECTS)
+sequenceT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+am_structT_OBJECTS = structT.$(OBJEXT)
+structT_OBJECTS = $(am_structT_OBJECTS)
+structT_DEPENDENCIES = ../tests/libtest-types.a ../libdap.la \
+	$(am__DEPENDENCIES_3)
+DEFAULT_INCLUDES = -I. at am__isrc@ -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/conf/depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+	--mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+	$(LDFLAGS) -o $@
+SOURCES = $(ArrayGeoConstraintTest_SOURCES) $(ArrayTest_SOURCES) \
+	$(AttrTableTest_SOURCES) $(ByteTest_SOURCES) \
+	$(CEFunctionsTest_SOURCES) $(DASTest_SOURCES) \
+	$(DDSTest_SOURCES) $(DDXParserTest_SOURCES) \
+	$(DODSFilterTest_SOURCES) $(GridGeoConstraintTest_SOURCES) \
+	$(HTTPCacheTest_SOURCES) $(HTTPConnectTest_SOURCES) \
+	$(Keywords2Test_SOURCES) $(MIMEUtilTest_SOURCES) \
+	$(MarshallerTest_SOURCES) $(RCReaderTest_SOURCES) \
+	$(RegexTest_SOURCES) $(ResponseBuilderTest_SOURCES) \
+	$(SequenceTest_SOURCES) $(SignalHandlerTest_SOURCES) \
+	$(ancT_SOURCES) $(arrayT_SOURCES) $(attrTableT_SOURCES) \
+	$(dasT_SOURCES) $(ddsT_SOURCES) $(generalUtilTest_SOURCES) \
+	$(marshT_SOURCES) $(parserUtilTest_SOURCES) \
+	$(sequenceT_SOURCES) $(structT_SOURCES)
+DIST_SOURCES = $(ArrayGeoConstraintTest_SOURCES) $(ArrayTest_SOURCES) \
+	$(AttrTableTest_SOURCES) $(ByteTest_SOURCES) \
+	$(CEFunctionsTest_SOURCES) $(DASTest_SOURCES) \
+	$(DDSTest_SOURCES) $(DDXParserTest_SOURCES) \
+	$(DODSFilterTest_SOURCES) $(GridGeoConstraintTest_SOURCES) \
+	$(HTTPCacheTest_SOURCES) $(HTTPConnectTest_SOURCES) \
+	$(Keywords2Test_SOURCES) $(MIMEUtilTest_SOURCES) \
+	$(MarshallerTest_SOURCES) $(RCReaderTest_SOURCES) \
+	$(RegexTest_SOURCES) $(ResponseBuilderTest_SOURCES) \
+	$(SequenceTest_SOURCES) $(SignalHandlerTest_SOURCES) \
+	$(ancT_SOURCES) $(arrayT_SOURCES) $(attrTableT_SOURCES) \
+	$(dasT_SOURCES) $(ddsT_SOURCES) $(generalUtilTest_SOURCES) \
+	$(marshT_SOURCES) $(parserUtilTest_SOURCES) \
+	$(sequenceT_SOURCES) $(structT_SOURCES)
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+	html-recursive info-recursive install-data-recursive \
+	install-dvi-recursive install-exec-recursive \
+	install-html-recursive install-info-recursive \
+	install-pdf-recursive install-ps-recursive install-recursive \
+	installcheck-recursive installdirs-recursive pdf-recursive \
+	ps-recursive uninstall-recursive
+HEADERS = $(noinst_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive	\
+  distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+	$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
+	distdir
+ETAGS = etags
+CTAGS = ctags
+am__tty_colors = \
+red=; grn=; lgn=; blu=; std=
+DIST_SUBDIRS = $(SUBDIRS)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+am__relativize = \
+  dir0=`pwd`; \
+  sed_first='s,^\([^/]*\)/.*$$,\1,'; \
+  sed_rest='s,^[^/]*/*,,'; \
+  sed_last='s,^.*/\([^/]*\)$$,\1,'; \
+  sed_butlast='s,/*[^/]*$$,,'; \
+  while test -n "$$dir1"; do \
+    first=`echo "$$dir1" | sed -e "$$sed_first"`; \
+    if test "$$first" != "."; then \
+      if test "$$first" = ".."; then \
+        dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
+        dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
+      else \
+        first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
+        if test "$$first2" = "$$first"; then \
+          dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
+        else \
+          dir2="../$$dir2"; \
+        fi; \
+        dir0="$$dir0"/"$$first"; \
+      fi; \
+    fi; \
+    dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
+  done; \
+  reldir="$$dir2"
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLIENTLIB_AGE = @CLIENTLIB_AGE@
+CLIENTLIB_CURRENT = @CLIENTLIB_CURRENT@
+CLIENTLIB_REVISION = @CLIENTLIB_REVISION@
+CLIENTLIB_VERSION = @CLIENTLIB_VERSION@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
+CPPUNIT_CONFIG = @CPPUNIT_CONFIG@
+CPPUNIT_LIBS = @CPPUNIT_LIBS@
+CURL_CFLAGS = @CURL_CFLAGS@
+CURL_LIBS = @CURL_LIBS@
+CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DAPLIB_AGE = @DAPLIB_AGE@
+DAPLIB_CURRENT = @DAPLIB_CURRENT@
+DAPLIB_REVISION = @DAPLIB_REVISION@
+DAP_PROTOCOL_VERSION = @DAP_PROTOCOL_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVR = @DVR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EVAL = @EVAL@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIBC21 = @GLIBC21@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDAP_VERSION = @LIBDAP_VERSION@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_MAJOR_VERSION = @PACKAGE_MAJOR_VERSION@
+PACKAGE_MINOR_VERSION = @PACKAGE_MINOR_VERSION@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_SUBMINOR_VERSION = @PACKAGE_SUBMINOR_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVERLIB_AGE = @SERVERLIB_AGE@
+SERVERLIB_CURRENT = @SERVERLIB_CURRENT@
+SERVERLIB_REVISION = @SERVERLIB_REVISION@
+SERVERLIB_VERSION = @SERVERLIB_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+XML2_STATIC_LIBS = @XML2_STATIC_LIBS@
+YACC = @YACC@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+curlprivatelibs = @curlprivatelibs@
+curlprivatereq = @curlprivatereq@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xmlprivatelibs = @xmlprivatelibs@
+xmlprivatereq = @xmlprivatereq@
+SUBDIRS = cache-testsuite
+
+# Tests
+AUTOMAKE_OPTIONS = foreign
+
+# Headers in 'tests' are used by the arrayT unit tests.
+AM_CPPFLAGS = -I$(top_srcdir)/GNU -I$(top_srcdir) \
+	-I$(top_srcdir)/tests $(am__append_1)
+AM_LDADD = $(am__append_2)
+
+# These are not used by automake but are often useful for certain types of
+# debugging. Set CXXFLAGS to this in the nightly build using export ...
+CXXFLAGS_DEBUG = -g3 -O0 -fno-defer-pop -Wall -W -Wcast-align -Werror
+TEST_COV_FLAGS = -ftest-coverage -fprofile-arcs
+noinst_HEADERS = test_config.h
+DIRS_EXTRA = das-testsuite dds-testsuite ddx-testsuite		\
+	rcreader-testsuite server-testsuite cgi-util-tests	\
+	ce-functions-testsuite
+
+EXTRA_DIST = $(DIRS_EXTRA) testFile.cc test_config.h.in
+CLEANFILES = testout .dodsrc  *.gcda *.gcno
+DISTCLEANFILES = test_config.h *.strm *.file tmp.txt
+
+#	fdiostreamTest
+ at CPPUNIT_FALSE@UNIT_TESTS = 
+
+############################################################################
+# Unit Tests
+#
+ at CPPUNIT_TRUE@UNIT_TESTS = marshT arrayT attrTableT structT sequenceT ddsT dasT	\
+ at CPPUNIT_TRUE@	RegexTest                                                       \
+ at CPPUNIT_TRUE@	ArrayTest AttrTableTest ByteTest MIMEUtilTest ancT DASTest 	\
+ at CPPUNIT_TRUE@	DDSTest	DDXParserTest DODSFilterTest generalUtilTest 		\
+ at CPPUNIT_TRUE@	HTTPCacheTest HTTPConnectTest parserUtilTest RCReaderTest 	\
+ at CPPUNIT_TRUE@	SequenceTest SignalHandlerTest CEFunctionsTest 			\
+ at CPPUNIT_TRUE@	GridGeoConstraintTest ArrayGeoConstraintTest MarshallerTest \
+ at CPPUNIT_TRUE@	ResponseBuilderTest Keywords2Test
+
+RegexTest_SOURCES = RegexTest.cc
+RegexTest_LDADD = ../libdap.la $(AM_LDADD)
+ArrayTest_SOURCES = ArrayTest.cc
+ArrayTest_LDADD = ../libdap.la $(AM_LDADD)
+AttrTableTest_SOURCES = AttrTableTest.cc
+AttrTableTest_LDADD = ../libdap.la $(AM_LDADD)
+ByteTest_SOURCES = ByteTest.cc
+ByteTest_LDADD = ../libdap.la $(AM_LDADD)
+MIMEUtilTest_SOURCES = MIMEUtilTest.cc
+MIMEUtilTest_LDADD = ../libdap.la $(AM_LDADD)
+ancT_SOURCES = ancT.cc
+ancT_LDADD = ../libdapserver.la ../libdap.la $(AM_LDADD)
+DASTest_SOURCES = DASTest.cc
+DASTest_LDADD = ../libdap.la $(AM_LDADD)
+DDSTest_SOURCES = DDSTest.cc
+DDSTest_LDADD = ../libdap.la $(AM_LDADD)
+DDXParserTest_SOURCES = DDXParserTest.cc
+DDXParserTest_CPPFLAGS = $(AM_CPPFLAGS) $(XML2_CFLAGS)
+DDXParserTest_LDADD = ../libdap.la $(AM_LDADD)
+DODSFilterTest_SOURCES = DODSFilterTest.cc
+DODSFilterTest_LDADD = ../libdapserver.la ../libdap.la \
+	../tests/libtest-types.a $(AM_LDADD)
+
+ResponseBuilderTest_SOURCES = ResponseBuilderTest.cc
+ResponseBuilderTest_LDADD = ../libdapserver.la ../libdap.la \
+	../tests/libtest-types.a $(AM_LDADD)
+
+Keywords2Test_SOURCES = Keywords2Test.cc
+Keywords2Test_LDADD = ../libdap.la $(AM_LDADD)
+generalUtilTest_SOURCES = generalUtilTest.cc
+generalUtilTest_LDADD = ../libdap.la $(AM_LDADD)
+HTTPCacheTest_SOURCES = HTTPCacheTest.cc
+HTTPCacheTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+HTTPConnectTest_SOURCES = HTTPConnectTest.cc
+HTTPConnectTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+parserUtilTest_SOURCES = parserUtilTest.cc
+parserUtilTest_LDADD = ../libdap.la $(AM_LDADD)
+RCReaderTest_SOURCES = RCReaderTest.cc
+RCReaderTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+SequenceTest_SOURCES = SequenceTest.cc
+SequenceTest_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+SignalHandlerTest_SOURCES = SignalHandlerTest.cc
+SignalHandlerTest_LDADD = ../libdap.la $(AM_LDADD)
+arrayT_SOURCES = arrayT.cc
+arrayT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+MarshallerTest_SOURCES = MarshallerTest.cc
+MarshallerTest_LDADD = ../tests/libtest-types.a ../libdapclient.la ../libdap.la $(AM_LDADD)
+marshT_SOURCES = marshT.cc
+marshT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+attrTableT_SOURCES = attrTableT.cc
+attrTableT_LDADD = ../tests/libtest-types.a  ../libdap.la $(AM_LDADD)
+structT_SOURCES = structT.cc
+structT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+sequenceT_SOURCES = sequenceT.cc
+sequenceT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+ddsT_SOURCES = ddsT.cc
+ddsT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+dasT_SOURCES = dasT.cc
+dasT_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+CEFunctionsTest_SOURCES = CEFunctionsTest.cc
+CEFunctionsTest_LDADD = ../tests/libtest-types.a  ../libdap.la $(AM_LDADD)
+GridGeoConstraintTest_SOURCES = GridGeoConstraintTest.cc
+GridGeoConstraintTest_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+ArrayGeoConstraintTest_SOURCES = ArrayGeoConstraintTest.cc
+ArrayGeoConstraintTest_LDADD = ../tests/libtest-types.a ../libdap.la $(AM_LDADD)
+all: all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign unit-tests/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --foreign unit-tests/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+clean-checkPROGRAMS:
+	@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
+	echo " rm -f" $$list; \
+	rm -f $$list || exit $$?; \
+	test -n "$(EXEEXT)" || exit 0; \
+	list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
+	echo " rm -f" $$list; \
+	rm -f $$list
+ArrayGeoConstraintTest$(EXEEXT): $(ArrayGeoConstraintTest_OBJECTS) $(ArrayGeoConstraintTest_DEPENDENCIES) 
+	@rm -f ArrayGeoConstraintTest$(EXEEXT)
+	$(CXXLINK) $(ArrayGeoConstraintTest_OBJECTS) $(ArrayGeoConstraintTest_LDADD) $(LIBS)
+ArrayTest$(EXEEXT): $(ArrayTest_OBJECTS) $(ArrayTest_DEPENDENCIES) 
+	@rm -f ArrayTest$(EXEEXT)
+	$(CXXLINK) $(ArrayTest_OBJECTS) $(ArrayTest_LDADD) $(LIBS)
+AttrTableTest$(EXEEXT): $(AttrTableTest_OBJECTS) $(AttrTableTest_DEPENDENCIES) 
+	@rm -f AttrTableTest$(EXEEXT)
+	$(CXXLINK) $(AttrTableTest_OBJECTS) $(AttrTableTest_LDADD) $(LIBS)
+ByteTest$(EXEEXT): $(ByteTest_OBJECTS) $(ByteTest_DEPENDENCIES) 
+	@rm -f ByteTest$(EXEEXT)
+	$(CXXLINK) $(ByteTest_OBJECTS) $(ByteTest_LDADD) $(LIBS)
+CEFunctionsTest$(EXEEXT): $(CEFunctionsTest_OBJECTS) $(CEFunctionsTest_DEPENDENCIES) 
+	@rm -f CEFunctionsTest$(EXEEXT)
+	$(CXXLINK) $(CEFunctionsTest_OBJECTS) $(CEFunctionsTest_LDADD) $(LIBS)
+DASTest$(EXEEXT): $(DASTest_OBJECTS) $(DASTest_DEPENDENCIES) 
+	@rm -f DASTest$(EXEEXT)
+	$(CXXLINK) $(DASTest_OBJECTS) $(DASTest_LDADD) $(LIBS)
+DDSTest$(EXEEXT): $(DDSTest_OBJECTS) $(DDSTest_DEPENDENCIES) 
+	@rm -f DDSTest$(EXEEXT)
+	$(CXXLINK) $(DDSTest_OBJECTS) $(DDSTest_LDADD) $(LIBS)
+DDXParserTest$(EXEEXT): $(DDXParserTest_OBJECTS) $(DDXParserTest_DEPENDENCIES) 
+	@rm -f DDXParserTest$(EXEEXT)
+	$(CXXLINK) $(DDXParserTest_OBJECTS) $(DDXParserTest_LDADD) $(LIBS)
+DODSFilterTest$(EXEEXT): $(DODSFilterTest_OBJECTS) $(DODSFilterTest_DEPENDENCIES) 
+	@rm -f DODSFilterTest$(EXEEXT)
+	$(CXXLINK) $(DODSFilterTest_OBJECTS) $(DODSFilterTest_LDADD) $(LIBS)
+GridGeoConstraintTest$(EXEEXT): $(GridGeoConstraintTest_OBJECTS) $(GridGeoConstraintTest_DEPENDENCIES) 
+	@rm -f GridGeoConstraintTest$(EXEEXT)
+	$(CXXLINK) $(GridGeoConstraintTest_OBJECTS) $(GridGeoConstraintTest_LDADD) $(LIBS)
+HTTPCacheTest$(EXEEXT): $(HTTPCacheTest_OBJECTS) $(HTTPCacheTest_DEPENDENCIES) 
+	@rm -f HTTPCacheTest$(EXEEXT)
+	$(CXXLINK) $(HTTPCacheTest_OBJECTS) $(HTTPCacheTest_LDADD) $(LIBS)
+HTTPConnectTest$(EXEEXT): $(HTTPConnectTest_OBJECTS) $(HTTPConnectTest_DEPENDENCIES) 
+	@rm -f HTTPConnectTest$(EXEEXT)
+	$(CXXLINK) $(HTTPConnectTest_OBJECTS) $(HTTPConnectTest_LDADD) $(LIBS)
+Keywords2Test$(EXEEXT): $(Keywords2Test_OBJECTS) $(Keywords2Test_DEPENDENCIES) 
+	@rm -f Keywords2Test$(EXEEXT)
+	$(CXXLINK) $(Keywords2Test_OBJECTS) $(Keywords2Test_LDADD) $(LIBS)
+MIMEUtilTest$(EXEEXT): $(MIMEUtilTest_OBJECTS) $(MIMEUtilTest_DEPENDENCIES) 
+	@rm -f MIMEUtilTest$(EXEEXT)
+	$(CXXLINK) $(MIMEUtilTest_OBJECTS) $(MIMEUtilTest_LDADD) $(LIBS)
+MarshallerTest$(EXEEXT): $(MarshallerTest_OBJECTS) $(MarshallerTest_DEPENDENCIES) 
+	@rm -f MarshallerTest$(EXEEXT)
+	$(CXXLINK) $(MarshallerTest_OBJECTS) $(MarshallerTest_LDADD) $(LIBS)
+RCReaderTest$(EXEEXT): $(RCReaderTest_OBJECTS) $(RCReaderTest_DEPENDENCIES) 
+	@rm -f RCReaderTest$(EXEEXT)
+	$(CXXLINK) $(RCReaderTest_OBJECTS) $(RCReaderTest_LDADD) $(LIBS)
+RegexTest$(EXEEXT): $(RegexTest_OBJECTS) $(RegexTest_DEPENDENCIES) 
+	@rm -f RegexTest$(EXEEXT)
+	$(CXXLINK) $(RegexTest_OBJECTS) $(RegexTest_LDADD) $(LIBS)
+ResponseBuilderTest$(EXEEXT): $(ResponseBuilderTest_OBJECTS) $(ResponseBuilderTest_DEPENDENCIES) 
+	@rm -f ResponseBuilderTest$(EXEEXT)
+	$(CXXLINK) $(ResponseBuilderTest_OBJECTS) $(ResponseBuilderTest_LDADD) $(LIBS)
+SequenceTest$(EXEEXT): $(SequenceTest_OBJECTS) $(SequenceTest_DEPENDENCIES) 
+	@rm -f SequenceTest$(EXEEXT)
+	$(CXXLINK) $(SequenceTest_OBJECTS) $(SequenceTest_LDADD) $(LIBS)
+SignalHandlerTest$(EXEEXT): $(SignalHandlerTest_OBJECTS) $(SignalHandlerTest_DEPENDENCIES) 
+	@rm -f SignalHandlerTest$(EXEEXT)
+	$(CXXLINK) $(SignalHandlerTest_OBJECTS) $(SignalHandlerTest_LDADD) $(LIBS)
+ancT$(EXEEXT): $(ancT_OBJECTS) $(ancT_DEPENDENCIES) 
+	@rm -f ancT$(EXEEXT)
+	$(CXXLINK) $(ancT_OBJECTS) $(ancT_LDADD) $(LIBS)
+arrayT$(EXEEXT): $(arrayT_OBJECTS) $(arrayT_DEPENDENCIES) 
+	@rm -f arrayT$(EXEEXT)
+	$(CXXLINK) $(arrayT_OBJECTS) $(arrayT_LDADD) $(LIBS)
+attrTableT$(EXEEXT): $(attrTableT_OBJECTS) $(attrTableT_DEPENDENCIES) 
+	@rm -f attrTableT$(EXEEXT)
+	$(CXXLINK) $(attrTableT_OBJECTS) $(attrTableT_LDADD) $(LIBS)
+dasT$(EXEEXT): $(dasT_OBJECTS) $(dasT_DEPENDENCIES) 
+	@rm -f dasT$(EXEEXT)
+	$(CXXLINK) $(dasT_OBJECTS) $(dasT_LDADD) $(LIBS)
+ddsT$(EXEEXT): $(ddsT_OBJECTS) $(ddsT_DEPENDENCIES) 
+	@rm -f ddsT$(EXEEXT)
+	$(CXXLINK) $(ddsT_OBJECTS) $(ddsT_LDADD) $(LIBS)
+generalUtilTest$(EXEEXT): $(generalUtilTest_OBJECTS) $(generalUtilTest_DEPENDENCIES) 
+	@rm -f generalUtilTest$(EXEEXT)
+	$(CXXLINK) $(generalUtilTest_OBJECTS) $(generalUtilTest_LDADD) $(LIBS)
+marshT$(EXEEXT): $(marshT_OBJECTS) $(marshT_DEPENDENCIES) 
+	@rm -f marshT$(EXEEXT)
+	$(CXXLINK) $(marshT_OBJECTS) $(marshT_LDADD) $(LIBS)
+parserUtilTest$(EXEEXT): $(parserUtilTest_OBJECTS) $(parserUtilTest_DEPENDENCIES) 
+	@rm -f parserUtilTest$(EXEEXT)
+	$(CXXLINK) $(parserUtilTest_OBJECTS) $(parserUtilTest_LDADD) $(LIBS)
+sequenceT$(EXEEXT): $(sequenceT_OBJECTS) $(sequenceT_DEPENDENCIES) 
+	@rm -f sequenceT$(EXEEXT)
+	$(CXXLINK) $(sequenceT_OBJECTS) $(sequenceT_LDADD) $(LIBS)
+structT$(EXEEXT): $(structT_OBJECTS) $(structT_DEPENDENCIES) 
+	@rm -f structT$(EXEEXT)
+	$(CXXLINK) $(structT_OBJECTS) $(structT_LDADD) $(LIBS)
+
+mostlyclean-compile:
+	-rm -f *.$(OBJEXT)
+
+distclean-compile:
+	-rm -f *.tab.c
+
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ArrayGeoConstraintTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ArrayTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/AttrTableTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ByteTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/CEFunctionsTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DASTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DDSTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DDXParserTest-DDXParserTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/DODSFilterTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/GridGeoConstraintTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/HTTPCacheTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/HTTPConnectTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/Keywords2Test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MIMEUtilTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/MarshallerTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RCReaderTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/RegexTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ResponseBuilderTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SequenceTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/SignalHandlerTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ancT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/arrayT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/attrTableT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/dasT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ddsT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/generalUtilTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/marshT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/parserUtilTest.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sequenceT.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/structT.Po at am__quote@
+
+.cc.o:
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+ at am__fastdepCXX_TRUE@	$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+ at am__fastdepCXX_TRUE@	$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(LTCXXCOMPILE) -c -o $@ $<
+
+DDXParserTest-DDXParserTest.o: DDXParserTest.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DDXParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT DDXParserTest-DDXParserTest.o -MD -MP -MF $(DEPDIR)/DDXParserTest-DDXParserTest.Tpo -c -o DDXParserTest-DDXParserTest.o `test -f 'DDXParserTest.cc' || echo '$(srcdir)/'`DDXParserTest.cc
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/DDXParserTest-DDXParserTest.Tpo $(DEPDIR)/DDXParserTest-DDXParserTest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DDXParserTest.cc' object='DDXParserTest-DDXParserTest.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DDXParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o DDXParserTest-DDXParserTest.o `test -f 'DDXParserTest.cc' || echo '$(srcdir)/'`DDXParserTest.cc
+
+DDXParserTest-DDXParserTest.obj: DDXParserTest.cc
+ at am__fastdepCXX_TRUE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DDXParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT DDXParserTest-DDXParserTest.obj -MD -MP -MF $(DEPDIR)/DDXParserTest-DDXParserTest.Tpo -c -o DDXParserTest-DDXParserTest.obj `if test -f 'DDXParserTest.cc'; then $(CYGPATH_W) 'DDXParserTest.cc'; else $(CYGPATH_W) '$(srcdir)/DDXParserTest.cc'; fi`
+ at am__fastdepCXX_TRUE@	$(am__mv) $(DEPDIR)/DDXParserTest-DDXParserTest.Tpo $(DEPDIR)/DDXParserTest-DDXParserTest.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='DDXParserTest.cc' object='DDXParserTest-DDXParserTest.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DDXParserTest_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o DDXParserTest-DDXParserTest.obj `if test -f 'DDXParserTest.cc'; then $(CYGPATH_W) 'DDXParserTest.cc'; else $(CYGPATH_W) '$(srcdir)/DDXParserTest.cc'; fi`
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+#     (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	target=`echo $@ | sed s/-recursive//`; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    dot_seen=yes; \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done; \
+	if test "$$dot_seen" = "no"; then \
+	  $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+	fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+	@failcom='exit 1'; \
+	for f in x $$MAKEFLAGS; do \
+	  case $$f in \
+	    *=* | --[!k]*);; \
+	    *k*) failcom='fail=yes';; \
+	  esac; \
+	done; \
+	dot_seen=no; \
+	case "$@" in \
+	  distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+	  *) list='$(SUBDIRS)' ;; \
+	esac; \
+	rev=''; for subdir in $$list; do \
+	  if test "$$subdir" = "."; then :; else \
+	    rev="$$subdir $$rev"; \
+	  fi; \
+	done; \
+	rev="$$rev ."; \
+	target=`echo $@ | sed s/-recursive//`; \
+	for subdir in $$rev; do \
+	  echo "Making $$target in $$subdir"; \
+	  if test "$$subdir" = "."; then \
+	    local_target="$$target-am"; \
+	  else \
+	    local_target="$$target"; \
+	  fi; \
+	  ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+	  || eval $$failcom; \
+	done && test -z "$$fail"
+tags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+	done
+ctags-recursive:
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+	done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+	list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	set x; \
+	here=`pwd`; \
+	if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+	  include_option=--etags-include; \
+	  empty_fix=.; \
+	else \
+	  include_option=--include; \
+	  empty_fix=; \
+	fi; \
+	list='$(SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test ! -f $$subdir/TAGS || \
+	      set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+	  fi; \
+	done; \
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	shift; \
+	if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+	  test -n "$$unique" || unique=$$empty_fix; \
+	  if test $$# -gt 0; then \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      "$$@" $$unique; \
+	  else \
+	    $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+	      $$unique; \
+	  fi; \
+	fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES)  $(TAGS_DEPENDENCIES) \
+		$(TAGS_FILES) $(LISP)
+	list='$(SOURCES) $(HEADERS)  $(LISP) $(TAGS_FILES)'; \
+	unique=`for i in $$list; do \
+	    if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+	  done | \
+	  $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+	      END { if (nonempty) { for (i in files) print i; }; }'`; \
+	test -z "$(CTAGS_ARGS)$$unique" \
+	  || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+	     $$unique
+
+GTAGS:
+	here=`$(am__cd) $(top_builddir) && pwd` \
+	  && $(am__cd) $(top_srcdir) \
+	  && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+check-TESTS: $(TESTS)
+	@failed=0; all=0; xfail=0; xpass=0; skip=0; \
+	srcdir=$(srcdir); export srcdir; \
+	list=' $(TESTS) '; \
+	$(am__tty_colors); \
+	if test -n "$$list"; then \
+	  for tst in $$list; do \
+	    if test -f ./$$tst; then dir=./; \
+	    elif test -f $$tst; then dir=; \
+	    else dir="$(srcdir)/"; fi; \
+	    if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xpass=`expr $$xpass + 1`; \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=XPASS; \
+	      ;; \
+	      *) \
+		col=$$grn; res=PASS; \
+	      ;; \
+	      esac; \
+	    elif test $$? -ne 77; then \
+	      all=`expr $$all + 1`; \
+	      case " $(XFAIL_TESTS) " in \
+	      *[\ \	]$$tst[\ \	]*) \
+		xfail=`expr $$xfail + 1`; \
+		col=$$lgn; res=XFAIL; \
+	      ;; \
+	      *) \
+		failed=`expr $$failed + 1`; \
+		col=$$red; res=FAIL; \
+	      ;; \
+	      esac; \
+	    else \
+	      skip=`expr $$skip + 1`; \
+	      col=$$blu; res=SKIP; \
+	    fi; \
+	    echo "$${col}$$res$${std}: $$tst"; \
+	  done; \
+	  if test "$$all" -eq 1; then \
+	    tests="test"; \
+	    All=""; \
+	  else \
+	    tests="tests"; \
+	    All="All "; \
+	  fi; \
+	  if test "$$failed" -eq 0; then \
+	    if test "$$xfail" -eq 0; then \
+	      banner="$$All$$all $$tests passed"; \
+	    else \
+	      if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+	      banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
+	    fi; \
+	  else \
+	    if test "$$xpass" -eq 0; then \
+	      banner="$$failed of $$all $$tests failed"; \
+	    else \
+	      if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+	      banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
+	    fi; \
+	  fi; \
+	  dashes="$$banner"; \
+	  skipped=""; \
+	  if test "$$skip" -ne 0; then \
+	    if test "$$skip" -eq 1; then \
+	      skipped="($$skip test was not run)"; \
+	    else \
+	      skipped="($$skip tests were not run)"; \
+	    fi; \
+	    test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$skipped"; \
+	  fi; \
+	  report=""; \
+	  if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+	    report="Please report to $(PACKAGE_BUGREPORT)"; \
+	    test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+	      dashes="$$report"; \
+	  fi; \
+	  dashes=`echo "$$dashes" | sed s/./=/g`; \
+	  if test "$$failed" -eq 0; then \
+	    echo "$$grn$$dashes"; \
+	  else \
+	    echo "$$red$$dashes"; \
+	  fi; \
+	  echo "$$banner"; \
+	  test -z "$$skipped" || echo "$$skipped"; \
+	  test -z "$$report" || echo "$$report"; \
+	  echo "$$dashes$$std"; \
+	  test "$$failed" -eq 0; \
+	else :; fi
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    test -d "$(distdir)/$$subdir" \
+	    || $(MKDIR_P) "$(distdir)/$$subdir" \
+	    || exit 1; \
+	  fi; \
+	done
+	@list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
+	  if test "$$subdir" = .; then :; else \
+	    dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
+	    $(am__relativize); \
+	    new_distdir=$$reldir; \
+	    dir1=$$subdir; dir2="$(top_distdir)"; \
+	    $(am__relativize); \
+	    new_top_distdir=$$reldir; \
+	    echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
+	    echo "     am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
+	    ($(am__cd) $$subdir && \
+	      $(MAKE) $(AM_MAKEFLAGS) \
+	        top_distdir="$$new_top_distdir" \
+	        distdir="$$new_distdir" \
+		am__remove_distdir=: \
+		am__skip_length_check=: \
+		am__skip_mode_fix=: \
+	        distdir) \
+	      || exit 1; \
+	  fi; \
+	done
+ at CPPUNIT_TRUE@check-local:
+check-am: all-am
+	$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
+	$(MAKE) $(AM_MAKEFLAGS) check-TESTS check-local
+check: check-recursive
+all-am: Makefile $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+install: install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+	-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-recursive
+
+clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
+	mostlyclean-am
+
+distclean: distclean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+	distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-recursive
+	-rm -rf ./$(DEPDIR)
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+	mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \
+	ctags-recursive install-am install-strip tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+	all all-am check check-TESTS check-am check-local clean \
+	clean-checkPROGRAMS clean-generic clean-libtool ctags \
+	ctags-recursive distclean distclean-compile distclean-generic \
+	distclean-libtool distclean-tags distdir dvi dvi-am html \
+	html-am info info-am install install-am install-data \
+	install-data-am install-dvi install-dvi-am install-exec \
+	install-exec-am install-html install-html-am install-info \
+	install-info-am install-man install-pdf install-pdf-am \
+	install-ps install-ps-am install-strip installcheck \
+	installcheck-am installdirs installdirs-am maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	tags tags-recursive uninstall uninstall-am
+
+
+test_config.h: test_config.h.in Makefile
+	sed -e "s%[@]abs_srcdir[@]%${abs_srcdir}%" $< > test_config.h
+
+ at CPPUNIT_FALSE@check-local:
+ at CPPUNIT_FALSE@	@echo ""
+ at CPPUNIT_FALSE@	@echo "**********************************************************"
+ at CPPUNIT_FALSE@	@echo "You must have cppunit 1.12.x or greater installed to run *"
+ at CPPUNIT_FALSE@	@echo "check target in unit-tests directory                     *"
+ at CPPUNIT_FALSE@	@echo "**********************************************************"
+ at CPPUNIT_FALSE@	@echo ""
+
+# fdiostreamTest_SOURCES = fdiostreamTest.cc
+# fdiostreamTest_LDADD = ../libdapclient.la ../libdap.la $(AM_LDADD)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/unit-tests/MarshallerTest.cc b/unit-tests/MarshallerTest.cc
new file mode 100644
index 0000000..86484e4
--- /dev/null
+++ b/unit-tests/MarshallerTest.cc
@@ -0,0 +1,995 @@
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include "config.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+
+//#define DODS_DEBUG 1
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include "TestByte.h"
+#include "TestInt16.h"
+#include "TestInt32.h"
+#include "TestUInt16.h"
+#include "TestUInt32.h"
+#include "TestFloat32.h"
+#include "TestFloat64.h"
+#include "TestStr.h"
+#include "TestUrl.h"
+#include "TestArray.h"
+#include "TestStructure.h"
+#include "TestGrid.h"
+#include "TestSequence.h"
+
+#include "DataDDS.h"
+#include "ConstraintEvaluator.h"
+#include "TestTypeFactory.h"
+#include "XDRFileMarshaller.h"
+#include "XDRStreamMarshaller.h"
+#include "XDRFileUnMarshaller.h"
+#include "XDRStreamUnMarshaller.h"
+#if 0
+#include "fdiostream.h"
+#endif
+#include "debug.h"
+
+using std::cerr ;
+using std::cout ;
+using std::endl ;
+using std::ofstream ;
+using std::ifstream ;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts.
+
+class MarshallerTest : public CppUnit::TestFixture {
+
+    CPPUNIT_TEST_SUITE( MarshallerTest ) ;
+#if 1
+    CPPUNIT_TEST( simple_types_file_serialize_test ) ;
+    CPPUNIT_TEST( array_file_serialize_test ) ;
+    CPPUNIT_TEST( structure_file_serialize_test ) ;
+    CPPUNIT_TEST( grid_file_serialize_test ) ;
+    CPPUNIT_TEST( sequence_file_serialize_test ) ;
+
+    CPPUNIT_TEST( simple_types_file_deserialize_test ) ;
+    CPPUNIT_TEST( array_file_deserialize_test ) ;
+    CPPUNIT_TEST( structure_file_deserialize_test ) ;
+    CPPUNIT_TEST( grid_file_deserialize_test ) ;
+    CPPUNIT_TEST( sequence_file_deserialize_test ) ;
+
+    CPPUNIT_TEST( simple_types_stream_serialize_test ) ;
+    CPPUNIT_TEST( array_stream_serialize_test ) ;
+    CPPUNIT_TEST( structure_stream_serialize_test ) ;
+    CPPUNIT_TEST( grid_stream_serialize_test ) ;
+    CPPUNIT_TEST( sequence_stream_serialize_test ) ;
+#endif
+#if 0
+    CPPUNIT_TEST( simple_types_fdistream_deserialize_test ) ;
+#endif
+#if 1
+    CPPUNIT_TEST( simple_types_stream_deserialize_test ) ;
+    CPPUNIT_TEST( array_stream_deserialize_test ) ;
+    CPPUNIT_TEST( structure_stream_deserialize_test ) ;
+    CPPUNIT_TEST( grid_stream_deserialize_test ) ;
+    CPPUNIT_TEST( sequence_stream_deserialize_test ) ;
+#endif
+    CPPUNIT_TEST_SUITE_END( ) ;
+
+    TestByte b;
+    TestInt16 i16 ;
+    TestInt32 i32 ;
+    TestUInt16 ui16 ;
+    TestUInt32 ui32 ;
+    TestFloat32 f32 ;
+    TestFloat64 f64 ;
+    TestStr str ;
+    TestUrl url ;
+    TestByte ab ;
+
+    TestArray arr ;
+
+    TestStructure s ;
+
+    ConstraintEvaluator eval ;
+    TestTypeFactory ttf ;
+    DataDDS dds ;
+
+    string str_value, str2_value;
+    string url_value;
+
+    dods_byte *db;
+public:
+    MarshallerTest() : b( "byte" ),
+	       i16( "i16" ) ,
+	       i32( "i32" ) ,
+	       ui16( "ui16" ) ,
+	       ui32( "ui32" ) ,
+	       f32( "f32" ) ,
+	       f64( "f64" ) ,
+	       str( "str" ) ,
+	       url( "url" ) ,
+	       ab( "ab" ) ,
+	       arr( "arr", &ab ) ,
+	       s( "s" ) ,
+	       dds( &ttf, "dds" )
+    {
+	b.read();
+	i16.read();
+	i32.read();
+	ui16.read();
+	ui32.read();
+	f32.read();
+	f64.read();
+	str.read();
+	url.read();
+
+	ab.read();
+
+	arr.append_dim( 5, "dim1" ) ;
+	arr.append_dim( 3, "dim2" ) ;
+	arr.read();
+	arr.set_read_p( true ) ;
+	db = new dods_byte[arr.length() * sizeof(dods_byte)] ;
+	arr.value( db ) ;
+
+	s.add_var( &i32 ) ;
+	s.add_var( &str ) ;
+	s.add_var( &arr ) ;
+	s.set_send_p( true ) ;
+
+	url_value = "http://dcz.gso.uri.edu/avhrr-archive/archive.html";
+    }
+
+    void setUp()
+    {
+    }
+
+    void tearDown()
+    {
+    }
+
+    void simple_types_file_serialize_test() {
+	try
+	{
+	    FILE *f = fopen( "st_test.file", "w" ) ;
+	    XDRFileMarshaller fm( f ) ;
+
+	    b.serialize( eval, dds, fm, false ) ;
+	    i16.serialize( eval, dds, fm, false ) ;
+	    i32.serialize( eval, dds, fm, false ) ;
+	    ui16.serialize( eval, dds, fm, false ) ;
+	    ui32.serialize( eval, dds, fm, false ) ;
+	    f32.serialize( eval, dds, fm, false ) ;
+	    f64.serialize( eval, dds, fm, false ) ;
+	    str.serialize( eval, dds, fm, false ) ;
+	    url.serialize( eval, dds, fm, false ) ;
+
+	    // fclose( f ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void simple_types_file_deserialize_test() {
+	try
+	{
+	    FILE *ff = fopen( "st_test.file", "r" ) ;
+	    XDRFileUnMarshaller um( ff ) ;
+
+	    Byte fb( "fb" ) ;
+	    fb.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fb.value() == b.value() ) ;
+
+	    Int16 fi16( "i16" ) ;
+	    fi16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi16.value() == i16.value() ) ;
+
+	    Int32 fi32( "i32" ) ;
+	    fi32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi32.value() == i32.value() ) ;
+
+	    UInt16 fui16( "ui16" ) ;
+	    fui16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui16.value() == ui16.value() ) ;
+
+	    UInt32 fui32( "ui32" ) ;
+	    fui32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui32.value() == ui32.value() ) ;
+
+	    Float32 ff32( "f32" ) ;
+	    ff32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff32.value() == f32.value() ) ;
+
+	    Float64 ff64( "f64" ) ;
+	    ff64.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff64.value() == f64.value() ) ;
+
+	    Str fstr( "str" ) ;
+	    fstr.deserialize( um, &dds, false ) ;
+	    // Test for the string value like this because the digit after
+	    // the colon changes each time the read() method is called.
+	    CPPUNIT_ASSERT( fstr.value().find("Silly test string:") != string::npos ) ;
+
+	    Url furl( "url" ) ;
+	    furl.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( furl.value() == url_value ) ;
+
+	    // fclose( ff ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void array_file_serialize_test() {
+	try
+	{
+	    FILE *f = fopen( "a_test.file", "w" ) ;
+	    XDRFileMarshaller fm( f ) ;
+
+	    arr.serialize( eval, dds, fm, false ) ;
+
+	    // fclose( f ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void array_file_deserialize_test() {
+	try
+	{
+	    FILE *ff = fopen( "a_test.file", "r" ) ;
+	    XDRFileUnMarshaller um( ff ) ;
+
+	    TestByte fab( "ab" ) ;
+	    TestArray farr( "arr", &fab ) ;
+	    farr.append_dim( 5, "dim1" ) ;
+	    farr.append_dim( 3, "dim2" ) ;
+	    farr.deserialize( um, &dds, false ) ;
+
+	    CPPUNIT_ASSERT( farr.length() == arr.length() ) ;
+
+	    dods_byte fdb[farr.length() * sizeof(dods_byte)] ;
+	    farr.value( fdb ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, farr.length() * sizeof( dods_byte ) ) ) ;
+
+	    // fclose( ff ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void structure_file_serialize_test() {
+	try
+	{
+	    FILE *f = fopen( "struct_test.file", "w" ) ;
+	    XDRFileMarshaller fm( f ) ;
+
+	    TestStructure s( "s" ) ;
+	    s.add_var( &i32 ) ;
+	    s.add_var( &str ) ;
+	    s.add_var( &arr ) ;
+	    s.set_send_p( true ) ;
+
+	    s.serialize( eval, dds, fm, false ) ;
+
+	    // fclose( f ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void structure_file_deserialize_test() {
+	try
+	{
+	    FILE *ff = fopen( "struct_test.file", "r" ) ;
+	    XDRFileUnMarshaller um( ff ) ;
+
+	    TestStructure fs( "fs" ) ;
+
+	    TestInt32 fsi32( "fsi32" ) ;
+	    fs.add_var( &fsi32 ) ;
+
+	    TestStr fsstr( "fsstr" ) ;
+	    fs.add_var( &fsstr ) ;
+
+	    TestByte fsab( "fsab" ) ;
+	    TestArray fsarr( "fsarr", &fsab ) ;
+	    fsarr.append_dim( 5, "dim1" ) ;
+	    fsarr.append_dim( 3, "dim2" ) ;
+	    fs.add_var( &fsarr ) ;
+
+	    fs.deserialize( um, &dds, false ) ;
+
+	    Int32 *fsi32_p = dynamic_cast<Int32 *>(fs.var( "fsi32" )) ;
+	    CPPUNIT_ASSERT( fsi32_p ) ;
+	    CPPUNIT_ASSERT( fsi32_p->value() == i32.value() ) ;
+
+	    Str *fsstr_p = dynamic_cast<Str *>(fs.var( "fsstr" )) ;
+	    CPPUNIT_ASSERT( fsstr_p ) ;
+	    DBG2(cerr << "fsstr_p->value(): " << fsstr_p->value() << endl);
+	    CPPUNIT_ASSERT( fsstr_p->value().find("Silly test string:") != string::npos ) ;
+
+	    BaseType *bt = fs.var( "fsab" ) ;
+	    CPPUNIT_ASSERT( bt ) ;
+	    Array *fsarr_p = dynamic_cast<Array *>(bt) ;
+	    CPPUNIT_ASSERT( fsarr_p ) ;
+	    dods_byte fdb[fsarr_p->length() * sizeof(dods_byte)] ;
+	    fsarr_p->value( fdb ) ;
+
+	    CPPUNIT_ASSERT( fsarr_p->length() == arr.length() ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, fsarr_p->length() * sizeof( dods_byte ) ) ) ;
+
+	    // fclose( ff ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void grid_file_serialize_test() {
+	try
+	{
+	    FILE *f = fopen( "g_test.file", "w" ) ;
+	    XDRFileMarshaller fm( f ) ;
+
+	    TestGrid tg( "grid1" );
+	    TestArray arr2( "arr2", &ab ) ;
+	    arr2.append_dim( 5, "dim1" ) ;
+	    arr2.append_dim( 3, "dim2" ) ;
+	    tg.add_var( &arr2, array );
+
+	    TestArray map1( "map1", &f32 ) ;
+	    map1.append_dim( 5, "dim1" ) ;
+	    tg.add_var( &map1, maps );
+
+	    TestArray map2( "map2", &f32 ) ;
+	    map2.append_dim( 3, "dim2" ) ;
+	    tg.add_var( &map2, maps );
+
+	    tg.set_send_p(true);
+	    tg.read();
+	    tg.set_read_p(true);
+
+	    tg.serialize( eval, dds, fm, false ) ;
+
+	    // fclose( f ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void grid_file_deserialize_test() {
+	try
+	{
+	    FILE *ff = fopen( "g_test.file", "r" ) ;
+	    XDRFileUnMarshaller um( ff ) ;
+
+	    TestGrid tg( "grid1" );
+	    TestArray arr2( "arr2", &ab ) ;
+	    arr2.append_dim( 5, "dim1" ) ;
+	    arr2.append_dim( 3, "dim2" ) ;
+	    tg.add_var(&arr2, array);
+
+	    TestArray map1( "map1", &f32 ) ;
+	    map1.append_dim( 5, "dim1" ) ;
+	    tg.add_var(&map1, maps);
+
+	    TestArray map2( "map2", &f32 ) ;
+	    map2.append_dim( 3, "dim2" ) ;
+	    tg.add_var(&map2, maps);
+
+       	    tg.deserialize( um, &dds, false ) ;
+
+	    // Check the values in the array
+	    CPPUNIT_ASSERT( tg.get_array()->length() == arr.length() ) ;
+
+	    dods_byte fdb[tg.get_array()->length() * sizeof(dods_byte)] ;
+	    tg.get_array()->value( fdb ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, tg.get_array()->length() * sizeof( dods_byte ) ) ) ;
+
+	    // Should test the map values here, but skip that for now...
+
+	    // fclose( ff ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void sequence_file_serialize_test() {
+	try
+	{
+	    FILE *f = fopen( "seq_test.file", "w" ) ;
+	    XDRFileMarshaller fm( f ) ;
+
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+
+	    seq.add_var( &seq2 ) ;
+
+	    seq.set_send_p( true ) ;
+	    seq.set_leaf_sequence() ;
+
+	    seq.serialize( eval, dds, fm, false ) ;
+
+	    // fclose( f ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void sequence_file_deserialize_test() {
+	try
+	{
+	    FILE *ff = fopen( "seq_test.file", "r" ) ;
+	    XDRFileUnMarshaller um( ff ) ;
+
+	    dods_byte fdb[arr.length() * sizeof(dods_byte)] ;
+
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+	    seq2.set_send_p( true ) ;
+	    seq.add_var( &seq2 ) ;
+	    seq.set_leaf_sequence() ;
+
+	    seq.deserialize( um, &dds, false ) ;
+	    unsigned int num_rows = seq.number_of_rows() ;
+	    CPPUNIT_ASSERT( num_rows == 4 ) ;
+	    for( unsigned int i = 0; i < num_rows; i++ )
+	    {
+		BaseTypeRow *row = seq.row_value( i ) ;
+		CPPUNIT_ASSERT( row ) ;
+		CPPUNIT_ASSERT( row->size() == 3 ) ;
+		Float64 *f64_p = dynamic_cast<Float64 *>((*row)[0]) ;
+		CPPUNIT_ASSERT( f64_p ) ;
+		CPPUNIT_ASSERT( f64_p->value() == f64.value() ) ;
+
+		Array *arr_p = dynamic_cast<Array *>((*row)[1]) ;
+		CPPUNIT_ASSERT( arr_p ) ;
+		arr_p->value( fdb ) ;
+		CPPUNIT_ASSERT( arr_p->length() == arr.length() ) ;
+		CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db,
+					 arr_p->length() * sizeof( dods_byte ) ) ) ;
+		Sequence *seq_p = dynamic_cast<Sequence *>((*row)[2]) ;
+		CPPUNIT_ASSERT( seq_p ) ;
+		unsigned int num_rows_sub = seq_p->number_of_rows() ;
+		CPPUNIT_ASSERT( num_rows == 4 ) ;
+		for( unsigned int j = 0; j < num_rows_sub; j++ )
+		{
+		    BaseTypeRow *row_sub = seq_p->row_value( j ) ;
+		    CPPUNIT_ASSERT( row_sub ) ;
+		    CPPUNIT_ASSERT( row_sub->size() == 2 ) ;
+		    UInt16 *ui16_p = dynamic_cast<UInt16 *>((*row_sub)[0]) ;
+		    CPPUNIT_ASSERT( ui16_p ) ;
+		    CPPUNIT_ASSERT( ui16_p->value() == ui16.value() ) ;
+		    Url *url_p = dynamic_cast<Url *>((*row_sub)[1]) ;
+		    CPPUNIT_ASSERT( url_p ) ;
+		    CPPUNIT_ASSERT( url_p->value() == url.value() ) ;
+		}
+	    }
+
+	    // fclose( ff ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    // Stream tests from here on
+
+    void simple_types_stream_serialize_test() {
+	try
+	{
+	    ofstream strm( "st_test.strm", ios::out|ios::trunc ) ;
+	    XDRStreamMarshaller sm( strm ) ;
+
+	    b.serialize( eval, dds, sm, false ) ;
+
+	    i16.serialize( eval, dds, sm, false ) ;
+
+	    i32.serialize( eval, dds, sm, false ) ;
+
+	    ui16.serialize( eval, dds, sm, false ) ;
+
+	    ui32.serialize( eval, dds, sm, false ) ;
+
+	    f32.serialize( eval, dds, sm, false ) ;
+
+	    f64.serialize( eval, dds, sm, false ) ;
+
+	    str.serialize( eval, dds, sm, false ) ;
+
+	    url.serialize( eval, dds, sm, false ) ;
+
+	    // strm.close() ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void simple_types_stream_deserialize_test() {
+	try
+	{
+#if 0
+	    ifstream strm( "st_test.strm", ios::in ) ;
+	    XDRStreamUnMarshaller um( strm ) ;
+#else
+	    FILE *sf = fopen( "st_test.strm", "r" ) ;
+	    XDRFileUnMarshaller um( sf ) ;
+#endif
+	    Byte fb( "fb" ) ;
+	    fb.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fb.value() == b.value() ) ;
+
+	    Int16 fi16( "i16" ) ;
+	    fi16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi16.value() == i16.value() ) ;
+
+	    Int32 fi32( "i32" ) ;
+	    fi32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi32.value() == i32.value() ) ;
+
+	    UInt16 fui16( "ui16" ) ;
+	    fui16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui16.value() == ui16.value() ) ;
+
+	    UInt32 fui32( "ui32" ) ;
+	    fui32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui32.value() == ui32.value() ) ;
+
+	    Float32 ff32( "f32" ) ;
+	    ff32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff32.value() == f32.value() ) ;
+
+	    Float64 ff64( "f64" ) ;
+	    ff64.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff64.value() == f64.value() ) ;
+
+	    Str fstr( "str" ) ;
+	    fstr.deserialize( um, &dds, false ) ;
+	    DBG(cerr << "fstr.value(): " << fstr.value() << endl);
+	    CPPUNIT_ASSERT( fstr.value().find("Silly test string:") != string::npos ) ;
+
+	    Url furl( "url" ) ;
+	    furl.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( furl.value() == url_value ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+#if 0
+    // Not currently run...
+    void simple_types_fdistream_deserialize_test() {
+	try
+	{
+#if 1
+	    int in = open( "st_test.strm", O_RDONLY );
+	    if (in < 0)
+		throw Error("Could not open file.");
+	    fdistream sin( in );
+#else
+	    FILE *in = fopen("st_test.strm", "r");
+	    if (!in)
+		throw Error("Could not open the file");
+	    fpistream sin(in);
+#endif
+	    XDRStreamUnMarshaller um( sin ) ;
+
+	    Byte fb( "fb" ) ;
+	    fb.deserialize( um, &dds, false ) ;
+	    DBG(std::cerr << "expected: '" << b.value() << "' ; actual: '" << fb.value() << "'" << std::endl);
+	    CPPUNIT_ASSERT( fb.value() == b.value() ) ;
+
+	    Int16 fi16( "i16" ) ;
+	    fi16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi16.value() == i16.value() ) ;
+
+	    Int32 fi32( "i32" ) ;
+	    fi32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi32.value() == i32.value() ) ;
+
+	    UInt16 fui16( "ui16" ) ;
+	    fui16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui16.value() == ui16.value() ) ;
+
+	    UInt32 fui32( "ui32" ) ;
+	    fui32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui32.value() == ui32.value() ) ;
+
+	    Float32 ff32( "f32" ) ;
+	    ff32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff32.value() == f32.value() ) ;
+
+	    Float64 ff64( "f64" ) ;
+	    ff64.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff64.value() == f64.value() ) ;
+
+	    Str fstr( "str" ) ;
+	    fstr.deserialize( um, &dds, false ) ;
+	    DBG(cerr << "fstr.value(): " << fstr.value() << endl);
+	    CPPUNIT_ASSERT( fstr.value().find("Silly test string:") != string::npos ) ;
+
+	    Url furl( "url" ) ;
+	    furl.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( furl.value() == url_value ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+#endif
+
+    void array_stream_serialize_test() {
+	try
+	{
+	    ofstream strm( "a_test.strm", ios::out|ios::trunc ) ;
+	    XDRStreamMarshaller sm( strm ) ;
+
+	    arr.serialize( eval, dds, sm, false ) ;
+
+	    // strm.close() ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void array_stream_deserialize_test() {
+	try
+	{
+#if 0
+	    ifstream strm( "a_test.strm", ios::in ) ;
+	    XDRStreamUnMarshaller um( strm ) ;
+#else
+	    FILE *sf = fopen( "a_test.strm", "r" ) ;
+	    XDRFileUnMarshaller um( sf ) ;
+#endif
+	    TestByte fab( "ab" ) ;
+	    TestArray farr( "arr", &fab ) ;
+	    farr.append_dim( 5, "dim1" ) ;
+	    farr.append_dim( 3, "dim2" ) ;
+	    farr.deserialize( um, &dds, false ) ;
+
+	    CPPUNIT_ASSERT( farr.length() == arr.length() ) ;
+
+	    dods_byte fdb[arr.length() * sizeof(dods_byte)] ;
+	    farr.value( fdb ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, farr.length() * sizeof( dods_byte ) ) ) ;
+
+	    // fclose( sf ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void structure_stream_serialize_test() {
+	try
+	{
+	    ofstream strm( "struct_test.strm", ios::out|ios::trunc ) ;
+	    XDRStreamMarshaller sm( strm ) ;
+
+	    TestStructure s( "s" ) ;
+	    s.add_var( &i32 ) ;
+	    s.add_var( &str ) ;
+	    s.add_var( &arr ) ;
+	    s.set_send_p( true ) ;
+
+	    s.serialize( eval, dds, sm, false ) ;
+
+	    // strm.close() ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void structure_stream_deserialize_test() {
+	try
+	{
+#if 0
+	    ifstream strm( "struct_test.strm", ios::in ) ;
+	    XDRStreamUnMarshaller um( strm ) ;
+#else
+	    FILE *sf = fopen( "struct_test.strm", "r" ) ;
+	    XDRFileUnMarshaller um( sf ) ;
+#endif
+	    TestStructure fs( "fs" ) ;
+	    TestInt32 fsi32( "fsi32" ) ;
+	    fs.add_var( &fsi32 ) ;
+
+	    TestStr fsstr( "fsstr" ) ;
+	    fs.add_var( &fsstr ) ;
+
+	    TestByte fsab( "fsab" ) ;
+	    TestArray fsarr( "fsarr", &fsab ) ;
+	    fsarr.append_dim( 5, "dim1" ) ;
+	    fsarr.append_dim( 3, "dim2" ) ;
+	    fs.add_var( &fsarr ) ;
+
+	    fs.deserialize( um, &dds, false ) ;
+
+	    Int32 *fsi32_p = dynamic_cast<Int32 *>(fs.var( "fsi32" )) ;
+	    CPPUNIT_ASSERT( fsi32_p ) ;
+	    CPPUNIT_ASSERT( fsi32_p->value() == i32.value() ) ;
+
+	    Str *fsstr_p = dynamic_cast<Str *>(fs.var( "fsstr" )) ;
+	    CPPUNIT_ASSERT( fsstr_p ) ;
+	    DBG(cerr << "fsstr_p->value(): " << fsstr_p->value() << endl);
+	    CPPUNIT_ASSERT( fsstr_p->value().find("Silly test string:") != string::npos ) ;
+
+	    BaseType *bt = fs.var( "fsab" ) ;
+	    CPPUNIT_ASSERT( bt ) ;
+	    Array *fsarr_p = dynamic_cast<Array *>(bt) ;
+	    CPPUNIT_ASSERT( fsarr_p ) ;
+	    CPPUNIT_ASSERT( fsarr_p->length() == arr.length() ) ;
+	    dods_byte fdb[fsarr_p->length() * sizeof(dods_byte)] ;
+	    fsarr_p->value( fdb ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, fsarr_p->length() * sizeof( dods_byte ) ) ) ;
+
+	    // fclose( sf ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void grid_stream_serialize_test() {
+	try
+	{
+	    ofstream strm( "g_test.strm", ios::out|ios::trunc ) ;
+	    XDRStreamMarshaller sm( strm ) ;
+
+	    TestGrid tg( "grid1" );
+	    TestArray arr2( "arr2", &ab ) ;
+	    arr2.append_dim( 5, "dim1" ) ;
+	    arr2.append_dim( 3, "dim2" ) ;
+	    tg.add_var( &arr2, array );
+
+	    TestArray map1( "map1", &f32 ) ;
+	    map1.append_dim( 5, "dim1" ) ;
+	    tg.add_var( &map1, maps );
+
+	    TestArray map2( "map2", &f32 ) ;
+	    map2.append_dim( 3, "dim2" ) ;
+	    tg.add_var( &map2, maps );
+
+	    tg.set_send_p(true);
+	    tg.read();
+	    tg.set_read_p(true);
+
+	    tg.serialize( eval, dds, sm, false ) ;
+
+	    // strm.close() ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void grid_stream_deserialize_test() {
+	try
+	{
+#if 0
+	    ifstream strm( "g_test.strm", ios::in ) ;
+	    XDRStreamUnMarshaller um( strm ) ;
+#else
+	    FILE *sf = fopen( "g_test.strm", "r" ) ;
+	    XDRFileUnMarshaller um( sf ) ;
+#endif
+	    TestGrid tg( "grid1" );
+	    TestArray arr2( "arr2", &ab ) ;
+	    arr2.append_dim( 5, "dim1" ) ;
+	    arr2.append_dim( 3, "dim2" ) ;
+	    tg.add_var(&arr2, array);
+
+	    TestArray map1( "map1", &f32 ) ;
+	    map1.append_dim( 5, "dim1" ) ;
+	    tg.add_var(&map1, maps);
+
+	    TestArray map2( "map2", &f32 ) ;
+	    map2.append_dim( 3, "dim2" ) ;
+	    tg.add_var(&map2, maps);
+
+	    tg.deserialize( um, &dds, false ) ;
+
+	    // Check the values in the array
+	    CPPUNIT_ASSERT( tg.get_array()->length() == arr.length() ) ;
+
+	    dods_byte fdb[tg.get_array()->length() * sizeof(dods_byte)] ;
+	    tg.get_array()->value( fdb ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, tg.get_array()->length() * sizeof( dods_byte ) ) ) ;
+
+	    // Should test the map values here, but skip that for now...
+
+	    // fclose( sf ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void sequence_stream_serialize_test() {
+	try
+	{
+	    ofstream strm( "seq_test.strm", ios::out|ios::trunc ) ;
+	    XDRStreamMarshaller sm( strm ) ;
+
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+	    seq.add_var( &seq2 ) ;
+
+	    seq.set_send_p( true ) ;
+	    seq.set_leaf_sequence() ;
+
+	    seq.serialize( eval, dds, sm, false ) ;
+
+	    // strm.close() ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+
+    void sequence_stream_deserialize_test() {
+	try
+	{
+#if 0
+	    ifstream strm( "seq_test.strm", ios::in ) ;
+	    XDRStreamUnMarshaller um( strm ) ;
+#else
+	    FILE *sf = fopen( "seq_test.strm", "r" ) ;
+	    XDRFileUnMarshaller um( sf ) ;
+#endif
+	    dods_byte fdb[arr.length() * sizeof(dods_byte)] ;
+
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+
+	    seq.add_var( &seq2 ) ;
+
+	    seq.set_leaf_sequence() ;
+
+	    seq.deserialize( um, &dds, false ) ;
+
+	    unsigned int num_rows = seq.number_of_rows() ;
+	    CPPUNIT_ASSERT( num_rows == 4 ) ;
+	    for( unsigned int i = 0; i < num_rows; i++ )
+	    {
+		BaseTypeRow *row = seq.row_value( i ) ;
+		CPPUNIT_ASSERT( row ) ;
+		CPPUNIT_ASSERT( row->size() == 3 ) ;
+		Float64 *f64_p = dynamic_cast<Float64 *>((*row)[0]) ;
+		CPPUNIT_ASSERT( f64_p ) ;
+		CPPUNIT_ASSERT( f64_p->value() == f64.value() ) ;
+		Array *arr_p = dynamic_cast<Array *>((*row)[1]) ;
+		CPPUNIT_ASSERT( arr_p ) ;
+		arr_p->value( fdb ) ;
+		CPPUNIT_ASSERT( arr_p->length() == arr.length() ) ;
+		CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db,
+					 arr_p->length() * sizeof( dods_byte ) ) ) ;
+		Sequence *seq_p = dynamic_cast<Sequence *>((*row)[2]) ;
+		CPPUNIT_ASSERT( seq_p ) ;
+		unsigned int num_rows_sub = seq_p->number_of_rows() ;
+		CPPUNIT_ASSERT( num_rows == 4 ) ;
+		for( unsigned int j = 0; j < num_rows_sub; j++ )
+		{
+		    BaseTypeRow *row_sub = seq_p->row_value( j ) ;
+		    CPPUNIT_ASSERT( row_sub ) ;
+		    CPPUNIT_ASSERT( row_sub->size() == 2 ) ;
+		    UInt16 *ui16_p = dynamic_cast<UInt16 *>((*row_sub)[0]) ;
+		    CPPUNIT_ASSERT( ui16_p ) ;
+		    CPPUNIT_ASSERT( ui16_p->value() == ui16.value() ) ;
+		    Url *url_p = dynamic_cast<Url *>((*row_sub)[1]) ;
+		    CPPUNIT_ASSERT( url_p ) ;
+		    CPPUNIT_ASSERT( url_p->value() == url.value() ) ;
+		}
+	    }
+
+	    // fclose( sf ) ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( MarshallerTest ) ;
+
+int main(int, char **)
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter(
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
+
diff --git a/unit-tests/RCReaderTest.cc b/unit-tests/RCReaderTest.cc
new file mode 100644
index 0000000..696e564
--- /dev/null
+++ b/unit-tests/RCReaderTest.cc
@@ -0,0 +1,359 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003,2006 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "config.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <cstring>
+#include <cstdlib>
+
+#include <string>
+#include <iostream>
+#include <fstream>
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+//#define DODS_DEBUG
+#include "RCReader.h"
+#include "debug.h"
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace std;
+
+namespace libdap
+{
+
+class RCReaderTest : public TestFixture {
+private:
+    RCReader *rcr;
+
+protected:
+
+public:
+    RCReaderTest() : rcr(RCReader::instance()) {}
+
+    void setUp () {}
+
+    void tearDown() {}
+
+    CPPUNIT_TEST_SUITE(RCReaderTest);
+
+    CPPUNIT_TEST(check_env_var_test1);
+    CPPUNIT_TEST(check_env_var_test2);
+    CPPUNIT_TEST(check_env_var_test3);
+    CPPUNIT_TEST(check_env_var_test4);
+    CPPUNIT_TEST(check_env_var_test5);
+    CPPUNIT_TEST(instance_test1);
+    CPPUNIT_TEST(instance_test2);
+    CPPUNIT_TEST(proxy_test1);
+    CPPUNIT_TEST(proxy_test2);
+    CPPUNIT_TEST(proxy_test3);
+    CPPUNIT_TEST(proxy_test4);
+    CPPUNIT_TEST(proxy_test5);
+    CPPUNIT_TEST(validate_ssl_test);
+    
+    CPPUNIT_TEST_SUITE_END();
+
+    void check_env_var_test1() {
+	putenv((char *)"DODS_CONF=");
+	CPPUNIT_ASSERT(rcr->check_env_var("DODS_CONF") == "");
+    }
+
+    void check_env_var_test2() {
+	putenv((char*)"DODS_CONF=Nothing_sensible");
+	CPPUNIT_ASSERT(rcr->check_env_var("DODS_CONF") == "");
+    }
+
+    void check_env_var_test3() {
+	putenv((char*)"DODS_CONF=/etc/passwd");
+	CPPUNIT_ASSERT(rcr->check_env_var("DODS_CONF") == "/etc/passwd");
+    }
+
+    void check_env_var_test4() {
+	// Set DODS_CONF to the CWD plus .dodsrc, create file called .dodsrc
+	// in the CWD and test to see if check_env_var finds it.
+	char cwd[1024];
+	getcwd(cwd, 1024);
+
+	string rc = string(cwd) + string("/.dodsrc");
+	ifstream ifp(rc.c_str()); // This should create .dodsrc in the CWD
+	string dc = string("DODS_CONF=") + string(cwd);
+	putenv(const_cast<char*>(dc.c_str()));
+
+	// Return existing file
+	CPPUNIT_ASSERT(rcr->check_env_var("DODS_CONF") == rc);
+	remove(rc.c_str());
+    }
+
+    void check_env_var_test5() {
+	// In this test we *don't* create the file, just set DODS_CONF to the
+	// directory and see if check_env_var() makes the RC file.
+	char cwd[1024];
+	getcwd(cwd, 1024);
+
+	string rc = string(cwd) + string("/.dodsrc");
+	string dc = string("DODS_CONF=") + string(cwd);
+	putenv(const_cast<char*>(dc.c_str()));
+
+	// Create the file.
+	CPPUNIT_ASSERT(rcr->check_env_var("DODS_CONF") == rc);
+	struct stat stat_info;
+	CPPUNIT_ASSERT(stat(rc.c_str(), &stat_info) == 0 &&
+		       S_ISREG(stat_info.st_mode));
+	remove(rc.c_str());
+    }
+
+    void instance_test1() {
+	// This test assumes that HOME *is* defined. We should find the
+	// .dodsrc there. If it's not there, we should create one there.
+	putenv((char*)"DODS_CONF=");
+	string home = getenv("HOME");
+	if (*home.rbegin() != '/')
+	    home += "/";
+	RCReader::delete_instance();
+	RCReader::initialize_instance();
+	RCReader *reader = RCReader::instance();
+	CPPUNIT_ASSERT(reader->d_rc_file_path == home + string(".dodsrc"));
+	DBG(cerr << "Cache root: " << reader->get_dods_cache_root() << endl);
+	CPPUNIT_ASSERT(reader->get_dods_cache_root() 
+		       == home + string(".dods_cache/"));
+    }
+
+    void instance_test2() {
+	// Set DODS_CONF to create a .dodsrc in the CWD, then check to make
+	// sure that .dodsrc has the correct cache root.
+	char cwd[1024];
+	getcwd(cwd, 1024);
+	DBG(cerr << "CWD: " << cwd << endl);
+	string rc = cwd;
+	rc += "/.dodsrc";
+	DBG(cerr << "RC: " << rc << endl);
+	remove(rc.c_str());	// make sure the RC does not exist
+
+	char dc[1024];
+	strncpy(dc, "DODS_CONF=", 1024);
+	strncat(dc, cwd, 1024-strlen("DODS_CONF="));
+	dc[1023] = '\0';
+	DBG(cerr << "dc: " << dc << endl);
+	putenv(dc);
+
+	RCReader::delete_instance();
+	RCReader::initialize_instance();
+	RCReader *reader = RCReader::instance();
+	DBG(cerr << "RC path: " << reader->d_rc_file_path << endl);
+	CPPUNIT_ASSERT(reader->d_rc_file_path 
+		       == string(cwd) + string("/.dodsrc"));
+	DBG(cerr << "Cache root: " << reader->get_dods_cache_root() << endl);
+	CPPUNIT_ASSERT(reader->get_dods_cache_root() 
+		       == string(cwd) + string("/.dods_cache/"));
+	
+    }
+
+    // Read the proxy info from rcreader-testsuite/test1.rc
+    void proxy_test1() {
+	string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test1.rc" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+	RCReader::delete_instance();
+	RCReader::initialize_instance();
+	RCReader *reader = RCReader::instance();
+	DBG(cerr << "RC path: " << reader->d_rc_file_path << endl);
+	CPPUNIT_ASSERT(reader->d_rc_file_path 
+		       == (string)TEST_SRC_DIR + "/rcreader-testsuite/test1.rc");
+	CPPUNIT_ASSERT(reader->get_proxy_server_protocol() == "http");
+
+	string proxy = reader->get_proxy_server_host_url();
+	CPPUNIT_ASSERT(proxy == "jimg:mypass at proxy.local.org:8080");
+
+	CPPUNIT_ASSERT(reader->get_proxy_server_host() == "proxy.local.org");
+	CPPUNIT_ASSERT(reader->get_proxy_server_port() == 8080);
+	CPPUNIT_ASSERT(reader->get_proxy_server_userpw() == "jimg:mypass");
+
+	CPPUNIT_ASSERT(reader->is_no_proxy_for_used());
+	CPPUNIT_ASSERT(reader->get_no_proxy_for_protocol() == "http");
+	CPPUNIT_ASSERT(reader->get_no_proxy_for_host() == "local.org");
+    }
+
+    void proxy_test2() {
+	string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test2.rc" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+	RCReader::delete_instance();
+	RCReader::initialize_instance();
+	RCReader *reader = RCReader::instance();
+	DBG(cerr << "RC path: " << reader->d_rc_file_path << endl);
+	CPPUNIT_ASSERT(reader->d_rc_file_path 
+		       == (string)TEST_SRC_DIR + "/rcreader-testsuite/test2.rc");
+	CPPUNIT_ASSERT(reader->get_proxy_server_protocol() == "http");
+
+	string proxy = reader->get_proxy_server_host_url();
+	DBG(cerr << "get_proxy_server_host_url(): " << proxy << endl);
+	CPPUNIT_ASSERT(proxy == "proxy.local.org:80");
+
+	CPPUNIT_ASSERT(reader->get_proxy_server_host() == "proxy.local.org");
+	CPPUNIT_ASSERT(reader->get_proxy_server_port() == 80);
+	CPPUNIT_ASSERT(reader->get_proxy_server_userpw() == "");
+    }
+
+    void proxy_test3() {
+	string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test3.rc" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+	try {
+	    RCReader::delete_instance();
+	    RCReader::initialize_instance();
+	    CPPUNIT_ASSERT(!"initialize_instance() should throw Error.");
+	}
+	catch(Error &e) {
+	    DBG(cerr << e.get_error_message() << endl);
+	    CPPUNIT_ASSERT(e.get_error_message() != "");
+	}
+    }
+    
+    void proxy_test4() {
+	string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test4.rc" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+	try {
+	    RCReader::delete_instance();
+	    RCReader::initialize_instance();
+	    RCReader *reader = RCReader::instance();
+	    DBG(cerr << "RC path: " << reader->d_rc_file_path << endl);
+	    CPPUNIT_ASSERT(reader->d_rc_file_path 
+			   == (string)TEST_SRC_DIR + "/rcreader-testsuite/test4.rc");
+	    CPPUNIT_ASSERT(reader->get_proxy_server_protocol() == "http");
+
+	    string proxy = reader->get_proxy_server_host_url();
+	    DBG(cerr << "get_proxy_server_host_url(): " << proxy << endl);
+	    CPPUNIT_ASSERT(proxy == "jimg:test at proxy.local.org:3128");
+
+	    CPPUNIT_ASSERT(reader->get_proxy_server_host() == "proxy.local.org");
+	    CPPUNIT_ASSERT(reader->get_proxy_server_port() == 3128);
+	    CPPUNIT_ASSERT(reader->get_proxy_server_userpw() == "jimg:test");
+	}
+	catch(Error &e) {
+	    DBG(cerr << e.get_error_message() << endl);
+	    CPPUNIT_ASSERT(e.get_error_message() != "");
+	}
+    }
+    
+    void proxy_test5() {
+	string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/test5.rc" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+	try {
+	    RCReader::delete_instance();
+	    RCReader::initialize_instance();
+	    RCReader *reader = RCReader::instance();
+	    DBG(cerr << "RC path: " << reader->d_rc_file_path << endl);
+	    CPPUNIT_ASSERT(reader->d_rc_file_path 
+			   == (string)TEST_SRC_DIR + "/rcreader-testsuite/test5.rc");
+	    string proxy = reader->get_proxy_server_host_url();
+	    DBG(cerr << "get_proxy_server_host_url(): " << proxy << endl);
+	    CPPUNIT_ASSERT(reader->get_proxy_server_protocol() == "http");
+
+	    CPPUNIT_ASSERT(proxy == "jimg:test at proxy.local.org:3128");
+
+	    CPPUNIT_ASSERT(reader->get_proxy_server_host() == "proxy.local.org");
+	    CPPUNIT_ASSERT(reader->get_proxy_server_port() == 3128);
+	    CPPUNIT_ASSERT(reader->get_proxy_server_userpw() == "jimg:test");
+	}
+	catch(Error &e) {
+	    DBG(cerr << e.get_error_message() << endl);
+	    CPPUNIT_ASSERT(e.get_error_message() != "");
+	}
+    }
+    
+
+    // This simple test checks to see that the VALIDATE_SSL parameter is 
+    // read correctly.
+    void validate_ssl_test() {
+	string rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/dodssrc_ssl_1" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+        RCReader::delete_instance();
+        RCReader::initialize_instance();
+        RCReader *reader = RCReader::instance();
+        // No param set in file
+        DBG(cerr << "reader->get_validate_ssl(): " << reader->get_validate_ssl()
+            << endl);
+        CPPUNIT_ASSERT(reader->get_validate_ssl() == 1);
+
+        // Param set in file
+	rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/dodssrc_ssl_2" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+        RCReader::delete_instance();
+        RCReader::initialize_instance();
+        reader = RCReader::instance();
+        DBG(cerr << "reader->check_env_var(\"DODS_CONF\"): " 
+            << reader->check_env_var("DODS_CONF") << endl);
+        DBG(cerr << "reader->get_validate_ssl(): " << reader->get_validate_ssl()
+            << endl);
+        CPPUNIT_ASSERT(reader->get_validate_ssl() == 1);
+
+        // Param cleared in file 
+	rc = (string)"DODS_CONF=" + TEST_SRC_DIR + "/rcreader-testsuite/dodsrc_ssl_3" ;
+	DBG(cerr << "rc: " << rc << endl);
+	putenv((char *)rc.c_str());
+
+        RCReader::delete_instance();
+        RCReader::initialize_instance();
+        reader = RCReader::instance();
+        DBG(cerr << "reader->get_validate_ssl(): " << reader->get_validate_ssl()
+            << endl);
+        CPPUNIT_ASSERT(reader->get_validate_ssl() == 0);
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RCReaderTest);
+
+} // namespace libdap
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/RegexTest.cc b/unit-tests/RegexTest.cc
new file mode 100644
index 0000000..38bf974
--- /dev/null
+++ b/unit-tests/RegexTest.cc
@@ -0,0 +1,149 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2005 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <string>
+
+#include "GNURegex.h"
+#include "Error.h"
+#include "debug.h"
+
+using namespace CppUnit;
+using namespace libdap;
+
+class RegexTest: public TestFixture {
+private:
+
+public:
+    RegexTest() {}
+    ~RegexTest() {}
+
+    void setUp() { 
+    } 
+
+    void tearDown() { 
+    }
+
+    CPPUNIT_TEST_SUITE( RegexTest );
+
+    CPPUNIT_TEST(ctor_test);
+    CPPUNIT_TEST(match_test);
+#if 1
+    CPPUNIT_TEST(search_test);
+#endif
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void ctor_test() {
+        try {
+            Regex r("abc");
+            CPPUNIT_ASSERT(1);
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error building object");
+        }
+
+        try {
+            Regex r("");
+            CPPUNIT_ASSERT(1);
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error building object");
+        }
+
+        try {
+            Regex r(".*");
+            CPPUNIT_ASSERT(1);
+        }
+        catch (Error &e) {
+            cerr << "Error: " << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error building object");
+        }
+    }
+    
+    void match_test() {
+        Regex simple("abc");
+        string s1 = "123abcdef";
+	DBG(cerr << "simple.match(s1.c_str(), s1.length()): "
+	     << simple.match(s1.c_str(), s1.length()) << endl);
+
+        CPPUNIT_ASSERT(simple.match(s1.c_str(), s1.length()) == 3);
+        CPPUNIT_ASSERT(simple.match(s1.c_str(), s1.length(), 4) == -1);
+        
+        Regex pattern("3.b");
+	DBG(cerr << "pattern.match(s1.c_str(), s1.length()): "
+	     << pattern.match(s1.c_str(), s1.length()) << endl);
+
+        CPPUNIT_ASSERT(pattern.match(s1.c_str(), s1.length()) == 3);
+        string s2 = "123acd";        
+        CPPUNIT_ASSERT(pattern.match(s2.c_str(), s2.length()) == -1);
+
+        Regex exclusion("[^123]+");
+	DBG(cerr << "exclusion.match(s1.c_str(), s1.length()): "
+	     << exclusion.match(s1.c_str(), s1.length()) << endl);
+
+        CPPUNIT_ASSERT(exclusion.match(s1.c_str(), s1.length()) == 6);
+        
+        Regex exclusion_range("[^0-9]+");
+        CPPUNIT_ASSERT(exclusion_range.match(s1.c_str(), s1.length()) == 6);
+    }    
+
+    void search_test() {
+        int matchlen;
+        
+        Regex simple("abc");
+        string s1 = "123abcdef";
+        CPPUNIT_ASSERT(simple.search(s1.c_str(), s1.length(), matchlen, 0) == 3);
+        CPPUNIT_ASSERT(matchlen == 3);
+        CPPUNIT_ASSERT(simple.search(s1.c_str(), s1.length(), matchlen, 4) == -1);
+        
+        Regex pattern("[a-z]+");
+        CPPUNIT_ASSERT(pattern.search(s1.c_str(), s1.length(), matchlen) == 3);
+        CPPUNIT_ASSERT(matchlen == 6);
+       
+        string s2 = "123abc123abcd";        
+        CPPUNIT_ASSERT(pattern.search(s2.c_str(), s2.length(), matchlen) == 3);
+        CPPUNIT_ASSERT(matchlen == 3);
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(RegexTest);
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/ResponseBuilderTest.cc b/unit-tests/ResponseBuilderTest.cc
new file mode 100644
index 0000000..cc2f866
--- /dev/null
+++ b/unit-tests/ResponseBuilderTest.cc
@@ -0,0 +1,494 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include "config.h"
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>  // for stat
+#include <cstring>
+#include <sstream>
+
+//#define DODS_DEBUG
+
+#include "ObjectType.h"
+#include "EncodingType.h"
+#include "ResponseBuilder.h"
+#include "DAS.h"
+#include "DDS.h"
+#include "GNURegex.h"
+#include "debug.h"
+
+#include "../tests/TestTypeFactory.h"
+#include "../tests/TestByte.h"
+
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+int test_variable_sleep_interval = 0;
+
+namespace libdap {
+
+class ResponseBuilderTest: public TestFixture {
+private:
+    ResponseBuilder *df, *df1, *df2, *df3, *df4, *df5;
+
+    AttrTable *cont_a;
+    DAS *das;
+    DDS *dds;
+    ostringstream oss;
+    time_t now;
+    char now_array[256];
+
+public:
+    ResponseBuilderTest()
+    {
+	now = time(0);
+	ostringstream time_string;
+	time_string << (int) now;
+	strncpy(now_array, time_string.str().c_str(), 255);
+	now_array[255] = '\0';
+    }
+
+    ~ResponseBuilderTest()
+    {
+    }
+
+    void setUp()
+    {
+	// Test pathname
+	df = new ResponseBuilder();
+#if 0
+	df->d_url = (string) TEST_SRC_DIR + "/server-testsuite/bears.data";
+#endif
+	// Test missing file
+	df1 = new ResponseBuilder();
+	df1->set_dataset_name("no-such-file");
+
+	// Test files in CWD. Note that the time is the GM time : Tue, 01 May
+	// 2001 01:08:14 -0700
+	df2 = new ResponseBuilder();
+	df2->set_dataset_name("test_config.h");
+
+	// This file has an ancillary DAS in the server-testsuite dir.
+	// df3 is also used to test escaping stuff in URLs. 5/4/2001 jhrg
+	df3 = new ResponseBuilder();
+	df3->set_dataset_name((string) TEST_SRC_DIR + "/server-testsuite/coads.data");
+	df3->set_ce("u,x,z[0]&grid(u,\"lat<10.0\")");
+	df3->set_timeout(1);
+
+	// Go back to this data source to test w/o an ancillary DAS.
+	df4 = new ResponseBuilder();
+	df4->set_dataset_name((string) TEST_SRC_DIR + "/server-testsuite/bears.data");
+	df4->set_ce("u,x,z[0]&grid(u,\"lat<10.0\")");
+	df4->set_timeout(1);
+
+	// Test escaping stuff. 5/4/2001 jhrg
+	df5 = new ResponseBuilder();
+	df5->set_dataset_name("nowhere%5Bmydisk%5Dmyfile");
+	df5->set_ce("u%5B0%5D");
+
+	cont_a = new AttrTable;
+	cont_a->append_attr("size", "Int32", "7");
+	cont_a->append_attr("type", "String", "cars");
+	das = new DAS;
+	das->add_table("a", cont_a);
+
+	// This AttrTable looks like:
+	//      Attributes {
+	//          a {
+	//              Int32 size 7;
+	//              String type cars;
+	//          }
+	//      }
+
+	TestTypeFactory ttf;
+	dds = new DDS(&ttf, "test");
+	TestByte a("a");
+	dds->add_var(&a);
+
+	dds->transfer_attributes(das);
+	dds->set_dap_major(3);
+	dds->set_dap_minor(2);
+    }
+
+    void tearDown()
+    {
+	delete df;
+	df = 0;
+	delete df1;
+	df1 = 0;
+	delete df2;
+	df2 = 0;
+	delete df3;
+	df3 = 0;
+	delete df4;
+	df4 = 0;
+	delete df5;
+	df5 = 0;
+
+	delete das;
+	das = 0;
+    }
+
+    bool re_match(Regex &r, const string &s)
+    {
+	DBG(cerr << "s.length(): " << s.length() << endl);
+	int pos = r.match(s.c_str(), s.length());
+	DBG(cerr << "r.match(s): " << pos << endl);
+	return pos > 0 && static_cast<unsigned> (pos) == s.length();
+    }
+
+    bool re_match_binary(Regex &r, const string &s)
+    {
+	DBG(cerr << "s.length(): " << s.length() << endl);
+	int pos = r.match(s.c_str(), s.length());
+	DBG(cerr << "r.match(s): " << pos << endl);
+	return pos > 0;
+    }
+#if 0
+    void add_keyword_test()
+    {
+	ResponseBuilder tdf;
+	tdf.add_keyword("test");
+	CPPUNIT_ASSERT(tdf.d_keywords.find("test") != tdf.d_keywords.end());
+	CPPUNIT_ASSERT(tdf.d_keywords.find("test") == tdf.d_keywords.begin());
+	CPPUNIT_ASSERT(*(tdf.d_keywords.find("test")) == string("test"));
+	tdf.add_keyword("dap3.3");
+	CPPUNIT_ASSERT(tdf.d_keywords.size() == 2);
+    }
+
+    void is_keyword_test()
+    {
+	ResponseBuilder tdf;
+	tdf.add_keyword("test");
+	tdf.add_keyword("dap3.3");
+	CPPUNIT_ASSERT(tdf.is_keyword("test"));
+	CPPUNIT_ASSERT(!tdf.is_keyword("TEST"));
+    }
+
+    void get_keywords()
+    {
+	ResponseBuilder tdf;
+	tdf.add_keyword("test");
+	tdf.add_keyword("dap2.0");
+	tdf.add_keyword("dap4.0");
+	CPPUNIT_ASSERT(tdf.d_keywords.size() == 3);
+
+	ostringstream oss;
+	list<string> kwds = tdf.get_keywords();
+	list<string>::iterator i = kwds.begin();
+	while (i != kwds.end())
+	    oss << *i++;
+
+	CPPUNIT_ASSERT(oss.str().find("test") != string::npos);
+	CPPUNIT_ASSERT(oss.str().find("dap2.0") != string::npos);
+	CPPUNIT_ASSERT(oss.str().find("dap4.0") != string::npos);
+    }
+#endif
+    void send_das_test()
+    {
+	Regex
+		r1(
+			"HTTP/1.0 200 OK\r\n\
+XDODS-Server: .*\
+XOPeNDAP-Server: .*\
+XDAP: .*\
+Date: .*\
+Last-Modified: .*\
+Content-Type: text/plain\r\n\
+Content-Description: dods_das\r\n\
+\r\n\
+Attributes \\{\n\
+    a \\{\n\
+        Int32 size 7;\n\
+        String type \"cars\";\n\
+    \\}\n\
+\\}\n");
+
+	df->send_das(oss, *das);
+
+	DBG(cerr << "DAS: " << oss.str() << endl);
+
+	CPPUNIT_ASSERT(re_match(r1, oss.str()));
+	oss.str("");
+    }
+
+    void send_dds_test()
+    {
+	Regex
+		r1(
+			"HTTP/1.0 200 OK\r\n\
+XDODS-Server: .*\
+XOPeNDAP-Server: .*\
+XDAP: .*\
+Date: .*\
+Last-Modified: .*\
+Content-Type: text/plain\r\n\
+Content-Description: dods_dds\r\n\
+\r\n\
+Dataset \\{\n\
+    Byte a;\n\
+\\} test;\n");
+
+	ConstraintEvaluator ce;
+
+	df->send_dds(oss, *dds, ce);
+
+	DBG(cerr << "DDS: " << oss.str() << endl);
+
+	CPPUNIT_ASSERT(re_match(r1, oss.str()));
+	oss.str("");
+    }
+
+    void send_ddx_test()
+    {
+	Regex
+		r1(
+			"HTTP/1.0 200 OK\r\n\
+XDODS-Server: .*\
+XOPeNDAP-Server: .*\
+XDAP: .*\
+Date: .*\
+Last-Modified: .*\
+Content-Type: text/xml\r\n\
+Content-Description: dap4-ddx\r\n\
+\r\n\
+<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>.*\
+<Dataset name=\"test\".*\
+.*\
+.*\
+.*\
+.*\
+.*\
+.*\
+dapVersion=\"3.2\">.*\
+.*\
+<Byte name=\"a\">.*\
+    <Attribute name=\"size\" type=\"Int32\">.*\
+        <value>7</value>.*\
+    </Attribute>.*\
+    <Attribute name=\"type\" type=\"String\">.*\
+        <value>cars</value>.*\
+    </Attribute>.*\
+</Byte>.*\
+.*\
+</Dataset>.*");
+
+	ConstraintEvaluator ce;
+
+	try {
+	    df->send_ddx(oss, *dds, ce);
+
+	    DBG(cerr << "DDX: " << oss.str() << endl);
+
+	    CPPUNIT_ASSERT(re_match(r1, oss.str()));
+	    oss.str("");
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL("Error: " + e.get_error_message());
+	}
+    }
+
+    void send_data_ddx_test()
+    {
+	Regex
+		r1(
+			"HTTP/1.0 200 OK\r\n\
+.*\
+XDAP:.*\r\n\
+.*\
+Content-Type: Multipart/Related; boundary=boundary; start=\"<start at opendap.org>\"; type=\"Text/xml\"\r\n\
+Content-Description: dap4-data-ddx\r\n\
+\r\n\
+--boundary\r\n\
+Content-Type: Text/xml; charset=iso-8859-1\r\n\
+Content-Id: <start at opendap.org>\r\n\
+Content-Description: dap4-ddx\r\n\
+\r\n\
+<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>.*\
+<Dataset name=\"test\".*\
+.*\
+dapVersion=\"3.2\">.*\
+.*\
+    <Byte name=\"a\">.*\
+        <Attribute name=\"size\" type=\"Int32\">.*\
+            <value>7</value>.*\
+        </Attribute>.*\
+        <Attribute name=\"type\" type=\"String\">.*\
+            <value>cars</value>.*\
+        </Attribute>.*\
+    </Byte>.*\
+.*\
+    <blob href=\"cid:.*@.*\"/>.*\
+</Dataset>.*\
+--boundary\r\n\
+Content-Type: application/octet-stream\r\n\
+Content-Id: <.*@.*>\r\n\
+Content-Description: dap4-data\r\n\
+Content-Encoding: binary\r\n\
+\r\n\
+.*");
+
+	// I do not look for the closing '--boundary' because the binary
+	// data breaks the regex functions in the c library WRT subsequent
+	// pattern matches. jhrg
+	//--boundary--\r\n");
+
+	ConstraintEvaluator ce;
+
+	try {
+	    df->send_data_ddx(oss, *dds, ce, "start at opendap.org", "boundary", true);
+
+	    DBG(cerr << "DataDDX: " << oss.str() << endl);
+
+	    CPPUNIT_ASSERT(re_match_binary(r1, oss.str()));
+	    oss.str("");
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL("Error: " + e.get_error_message());
+	}
+    }
+
+    void send_data_ddx_test2()
+    {
+	Regex
+		r1(
+			"--boundary\r\n\
+Content-Type: Text/xml; charset=iso-8859-1\r\n\
+Content-Id: <start at opendap.org>\r\n\
+Content-Description: dap4-ddx\r\n\
+\r\n\
+<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>.*\
+<Dataset name=\"test\".*\
+.*\
+dapVersion=\"3.2\">.*\
+.*\
+    <Byte name=\"a\">.*\
+        <Attribute name=\"size\" type=\"Int32\">.*\
+            <value>7</value>.*\
+        </Attribute>.*\
+        <Attribute name=\"type\" type=\"String\">.*\
+            <value>cars</value>.*\
+        </Attribute>.*\
+    </Byte>.*\
+.*\
+    <blob href=\"cid:.*@.*\"/>.*\
+</Dataset>.*\
+--boundary\r\n\
+Content-Type: application/octet-stream\r\n\
+Content-Id: <.*@.*>\r\n\
+Content-Description: dap4-data\r\n\
+Content-Encoding: binary\r\n\
+\r\n\
+.*");
+
+	ConstraintEvaluator ce;
+
+	try {
+	    df->send_data_ddx(oss, *dds, ce, "start at opendap.org", "boundary", false);
+	    DBG(cerr << "DataDDX: " << oss.str() << endl);
+	    CPPUNIT_ASSERT(re_match_binary(r1, oss.str()));
+
+	    // Unlike the test where the full headers are generated, there's
+	    // no check for a conditional response here because that feature
+	    // of ResponseBuilder is only supported when MIME headers are built by
+	    // the class. In order to return a '304' response, headers must be
+	    // built.
+	}
+	catch (Error &e) {
+	    CPPUNIT_FAIL("Error: " + e.get_error_message());
+	}
+    }
+
+    void escape_code_test()
+    {
+	// These should NOT be escaped.
+
+	DBG(cerr << df3->get_dataset_name() << endl);
+	DBG(cerr << df3->get_ce() << endl);
+
+	CPPUNIT_ASSERT(df3->get_dataset_name() == (string)TEST_SRC_DIR + "/server-testsuite/coads.data");
+	CPPUNIT_ASSERT(df3->get_ce() == "u,x,z[0]&grid(u,\"lat<10.0\")");
+
+	// The ResponseBuilder instance is feed escaped values; they should be
+	// unescaped by the ctor and the mutators. 5/4/2001 jhrg
+
+	DBG(cerr << df5->get_dataset_name() << endl);
+	DBG(cerr << df5->get_ce() << endl);
+
+	CPPUNIT_ASSERT(df5->get_dataset_name() == "nowhere[mydisk]myfile");
+	CPPUNIT_ASSERT(df5->get_ce() == "u[0]");
+
+	df5->set_ce("u%5B0%5D");
+	CPPUNIT_ASSERT(df5->get_ce() == "u[0]");
+
+	df5->set_ce("Grid%20u%5B0%5D");
+	CPPUNIT_ASSERT(df5->get_ce() == "Grid%20u[0]");
+    }
+
+    // This tests reading the timeout value from argv[].
+    void timeout_test()
+    {
+	CPPUNIT_ASSERT(df3->get_timeout() == 1);
+	CPPUNIT_ASSERT(df1->get_timeout() == 0);
+    }
+
+CPPUNIT_TEST_SUITE( ResponseBuilderTest );
+#if 0
+	CPPUNIT_TEST(add_keyword_test);
+	CPPUNIT_TEST(is_keyword_test);
+	CPPUNIT_TEST(get_keywords);
+#endif
+	CPPUNIT_TEST(send_das_test);
+	CPPUNIT_TEST(send_dds_test);
+
+	CPPUNIT_TEST(send_ddx_test);
+	CPPUNIT_TEST(send_data_ddx_test);
+	CPPUNIT_TEST(send_data_ddx_test2);
+
+	CPPUNIT_TEST(escape_code_test);
+
+    CPPUNIT_TEST_SUITE_END();
+};
+CPPUNIT_TEST_SUITE_REGISTRATION(ResponseBuilderTest);
+}
+
+int main(int, char**)
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
+
+    bool wasSuccessful = runner.run("", false);
+
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/SequenceTest.cc b/unit-tests/SequenceTest.cc
new file mode 100644
index 0000000..bbcdb16
--- /dev/null
+++ b/unit-tests/SequenceTest.cc
@@ -0,0 +1,428 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include <string>
+#include <cstring>
+
+//#define DODS_DEBUG
+
+#include "DDS.h"
+#include "ConstraintEvaluator.h"
+
+#include "../tests/TestTypeFactory.h"
+#include "../tests/TestSequence.h"
+#include "../tests/TestInt32.h"
+#include "../tests/TestStr.h"
+
+#include "GNURegex.h"
+#include "debug.h"
+
+using namespace CppUnit;
+using namespace std;
+
+int test_variable_sleep_interval;
+
+//  Note: MS VC++ won't tolerate the embedded newlines in strings, hence the \n
+//  is explicit.
+static const char *s_as_string = \
+"BaseType \\(0x.*\\):\n\
+          _name: s\n\
+          _type: Sequence\n\
+          _dataset: \n\
+          _read_p: 0\n\
+          _send_p: 0\n\
+          _synthesized_p: 0\n\
+          d_parent: 0\n\
+          d_attr: 0x.*\n\
+BaseType \\(0x.*\\):\n\
+          _name: i1\n\
+          _type: Int32\n\
+          _dataset: \n\
+          _read_p: 0\n\
+          _send_p: 0\n\
+          _synthesized_p: 0\n\
+          d_parent: 0x.*\n\
+          d_attr: 0x.*\n\
+BaseType \\(0x.*\\):\n\
+          _name: str1\n\
+          _type: String\n\
+          _dataset: \n\
+          _read_p: 0\n\
+          _send_p: 0\n\
+          _synthesized_p: 0\n\
+          d_parent: 0x.*\n\
+          d_attr: 0x.*\n\
+BaseType \\(0x.*\\):\n\
+          _name: i2\n\
+          _type: Int32\n\
+          _dataset: \n\
+          _read_p: 0\n\
+          _send_p: 0\n\
+          _synthesized_p: 0\n\
+          d_parent: 0x.*\n\
+          d_attr: 0x.*\n\
+\n";
+
+static Regex s_regex(s_as_string);
+
+namespace libdap
+{
+
+class SequenceTest : public TestFixture {
+private:
+    DDS *dds;
+    TestSequence *s, *ss, *ps, *sss, *ts, *tts;
+
+public:
+    SequenceTest() {}
+    ~SequenceTest() {}
+
+    void setUp() { 
+	// Set up a simple sequence. Used to test ctor, assigment, et cetera.
+	s = new TestSequence("s");
+	s->add_var(new TestInt32("i1"));
+	s->add_var(new TestStr("str1"));
+	s->add_var(new TestInt32("i2"));
+        s->set_series_values(true);        
+
+        // Set ss, a two level sequence
+        ss = new TestSequence("ss");
+        ss->add_var(new TestInt32("i1"));
+        ss->set_series_values(true);
+        
+        ps = new TestSequence("child_of_ss");
+        ps->add_var(new TestInt32("i2"));
+        ps->set_series_values(true);
+        
+        ss->add_var(ps);
+        
+	// Set up sss, used to test multi-level sequences
+	sss = new TestSequence("sss");
+	sss->add_var(new TestInt32("i1"));
+	
+	ts = new TestSequence("child_of_sss");
+	ts->add_var(new TestStr("str1"));
+	
+	tts = new TestSequence("child_of_child_of_sss");
+	tts->add_var(new TestInt32("i2"));
+	ts->add_var(tts);
+
+	sss->add_var(ts);	// This has to be here because add_var adds
+				// copies of its argument.
+        sss->set_series_values(true);
+        
+        TestTypeFactory ttf;
+        dds = new DDS(&ttf);
+        dds->add_var(s);
+        dds->add_var(ss);
+        dds->add_var(sss);
+    } 
+
+    void tearDown() { 
+	delete s; s = 0;
+        delete ss; ss = 0;
+        delete ps; ps = 0;
+	delete sss; sss = 0;
+	delete ts; ts = 0;
+	delete tts; tts = 0;
+        
+        delete dds; dds = 0;
+    }
+
+    bool re_match(Regex &r, const char *s) {
+	int match_position = r.match(s, strlen(s));
+	DBG(cerr << "match position: " << match_position 
+	    << " string length: " << (int)strlen(s) << endl);
+	return match_position == (int)strlen(s);
+    }
+
+    CPPUNIT_TEST_SUITE( SequenceTest );
+
+    CPPUNIT_TEST(ctor_test);
+    CPPUNIT_TEST(assignment);
+    CPPUNIT_TEST(copy_ctor);
+#if 0
+    CPPUNIT_TEST(test_set_leaf_sequence);
+    CPPUNIT_TEST(test_set_leaf_sequence2);
+    CPPUNIT_TEST(test_set_leaf_sequence3);
+    CPPUNIT_TEST(intern_data_for_leaf_test);
+    CPPUNIT_TEST(intern_data_test1);
+    CPPUNIT_TEST(intern_data_test2);
+    CPPUNIT_TEST(intern_data_test3);
+#endif
+
+    CPPUNIT_TEST_SUITE_END();
+
+    // Tests for methods
+    void intern_data_test1() {
+        ConstraintEvaluator ce;
+        s->set_send_p(true);
+        s->set_leaf_sequence();
+        try {
+            s->intern_data(ce, *dds);
+            
+            // Test the first value in the first four rows
+            BaseType *btp = s->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = s->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = s->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = s->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+            DBG(s->print_val(stdout));
+        }
+        catch (Error &e) {
+            cerr << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in transfer_data_for_leaf_test1()");
+        }
+    }
+    
+    void intern_data_test2() {
+        ConstraintEvaluator ce;
+        ss->set_send_p(true);
+        ss->set_leaf_sequence();
+        try {
+            ss->intern_data(ce, *dds);
+            DBG(ss->print_val(stdout));
+            
+            // Test the first value in the first four rows
+            BaseType *btp = ss->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = ss->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = ss->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = ss->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+            
+            // Look at some values in the inner sequence
+            Sequence *sp = dynamic_cast<Sequence*>(ss->var_value(0, 1));
+            CPPUNIT_ASSERT(sp);
+            btp = sp->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = sp->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = sp->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = sp->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+            
+            sp = dynamic_cast<Sequence*>(ss->var_value(3, 1));
+            CPPUNIT_ASSERT(sp);
+            btp = sp->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = sp->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = sp->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = sp->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+        }
+        catch (Error &e) {
+            cerr << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in transfer_data_test2()");
+        }
+    }
+    
+    void intern_data_test3() {
+        ConstraintEvaluator ce;
+        sss->set_send_p(true);
+        sss->set_leaf_sequence();
+        try {
+            sss->intern_data(ce, *dds);
+            DBG(sss->print_val_by_rows(stdout, "", true, true));
+            // Test the first value in the first four rows
+            BaseType *btp = sss->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = sss->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = sss->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = sss->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+            
+            // Look at some values in the inner-most sequence (skip the middle
+            // sequence since I don't have a value() accessor for that yet.
+            Sequence *sp = dynamic_cast<Sequence*>(sss->var_value(0, 1));
+            CPPUNIT_ASSERT(sp);
+            Sequence *ssp = dynamic_cast<Sequence*>(sp->var_value(0, 1));
+            CPPUNIT_ASSERT(ssp);
+            
+            btp = ssp->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = ssp->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = ssp->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = ssp->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+            
+            sp = dynamic_cast<Sequence*>(sss->var_value(3, 1));
+            CPPUNIT_ASSERT(sp);
+            ssp = dynamic_cast<Sequence*>(sp->var_value(3, 1));
+            CPPUNIT_ASSERT(ssp);
+            
+            btp = ssp->var_value(0, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = ssp->var_value(1, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = ssp->var_value(2, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = ssp->var_value(3, 0);
+            CPPUNIT_ASSERT(btp && dynamic_cast<Int32&>(*btp).value() == 1048576);
+        }
+        catch (Error &e) {
+            cerr << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in transfer_data_test3()");
+        }
+    }
+    
+    void intern_data_for_leaf_test() {
+        ConstraintEvaluator ce;
+        s->set_send_p(true);
+        try {
+            Sequence::sequence_values_stack_t sequence_values_stack;
+            sequence_values_stack.push(&s->d_values);
+            s->intern_data_for_leaf(*dds, ce, sequence_values_stack);
+            
+            // Test the first value in the first four rows
+            BaseType *btp = s->var_value(0, 0);
+            CPPUNIT_ASSERT(dynamic_cast<Int32&>(*btp).value() == 32);
+            btp = s->var_value(1, 0);
+            CPPUNIT_ASSERT(dynamic_cast<Int32&>(*btp).value() == 1024);
+            btp = s->var_value(2, 0);
+            CPPUNIT_ASSERT(dynamic_cast<Int32&>(*btp).value() == 32768);
+            btp = s->var_value(3, 0);
+            CPPUNIT_ASSERT(dynamic_cast<Int32&>(*btp).value() == 1048576);
+            DBG(s->print_val(stdout));
+        }
+        catch (Error &e) {
+            cerr << e.get_error_message() << endl;
+            CPPUNIT_ASSERT(!"Error in transfer_data_for_leaf_test()");
+        }
+    }
+    
+    void test_set_leaf_sequence3() {
+        // Test for the rejection of a Sequence with two sequences in it.
+        sss->add_var(ss);
+        sss->set_send_p(true);
+        try {
+             sss->set_leaf_sequence(1);
+             CPPUNIT_ASSERT(!"Should have thrown Error");
+        }
+        catch (Error &e) {
+             cerr << e.get_error_message() << endl;
+             CPPUNIT_ASSERT("Caught Error");
+        }
+    }
+
+    void test_set_leaf_sequence2() {
+        // Three level sequence
+        sss->set_send_p(true);          // set send_p for whole seq
+        // Now the lowest sequence is not longer to be sent. The middle sequence
+        // is the lowest with fields to be sent and so should be the leaf.
+        Sequence::Vars_iter i = sss->var_begin();
+        Sequence *inner = dynamic_cast<Sequence*>(*++i);
+        i = inner->var_begin();
+        inner = dynamic_cast<Sequence*>(*++i);
+        inner->set_send_p(false);       // now clear send_p for the inner most seq
+        sss->set_leaf_sequence(1);
+
+        CPPUNIT_ASSERT(!sss->is_leaf_sequence());
+        
+        i = sss->var_begin();
+        inner = dynamic_cast<Sequence*>(*++i);
+        CPPUNIT_ASSERT(inner && inner->is_leaf_sequence());
+
+        i = inner->var_begin();
+        Sequence *inner2 = dynamic_cast<Sequence*>(*++i);
+        CPPUNIT_ASSERT(inner2 && !inner2->is_leaf_sequence());
+    }
+
+    void test_set_leaf_sequence() {
+        // One level sequence
+        s->set_send_p(true);
+        s->set_leaf_sequence(1);
+        CPPUNIT_ASSERT(s->is_leaf_sequence());
+        
+        // Two level sequence
+        ss->set_send_p(true);
+        ss->set_leaf_sequence(1);
+        CPPUNIT_ASSERT(!ss->is_leaf_sequence());
+        // add_var() _copies_ the object, so ps should not be used here.
+        Sequence::Vars_iter i = ss->var_begin();
+        Sequence *inner = dynamic_cast<Sequence*>(*++i);
+        CPPUNIT_ASSERT(inner->type() == dods_sequence_c && inner->is_leaf_sequence());
+        
+        // Three level sequence
+        sss->set_send_p(true);
+        sss->set_leaf_sequence(1);
+        CPPUNIT_ASSERT(!sss->is_leaf_sequence());
+        
+        i = sss->var_begin();
+        inner = dynamic_cast<Sequence*>(*++i);
+        CPPUNIT_ASSERT(inner && !inner->is_leaf_sequence());
+
+        i = inner->var_begin();
+        Sequence *inner2 = dynamic_cast<Sequence*>(*++i);
+        CPPUNIT_ASSERT(inner2 && inner2->is_leaf_sequence());
+    }
+    
+    void ctor_test() {
+	DBG(cerr << "s: " << s->toString() << endl);
+	CPPUNIT_ASSERT(re_match(s_regex, s->toString().c_str()));
+    }
+
+    void assignment() {
+	Sequence ts2 = *s;
+	DBG(cerr << "ts2: " << ts2.toString() << endl);
+	CPPUNIT_ASSERT(re_match(s_regex, ts2.toString().c_str()));
+    }
+
+    void copy_ctor() {
+	Sequence s2 = *s;
+	CPPUNIT_ASSERT(re_match(s_regex, s2.toString().c_str()));
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SequenceTest);
+
+}
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
diff --git a/unit-tests/SignalHandlerTest.cc b/unit-tests/SignalHandlerTest.cc
new file mode 100644
index 0000000..7d281db
--- /dev/null
+++ b/unit-tests/SignalHandlerTest.cc
@@ -0,0 +1,112 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#ifndef WIN32
+#include <unistd.h>  // for alarm sleep
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+ 
+#include "SignalHandler.h"
+#include "debug.h"
+
+using namespace CppUnit;
+using namespace std;
+
+namespace libdap
+{
+
+class SignalHandlerTest : public TestFixture {
+private:
+    SignalHandler *sh;
+    TestHandler *th;
+
+public: 
+    SignalHandlerTest() {}
+    ~SignalHandlerTest() {}
+
+    void setUp() {
+	sh = SignalHandler::instance();
+	th = new TestHandler;
+    }
+
+    void tearDown() {
+	delete th; th = 0;
+    }
+
+    // Tests for methods
+    void register_handler_test() {
+	sh->register_handler(SIGALRM, th);
+	CPPUNIT_ASSERT(sh->d_signal_handlers[SIGALRM] == th);
+    }
+
+    void remove_handler_test() {
+	CPPUNIT_ASSERT(sh->remove_handler(SIGALRM) == th);
+    }
+
+    void alarm_test() {
+	// Ignore the alarm signal and then register our handler. Without
+	// setting alram to ignore first the SignalHandler will call our
+	// EventHandler and then perform the default action for the signal,
+	// which is call exit() with EXIT_FAILURE.
+	signal(SIGALRM, SIG_IGN);
+	sh->register_handler(SIGALRM, th);
+	alarm(1);
+	sleep(10);
+	CPPUNIT_ASSERT(th->flag == 1);
+    }
+
+    CPPUNIT_TEST_SUITE( SignalHandlerTest );
+
+    CPPUNIT_TEST(register_handler_test);
+    CPPUNIT_TEST(remove_handler_test);
+    CPPUNIT_TEST(alarm_test);
+
+    CPPUNIT_TEST_SUITE_END();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(SignalHandlerTest);
+
+}
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
+
+
+
diff --git a/unit-tests/ancT.cc b/unit-tests/ancT.cc
new file mode 100644
index 0000000..6caadca
--- /dev/null
+++ b/unit-tests/ancT.cc
@@ -0,0 +1,110 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#ifndef TM_IN_SYS_TIME
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>   // for stat
+
+#include <string>
+#include <sstream>
+
+//#define DODS_DEBUG
+
+#include "Ancillary.h"
+
+#include "debug.h"
+#include <test_config.h>
+
+using namespace CppUnit;
+using namespace std;
+using namespace libdap;
+
+class ancT : public TestFixture {
+private:
+
+protected:
+
+public:
+    ancT() {}
+    ~ancT() {}
+    
+    void setUp () {}
+
+    void tearDown() {}
+
+    CPPUNIT_TEST_SUITE( ancT );
+
+    CPPUNIT_TEST(find_ancillary_file_test);
+    CPPUNIT_TEST(find_group_ancillary_file_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    void find_ancillary_file_test() {
+	CPPUNIT_ASSERT(Ancillary::find_ancillary_file((string)TEST_SRC_DIR + "/das-testsuite/test.1", "das", "", "") 
+		       == (string)TEST_SRC_DIR + "/das-testsuite/test.1.das");
+	CPPUNIT_ASSERT(Ancillary::find_ancillary_file((string)TEST_SRC_DIR + "/das-testsuite/special.test.hdf", "das", "", "") 
+		       == (string)TEST_SRC_DIR + "/das-testsuite/special.test.das");
+	CPPUNIT_ASSERT(Ancillary::find_ancillary_file((string)TEST_SRC_DIR + "/das-testsuite/test.2", "das", "", "") 
+		       == (string)TEST_SRC_DIR + "/das-testsuite/das");
+	CPPUNIT_ASSERT(Ancillary::find_ancillary_file((string)TEST_SRC_DIR + "/das-testsuite/test.1.gz", "das", "", "") 
+		       == (string)TEST_SRC_DIR + "/das-testsuite/test.1.das");
+	CPPUNIT_ASSERT(Ancillary::find_ancillary_file((string)TEST_SRC_DIR + "/das-testsuite/test.3.Z", "das", "", "") 
+		       == (string)TEST_SRC_DIR + "/das-testsuite/test.3.Z.das");
+    }
+ 
+    void find_group_ancillary_file_test() {
+	CPPUNIT_ASSERT(Ancillary::find_group_ancillary_file((string)TEST_SRC_DIR + "/cgi-util-tests/02group.hdf", ".htm")
+		       == (string)TEST_SRC_DIR + "/cgi-util-tests/group.htm");
+	CPPUNIT_ASSERT(Ancillary::find_group_ancillary_file((string)TEST_SRC_DIR + "/cgi-util-tests/group01.hdf", ".htm")
+		       == (string)TEST_SRC_DIR + "/cgi-util-tests/group.htm");
+	CPPUNIT_ASSERT(Ancillary::find_group_ancillary_file((string)TEST_SRC_DIR + "/cgi-util-tests/group.hdf", ".htm")
+		       == "");
+    }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(ancT);
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/arrayT.cc b/unit-tests/arrayT.cc
new file mode 100644
index 0000000..465dbb0
--- /dev/null
+++ b/unit-tests/arrayT.cc
@@ -0,0 +1,190 @@
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include <iostream>
+#include "TestArray.h"
+#include "TestInt16.h"
+#include "TestTypeFactory.h"
+#include "util.h"
+//#include "Pix.h"
+
+using std::cerr ;
+using std::endl ;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts. 
+
+class arrayT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( arrayT ) ;
+CPPUNIT_TEST( arrayT_test ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+private:
+    /* TEST PRIVATE DATA */
+    TestTypeFactory *factory;
+    
+public:
+    void setUp()
+    {
+        factory = new TestTypeFactory;
+    }
+
+    void tearDown() 
+    {
+        delete factory; factory = 0;
+    }
+
+    void arrayT_test()
+    {
+	BaseType *bt = factory->NewInt16() ;
+
+	TestArray ar( "My Array", bt ) ;
+
+	int l = ar.length() ;
+	CPPUNIT_ASSERT( l == -1 ) ;
+
+	try
+	{
+	    int w = ar.width() ;
+	    CPPUNIT_ASSERT( w == ( l * (int)bt->width() ) ) ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "Unable to retrieve width" ) ;
+	}
+
+	ar.append_dim( 4, "dim1" ) ;
+
+	l = ar.length() ;
+	CPPUNIT_ASSERT( l == 4 ) ;
+
+	try
+	{
+	    int w = ar.width() ;
+	    CPPUNIT_ASSERT( w == ( l * (int)bt->width() ) ) ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "Unable to retrieve width" ) ;
+	}
+
+	ar.append_dim( 3, "dim2" ) ;
+
+	l = ar.length() ;
+	CPPUNIT_ASSERT( l == 12 ) ;
+
+	try
+	{
+	    int w = ar.width() ;
+	    CPPUNIT_ASSERT( w == ( l * (int)bt->width() ) ) ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "Unable to retrieve width" ) ;
+	}
+
+	ar.append_dim( 2, "dim3" ) ;
+
+	l = ar.length() ;
+	CPPUNIT_ASSERT( l == 24 ) ;
+
+	try
+	{
+	    int w = ar.width() ;
+	    CPPUNIT_ASSERT( w == ( l * (int)bt->width() ) ) ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "Unable to retrieve width" ) ;
+	}
+
+	vector<string> dims ;
+	typedef vector<string>::const_iterator citer ;
+	dims.push_back( "dim1" ) ;
+	dims.push_back( "dim2" ) ;
+	dims.push_back( "dim3" ) ;
+
+	vector<int> dimsize ;
+	typedef vector<int>::const_iterator dsiter ;
+	dimsize.push_back( 4 ) ;
+	dimsize.push_back( 3 ) ;
+	dimsize.push_back( 2 ) ;
+
+	citer i = dims.begin() ;
+	dsiter d = dimsize.begin() ;
+	Array::Dim_iter diter = ar.dim_begin() ;
+	i = dims.begin() ;
+	d = dimsize.begin() ;
+	for( ; diter != ar.dim_end() && i != dims.end(); diter++, i++, d++ )
+	{
+	    CPPUNIT_ASSERT( ar.dimension_name( diter ) == (*i) ) ;
+	    if( ar.dimension_name( diter ) == (*i) )
+	    {
+		CPPUNIT_ASSERT( ar.dimension_size( diter ) == (*d) ) ;
+		CPPUNIT_ASSERT( ar.dimension_start( diter ) == 0 ) ;
+		CPPUNIT_ASSERT( ar.dimension_stop( diter ) == (*d)-1 ) ;
+		CPPUNIT_ASSERT( ar.dimension_stride( diter ) == 1 ) ;
+	    }
+	}
+	if( diter != ar.dim_end() && i == dims.end() )
+	{
+	    CPPUNIT_FAIL( "too many dimensions" ) ;
+	}
+	else if( diter == ar.dim_end() && i != dims.end() )
+	{
+	    CPPUNIT_FAIL( "not enough dimensions" ) ;
+	}
+
+	unsigned int numdims = ar.dimensions( ) ;
+	CPPUNIT_ASSERT( numdims == 3 ) ;
+
+	diter = ar.dim_begin() ;
+	ar.add_constraint( diter, 0, 2, 3 ) ;
+
+	l = ar.length() ;
+	CPPUNIT_ASSERT( l == 12 ) ;
+
+	diter = ar.dim_begin() ;
+	diter++ ;
+	ar.add_constraint( diter, 0, 2, 2 ) ;
+
+	l = ar.length() ;
+	CPPUNIT_ASSERT( l == 8 ) ;
+
+	ar.reset_constraint() ;
+
+	l = ar.length() ;
+	CPPUNIT_ASSERT( l == 24 ) ;
+
+	bool is_read = ar.read() ;
+	CPPUNIT_ASSERT( is_read == true ) ;
+
+	cout << ar << endl ;
+
+	/* ar.print_val( stdout ) ; */
+
+	delete bt ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( arrayT ) ;
+
+int main(int, char **)
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( 
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/attrTableT.cc b/unit-tests/attrTableT.cc
new file mode 100644
index 0000000..d322cd4
--- /dev/null
+++ b/unit-tests/attrTableT.cc
@@ -0,0 +1,318 @@
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include <iostream>
+#include <vector>
+#include "AttrTable.h"
+//#include "Pix.h"
+
+using std::cerr ;
+using std::endl ;
+using std::vector ;
+
+using namespace libdap ;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts. 
+
+class attrTableT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( attrTableT ) ;
+CPPUNIT_TEST( attrTableT_test ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+private:
+    /* TEST PRIVATE DATA */
+
+public:
+    void setUp()
+    {
+    }
+
+    void tearDown() 
+    {
+    }
+
+    void attrTableT_test()
+    {
+	AttrTable at ;
+
+	unsigned int at_size = at.get_size() ;
+	CPPUNIT_ASSERT( at_size == 0 ) ;
+
+	string at_name = at.get_name() ;
+	CPPUNIT_ASSERT( at_name == "" ) ;
+
+	at.set_name( "My Attributes" ) ;
+	at_name = at.get_name() ;
+	CPPUNIT_ASSERT( at_name == "My Attributes" ) ;
+
+	AttrTable *container = at.find_container( "dummy_container" ) ;
+	CPPUNIT_ASSERT( !container ) ;
+
+	AttrTable *dummy_at = 0 ;
+
+	AttrTable::Attr_iter iter ;
+	at.find( "dummy_attr", &dummy_at, &iter ) ;
+	CPPUNIT_ASSERT( iter == at.attr_end() ) ;
+
+	string attr_name = "attr1" ;
+	string attr_type = "string" ;
+	string attr_value = "attr1Value1" ;
+	at.append_attr( attr_name, attr_type, attr_value ) ;
+
+	attr_name = "attr2" ;
+	attr_type = "string" ;
+	attr_value = "attr2Value1" ;
+	at.append_attr( attr_name, attr_type, attr_value ) ;
+
+	attr_name = "attr3" ;
+	attr_type = "string" ;
+	attr_value = "attr3Value1" ;
+	at.append_attr( attr_name, attr_type, attr_value ) ;
+
+	at.append_attr( "attr4", "string", "attr4Value1" ) ;
+
+	at_size = at.get_size() ;
+	CPPUNIT_ASSERT( at_size == 4 ) ;
+
+	//at.print( stdout ) ;
+	iter = at.attr_end() ;
+	at.find( "attr3", &dummy_at, &iter ) ;
+	CPPUNIT_ASSERT( iter != at.attr_end() ) ;
+
+	iter = at.attr_end() ;
+	at.find( "dummy_attr", &dummy_at, &iter ) ;
+	CPPUNIT_ASSERT( iter == at.attr_end() ) ;
+
+	attr_type = at.get_type( "attr3" ) ;
+	CPPUNIT_ASSERT( attr_type == "String" ) ;
+
+	AttrType attr_type_enum = at.get_attr_type( "attr3" ) ;
+	CPPUNIT_ASSERT( attr_type_enum == Attr_string ) ;
+
+	unsigned int num_attrs = at.get_attr_num( "attr3" ) ;
+	CPPUNIT_ASSERT( num_attrs == 1 ) ;
+
+	attr_value = at.get_attr( "attr3" ) ;
+	CPPUNIT_ASSERT( attr_value == "attr3Value1" ) ;
+
+	at.append_attr( "attr3", "string", "attr3Value2" ) ;
+	at.append_attr( "attr3", "string", "attr3Value3" ) ;
+	at.append_attr( "attr3", "string", "attr3Value4" ) ;
+
+	attr_value = at.get_attr( "attr3" ) ;
+	CPPUNIT_ASSERT( attr_value == "attr3Value1" ) ;
+
+	vector<string> sb ;
+	sb.push_back( "attr3Value1" ) ;
+	sb.push_back( "attr3Value2" ) ;
+	sb.push_back( "attr3Value3" ) ;
+	sb.push_back( "attr3Value4" ) ;
+
+	typedef vector<string>::const_iterator str_citer ;
+	typedef vector<string>::iterator str_iter ;
+
+	vector<string> *values = at.get_attr_vector( "attr3" ) ;
+	CPPUNIT_ASSERT( values ) ;
+	if( values )
+	{
+	    str_citer vi = values->begin() ;
+	    str_citer sbi = sb.begin() ;
+	    for( ; vi != values->end() && sbi != sb.end(); vi++, sbi++ )
+	    {
+		CPPUNIT_ASSERT( (*vi) == (*sbi) ) ;
+	    }
+	    CPPUNIT_ASSERT( vi == values->end() && sbi == sb.end() ) ;
+	    if( vi == values->end() && sbi != sb.end() )
+	    {
+		CPPUNIT_FAIL( "not enough values" ) ;
+	    }
+	    else if( vi != values->end() && sbi == sb.end() )
+	    {
+		CPPUNIT_FAIL( "too many values" ) ;
+	    }
+	}
+
+	vector<string> attrs ;
+	attrs.push_back( "attr1" ) ;
+	attrs.push_back( "attr2" ) ;
+	attrs.push_back( "attr3" ) ;
+	attrs.push_back( "attr4" ) ;
+
+        str_citer ai = attrs.begin() ;
+        AttrTable::Attr_iter i = at.attr_begin() ;
+	// ai = attrs.begin() ;
+	for( ; i != at.attr_end() && ai != attrs.end(); i++, ai++ )
+	{
+	    CPPUNIT_ASSERT( (*i)->name == (*ai) ) ;
+	}
+	CPPUNIT_ASSERT( i == at.attr_end() && ai == attrs.end() ) ;
+	if( i != at.attr_end() && ai == attrs.end() )
+	{
+	    CPPUNIT_FAIL( "too many attributes"  ) ;
+	}
+	else if( i == at.attr_end() && ai != attrs.end() )
+	{
+	    CPPUNIT_FAIL( "not enough attributes"  ) ;
+	}
+
+	iter = at.attr_end() ;
+	at.find( "attr3", &dummy_at, &iter ) ;
+	CPPUNIT_ASSERT( iter != at.attr_end() ) ;
+
+	attr_name = at.get_name( iter ) ;
+	CPPUNIT_ASSERT( attr_name == "attr3" ) ;
+
+	bool isit = at.is_container( iter ) ;
+	CPPUNIT_ASSERT( isit == false ) ;
+
+	dummy_at = at.get_attr_table( iter ) ;
+	CPPUNIT_ASSERT( !dummy_at ) ;
+
+	attr_type = at.get_type( iter ) ;
+	CPPUNIT_ASSERT( attr_type == "String" ) ;
+
+	attr_type_enum = at.get_attr_type( iter ) ;
+	CPPUNIT_ASSERT( attr_type_enum == Attr_string ) ;
+
+	attr_value = at.get_attr( iter ) ;
+	CPPUNIT_ASSERT( attr_value == "attr3Value1" ) ;
+
+	attr_value = at.get_attr( iter, 1 ) ;
+	CPPUNIT_ASSERT( attr_value == "attr3Value2" ) ;
+
+	values = at.get_attr_vector( iter ) ;
+	CPPUNIT_ASSERT( values ) ;
+	if( values )
+	{
+	    str_citer vi = values->begin() ;
+	    str_citer sbi = sb.begin() ;
+	    for( ; vi != values->end() && sbi != sb.end(); vi++, sbi++ )
+	    {
+		CPPUNIT_ASSERT( (*vi) == (*sbi) ) ;
+	    }
+	    CPPUNIT_ASSERT( vi == values->end() && sbi == sb.end() ) ;
+	    if( vi == values->end() && sbi != sb.end() )
+	    {
+		CPPUNIT_FAIL( "not enough values"  ) ;
+	    }
+	    else if( vi != values->end() && sbi == sb.end() )
+	    {
+		CPPUNIT_FAIL( "too many values"  ) ;
+	    }
+	}
+
+
+	{
+	    str_iter sbi = sb.begin() ;
+	    sbi++ ;
+	    sb.erase( sbi ) ;
+	}
+
+	at.del_attr( "attr3", 1 ) ;
+	values = at.get_attr_vector( iter ) ;
+	CPPUNIT_ASSERT( values ) ;
+	if( values )
+	{
+	    str_citer vi = values->begin() ;
+	    str_citer sbi = sb.begin() ;
+	    for( ; vi != values->end() && sbi != sb.end(); vi++, sbi++ )
+	    {
+		CPPUNIT_ASSERT( (*vi) == (*sbi) ) ;
+	    }
+	    CPPUNIT_ASSERT( vi == values->end() && sbi == sb.end() ) ;
+	    if( vi == values->end() && sbi != sb.end() )
+	    {
+		CPPUNIT_FAIL( "not enough values"  ) ;
+	    }
+	    else if( vi != values->end() && sbi == sb.end() )
+	    {
+		CPPUNIT_FAIL( "too many values"  ) ;
+	    }
+	}
+
+	at.del_attr( "attr3" ) ;
+	container = 0 ;
+	try
+	{
+	    container = at.append_container( "attr2" ) ;
+	    CPPUNIT_FAIL( "added container named attr2 successfully - already exists" ) ;
+	}
+	catch( Error &e )
+	{
+	}
+	CPPUNIT_ASSERT( !container ) ;
+
+	try
+	{
+	    container = at.append_container( "attr5" ) ;
+	}
+	catch( Error &e )
+	{
+	    CPPUNIT_FAIL( "failed to add new container attr5" ) ;
+	}
+	CPPUNIT_ASSERT( container ) ;
+	if( container )
+	{
+	    CPPUNIT_ASSERT( container->get_name() == "attr5" ) ;
+	}
+
+	container = at.find_container( "attr5" ) ;
+	CPPUNIT_ASSERT( container ) ;
+	if( container )
+	{
+	    string container_name = container->get_name() ;
+	    CPPUNIT_ASSERT( container_name == "attr5" ) ;
+	}
+
+	iter = at.attr_end() ;
+	at.find( "attr5", &dummy_at, &iter ) ;
+	CPPUNIT_ASSERT( iter != at.attr_end() ) ;
+	attr_name =  at.get_name( iter ) ;
+	CPPUNIT_ASSERT( attr_name == "attr5" ) ;
+	isit = at.is_container( iter ) ;
+	CPPUNIT_ASSERT( isit == true ) ;
+	container = at.get_attr_table( iter ) ;
+	CPPUNIT_ASSERT( container ) ;
+	attr_type = at.get_type( iter ) ;
+	CPPUNIT_ASSERT( attr_type == "Container" ) ;
+	attr_type_enum = at.get_attr_type( iter ) ;
+	CPPUNIT_ASSERT( attr_type_enum == Attr_container ) ;
+
+	/* FIX: does append attr return anything? */
+	container->append_attr( "attr5-1", "string", "attr5.1Value1" ) ;
+	container->append_attr( "attr5-2", "string", "attr5.2Value1" ) ;
+	container->append_attr( "attr5-3", "string", "attr5.3Value1" ) ;
+	container->append_attr( "attr5-4", "string", "attr5.4Value1" ) ;
+	iter = at.attr_end() ;
+	at.find( "attr5.attr5-3", &dummy_at, &iter ) ;
+	CPPUNIT_ASSERT( iter != at.attr_end() ) ;
+	CPPUNIT_ASSERT( container == dummy_at ) ;
+
+	//at.print( stdout ) ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( attrTableT ) ;
+
+/* NOTHING NEEDS TO BE CHANGED BELOW HERE */
+
+int main( int, char ** )
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( 
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/cache-testsuite/Makefile.am b/unit-tests/cache-testsuite/Makefile.am
new file mode 100644
index 0000000..82dd6ed
--- /dev/null
+++ b/unit-tests/cache-testsuite/Makefile.am
@@ -0,0 +1,15 @@
+noinst_SCRIPTS = cleanup.sh
+
+EXTRA_DIST = cleanup.sh.in dodsrc dot.index dods_cache_init
+
+DISTCLEANFILES = cleanup.sh
+
+cleanup.sh: cleanup.sh.in ../../config.status
+	sed -e "s%[@]srcdir[@]%${srcdir}%" $< > cleanup.sh
+	chmod +x cleanup.sh
+
+clean-local: cleanup.sh
+	sh ./cleanup.sh
+
+distclean-local:
+	rm -rf dods_cache
diff --git a/unit-tests/cache-testsuite/Makefile.in b/unit-tests/cache-testsuite/Makefile.in
new file mode 100644
index 0000000..23b36b5
--- /dev/null
+++ b/unit-tests/cache-testsuite/Makefile.in
@@ -0,0 +1,722 @@
+# Makefile.in generated by automake 1.11 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+ at SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+subdir = unit-tests/cache-testsuite
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/gl/m4/00gnulib.m4 \
+	$(top_srcdir)/gl/m4/alloca.m4 $(top_srcdir)/gl/m4/btowc.m4 \
+	$(top_srcdir)/gl/m4/codeset.m4 \
+	$(top_srcdir)/gl/m4/configmake.m4 \
+	$(top_srcdir)/gl/m4/extensions.m4 \
+	$(top_srcdir)/gl/m4/fcntl-o.m4 $(top_srcdir)/gl/m4/glibc21.m4 \
+	$(top_srcdir)/gl/m4/gnulib-common.m4 \
+	$(top_srcdir)/gl/m4/gnulib-comp.m4 \
+	$(top_srcdir)/gl/m4/gnulib-tool.m4 \
+	$(top_srcdir)/gl/m4/include_next.m4 \
+	$(top_srcdir)/gl/m4/langinfo_h.m4 \
+	$(top_srcdir)/gl/m4/localcharset.m4 \
+	$(top_srcdir)/gl/m4/locale-fr.m4 \
+	$(top_srcdir)/gl/m4/locale-ja.m4 \
+	$(top_srcdir)/gl/m4/locale-zh.m4 \
+	$(top_srcdir)/gl/m4/longlong.m4 $(top_srcdir)/gl/m4/malloc.m4 \
+	$(top_srcdir)/gl/m4/mbrtowc.m4 $(top_srcdir)/gl/m4/mbsinit.m4 \
+	$(top_srcdir)/gl/m4/mbstate_t.m4 \
+	$(top_srcdir)/gl/m4/multiarch.m4 \
+	$(top_srcdir)/gl/m4/nl_langinfo.m4 \
+	$(top_srcdir)/gl/m4/regex.m4 $(top_srcdir)/gl/m4/ssize_t.m4 \
+	$(top_srcdir)/gl/m4/stdbool.m4 $(top_srcdir)/gl/m4/stddef_h.m4 \
+	$(top_srcdir)/gl/m4/stdint.m4 $(top_srcdir)/gl/m4/stdlib_h.m4 \
+	$(top_srcdir)/gl/m4/unistd_h.m4 \
+	$(top_srcdir)/gl/m4/warn-on-use.m4 \
+	$(top_srcdir)/gl/m4/wchar_h.m4 $(top_srcdir)/gl/m4/wchar_t.m4 \
+	$(top_srcdir)/gl/m4/wcrtomb.m4 $(top_srcdir)/gl/m4/wctype_h.m4 \
+	$(top_srcdir)/gl/m4/wint_t.m4 $(top_srcdir)/conf/acinclude.m4 \
+	$(top_srcdir)/conf/check_zlib.m4 $(top_srcdir)/conf/cppunit.m4 \
+	$(top_srcdir)/conf/libtool.m4 $(top_srcdir)/conf/ltoptions.m4 \
+	$(top_srcdir)/conf/ltsugar.m4 $(top_srcdir)/conf/ltversion.m4 \
+	$(top_srcdir)/conf/lt~obsolete.m4 $(top_srcdir)/conf/pkg.m4 \
+	$(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+	$(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h \
+	$(top_builddir)/dods-datatypes-config.h \
+	$(top_builddir)/xdr-datatypes-config.h
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SCRIPTS = $(noinst_SCRIPTS)
+SOURCES =
+DIST_SOURCES =
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+pkglibexecdir = @pkglibexecdir@
+ACLOCAL = @ACLOCAL@
+ALLOCA = @ALLOCA@
+ALLOCA_H = @ALLOCA_H@
+AMTAR = @AMTAR@
+APPLE_UNIVERSAL_BUILD = @APPLE_UNIVERSAL_BUILD@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BITSIZEOF_PTRDIFF_T = @BITSIZEOF_PTRDIFF_T@
+BITSIZEOF_SIG_ATOMIC_T = @BITSIZEOF_SIG_ATOMIC_T@
+BITSIZEOF_SIZE_T = @BITSIZEOF_SIZE_T@
+BITSIZEOF_WCHAR_T = @BITSIZEOF_WCHAR_T@
+BITSIZEOF_WINT_T = @BITSIZEOF_WINT_T@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CLIENTLIB_AGE = @CLIENTLIB_AGE@
+CLIENTLIB_CURRENT = @CLIENTLIB_CURRENT@
+CLIENTLIB_REVISION = @CLIENTLIB_REVISION@
+CLIENTLIB_VERSION = @CLIENTLIB_VERSION@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CPPUNIT_CFLAGS = @CPPUNIT_CFLAGS@
+CPPUNIT_CONFIG = @CPPUNIT_CONFIG@
+CPPUNIT_LIBS = @CPPUNIT_LIBS@
+CURL_CFLAGS = @CURL_CFLAGS@
+CURL_LIBS = @CURL_LIBS@
+CURL_STATIC_LIBS = @CURL_STATIC_LIBS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DAPLIB_AGE = @DAPLIB_AGE@
+DAPLIB_CURRENT = @DAPLIB_CURRENT@
+DAPLIB_REVISION = @DAPLIB_REVISION@
+DAP_PROTOCOL_VERSION = @DAP_PROTOCOL_VERSION@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+DVR = @DVR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EVAL = @EVAL@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GLIBC21 = @GLIBC21@
+GNULIB_ATOLL = @GNULIB_ATOLL@
+GNULIB_BTOWC = @GNULIB_BTOWC@
+GNULIB_CALLOC_POSIX = @GNULIB_CALLOC_POSIX@
+GNULIB_CANONICALIZE_FILE_NAME = @GNULIB_CANONICALIZE_FILE_NAME@
+GNULIB_CHOWN = @GNULIB_CHOWN@
+GNULIB_CLOSE = @GNULIB_CLOSE@
+GNULIB_DUP2 = @GNULIB_DUP2@
+GNULIB_DUP3 = @GNULIB_DUP3@
+GNULIB_ENVIRON = @GNULIB_ENVIRON@
+GNULIB_EUIDACCESS = @GNULIB_EUIDACCESS@
+GNULIB_FACCESSAT = @GNULIB_FACCESSAT@
+GNULIB_FCHDIR = @GNULIB_FCHDIR@
+GNULIB_FCHOWNAT = @GNULIB_FCHOWNAT@
+GNULIB_FSYNC = @GNULIB_FSYNC@
+GNULIB_FTRUNCATE = @GNULIB_FTRUNCATE@
+GNULIB_GETCWD = @GNULIB_GETCWD@
+GNULIB_GETDOMAINNAME = @GNULIB_GETDOMAINNAME@
+GNULIB_GETDTABLESIZE = @GNULIB_GETDTABLESIZE@
+GNULIB_GETGROUPS = @GNULIB_GETGROUPS@
+GNULIB_GETHOSTNAME = @GNULIB_GETHOSTNAME@
+GNULIB_GETLOADAVG = @GNULIB_GETLOADAVG@
+GNULIB_GETLOGIN = @GNULIB_GETLOGIN@
+GNULIB_GETLOGIN_R = @GNULIB_GETLOGIN_R@
+GNULIB_GETPAGESIZE = @GNULIB_GETPAGESIZE@
+GNULIB_GETSUBOPT = @GNULIB_GETSUBOPT@
+GNULIB_GETUSERSHELL = @GNULIB_GETUSERSHELL@
+GNULIB_GRANTPT = @GNULIB_GRANTPT@
+GNULIB_LCHOWN = @GNULIB_LCHOWN@
+GNULIB_LINK = @GNULIB_LINK@
+GNULIB_LINKAT = @GNULIB_LINKAT@
+GNULIB_LSEEK = @GNULIB_LSEEK@
+GNULIB_MALLOC_POSIX = @GNULIB_MALLOC_POSIX@
+GNULIB_MBRLEN = @GNULIB_MBRLEN@
+GNULIB_MBRTOWC = @GNULIB_MBRTOWC@
+GNULIB_MBSINIT = @GNULIB_MBSINIT@
+GNULIB_MBSNRTOWCS = @GNULIB_MBSNRTOWCS@
+GNULIB_MBSRTOWCS = @GNULIB_MBSRTOWCS@
+GNULIB_MKDTEMP = @GNULIB_MKDTEMP@
+GNULIB_MKOSTEMP = @GNULIB_MKOSTEMP@
+GNULIB_MKOSTEMPS = @GNULIB_MKOSTEMPS@
+GNULIB_MKSTEMP = @GNULIB_MKSTEMP@
+GNULIB_MKSTEMPS = @GNULIB_MKSTEMPS@
+GNULIB_NL_LANGINFO = @GNULIB_NL_LANGINFO@
+GNULIB_PIPE = @GNULIB_PIPE@
+GNULIB_PIPE2 = @GNULIB_PIPE2@
+GNULIB_PREAD = @GNULIB_PREAD@
+GNULIB_PTSNAME = @GNULIB_PTSNAME@
+GNULIB_PUTENV = @GNULIB_PUTENV@
+GNULIB_PWRITE = @GNULIB_PWRITE@
+GNULIB_RANDOM_R = @GNULIB_RANDOM_R@
+GNULIB_READLINK = @GNULIB_READLINK@
+GNULIB_READLINKAT = @GNULIB_READLINKAT@
+GNULIB_REALLOC_POSIX = @GNULIB_REALLOC_POSIX@
+GNULIB_REALPATH = @GNULIB_REALPATH@
+GNULIB_RMDIR = @GNULIB_RMDIR@
+GNULIB_RPMATCH = @GNULIB_RPMATCH@
+GNULIB_SETENV = @GNULIB_SETENV@
+GNULIB_SLEEP = @GNULIB_SLEEP@
+GNULIB_STRTOD = @GNULIB_STRTOD@
+GNULIB_STRTOLL = @GNULIB_STRTOLL@
+GNULIB_STRTOULL = @GNULIB_STRTOULL@
+GNULIB_SYMLINK = @GNULIB_SYMLINK@
+GNULIB_SYMLINKAT = @GNULIB_SYMLINKAT@
+GNULIB_SYSTEM_POSIX = @GNULIB_SYSTEM_POSIX@
+GNULIB_TTYNAME_R = @GNULIB_TTYNAME_R@
+GNULIB_UNISTD_H_GETOPT = @GNULIB_UNISTD_H_GETOPT@
+GNULIB_UNISTD_H_SIGPIPE = @GNULIB_UNISTD_H_SIGPIPE@
+GNULIB_UNLINK = @GNULIB_UNLINK@
+GNULIB_UNLINKAT = @GNULIB_UNLINKAT@
+GNULIB_UNLOCKPT = @GNULIB_UNLOCKPT@
+GNULIB_UNSETENV = @GNULIB_UNSETENV@
+GNULIB_USLEEP = @GNULIB_USLEEP@
+GNULIB_WCRTOMB = @GNULIB_WCRTOMB@
+GNULIB_WCSNRTOMBS = @GNULIB_WCSNRTOMBS@
+GNULIB_WCSRTOMBS = @GNULIB_WCSRTOMBS@
+GNULIB_WCTOB = @GNULIB_WCTOB@
+GNULIB_WCWIDTH = @GNULIB_WCWIDTH@
+GNULIB_WRITE = @GNULIB_WRITE@
+GNULIB__EXIT = @GNULIB__EXIT@
+GREP = @GREP@
+HAVE_ATOLL = @HAVE_ATOLL@
+HAVE_BTOWC = @HAVE_BTOWC@
+HAVE_CANONICALIZE_FILE_NAME = @HAVE_CANONICALIZE_FILE_NAME@
+HAVE_CHOWN = @HAVE_CHOWN@
+HAVE_DECL_ENVIRON = @HAVE_DECL_ENVIRON@
+HAVE_DECL_FCHDIR = @HAVE_DECL_FCHDIR@
+HAVE_DECL_GETDOMAINNAME = @HAVE_DECL_GETDOMAINNAME@
+HAVE_DECL_GETLOADAVG = @HAVE_DECL_GETLOADAVG@
+HAVE_DECL_GETLOGIN_R = @HAVE_DECL_GETLOGIN_R@
+HAVE_DECL_GETPAGESIZE = @HAVE_DECL_GETPAGESIZE@
+HAVE_DECL_GETUSERSHELL = @HAVE_DECL_GETUSERSHELL@
+HAVE_DECL_SETENV = @HAVE_DECL_SETENV@
+HAVE_DECL_TTYNAME_R = @HAVE_DECL_TTYNAME_R@
+HAVE_DECL_UNSETENV = @HAVE_DECL_UNSETENV@
+HAVE_DECL_WCTOB = @HAVE_DECL_WCTOB@
+HAVE_DECL_WCWIDTH = @HAVE_DECL_WCWIDTH@
+HAVE_DUP2 = @HAVE_DUP2@
+HAVE_DUP3 = @HAVE_DUP3@
+HAVE_EUIDACCESS = @HAVE_EUIDACCESS@
+HAVE_FACCESSAT = @HAVE_FACCESSAT@
+HAVE_FCHDIR = @HAVE_FCHDIR@
+HAVE_FCHOWNAT = @HAVE_FCHOWNAT@
+HAVE_FEATURES_H = @HAVE_FEATURES_H@
+HAVE_FSYNC = @HAVE_FSYNC@
+HAVE_FTRUNCATE = @HAVE_FTRUNCATE@
+HAVE_GETDTABLESIZE = @HAVE_GETDTABLESIZE@
+HAVE_GETGROUPS = @HAVE_GETGROUPS@
+HAVE_GETHOSTNAME = @HAVE_GETHOSTNAME@
+HAVE_GETLOGIN = @HAVE_GETLOGIN@
+HAVE_GETPAGESIZE = @HAVE_GETPAGESIZE@
+HAVE_GETSUBOPT = @HAVE_GETSUBOPT@
+HAVE_GRANTPT = @HAVE_GRANTPT@
+HAVE_INTTYPES_H = @HAVE_INTTYPES_H@
+HAVE_ISWBLANK = @HAVE_ISWBLANK@
+HAVE_ISWCNTRL = @HAVE_ISWCNTRL@
+HAVE_LANGINFO_CODESET = @HAVE_LANGINFO_CODESET@
+HAVE_LANGINFO_ERA = @HAVE_LANGINFO_ERA@
+HAVE_LANGINFO_H = @HAVE_LANGINFO_H@
+HAVE_LANGINFO_T_FMT_AMPM = @HAVE_LANGINFO_T_FMT_AMPM@
+HAVE_LANGINFO_YESEXPR = @HAVE_LANGINFO_YESEXPR@
+HAVE_LCHOWN = @HAVE_LCHOWN@
+HAVE_LINK = @HAVE_LINK@
+HAVE_LINKAT = @HAVE_LINKAT@
+HAVE_LONG_LONG_INT = @HAVE_LONG_LONG_INT@
+HAVE_MBRLEN = @HAVE_MBRLEN@
+HAVE_MBRTOWC = @HAVE_MBRTOWC@
+HAVE_MBSINIT = @HAVE_MBSINIT@
+HAVE_MBSNRTOWCS = @HAVE_MBSNRTOWCS@
+HAVE_MBSRTOWCS = @HAVE_MBSRTOWCS@
+HAVE_MKDTEMP = @HAVE_MKDTEMP@
+HAVE_MKOSTEMP = @HAVE_MKOSTEMP@
+HAVE_MKOSTEMPS = @HAVE_MKOSTEMPS@
+HAVE_MKSTEMP = @HAVE_MKSTEMP@
+HAVE_MKSTEMPS = @HAVE_MKSTEMPS@
+HAVE_NL_LANGINFO = @HAVE_NL_LANGINFO@
+HAVE_OS_H = @HAVE_OS_H@
+HAVE_PIPE = @HAVE_PIPE@
+HAVE_PIPE2 = @HAVE_PIPE2@
+HAVE_PREAD = @HAVE_PREAD@
+HAVE_PTSNAME = @HAVE_PTSNAME@
+HAVE_PWRITE = @HAVE_PWRITE@
+HAVE_RANDOM_H = @HAVE_RANDOM_H@
+HAVE_RANDOM_R = @HAVE_RANDOM_R@
+HAVE_READLINK = @HAVE_READLINK@
+HAVE_READLINKAT = @HAVE_READLINKAT@
+HAVE_REALPATH = @HAVE_REALPATH@
+HAVE_RPMATCH = @HAVE_RPMATCH@
+HAVE_SETENV = @HAVE_SETENV@
+HAVE_SIGNED_SIG_ATOMIC_T = @HAVE_SIGNED_SIG_ATOMIC_T@
+HAVE_SIGNED_WCHAR_T = @HAVE_SIGNED_WCHAR_T@
+HAVE_SIGNED_WINT_T = @HAVE_SIGNED_WINT_T@
+HAVE_SLEEP = @HAVE_SLEEP@
+HAVE_STDINT_H = @HAVE_STDINT_H@
+HAVE_STRTOD = @HAVE_STRTOD@
+HAVE_STRTOLL = @HAVE_STRTOLL@
+HAVE_STRTOULL = @HAVE_STRTOULL@
+HAVE_STRUCT_RANDOM_DATA = @HAVE_STRUCT_RANDOM_DATA@
+HAVE_SYMLINK = @HAVE_SYMLINK@
+HAVE_SYMLINKAT = @HAVE_SYMLINKAT@
+HAVE_SYS_BITYPES_H = @HAVE_SYS_BITYPES_H@
+HAVE_SYS_INTTYPES_H = @HAVE_SYS_INTTYPES_H@
+HAVE_SYS_LOADAVG_H = @HAVE_SYS_LOADAVG_H@
+HAVE_SYS_PARAM_H = @HAVE_SYS_PARAM_H@
+HAVE_SYS_TYPES_H = @HAVE_SYS_TYPES_H@
+HAVE_UNISTD_H = @HAVE_UNISTD_H@
+HAVE_UNLINKAT = @HAVE_UNLINKAT@
+HAVE_UNLOCKPT = @HAVE_UNLOCKPT@
+HAVE_UNSIGNED_LONG_LONG_INT = @HAVE_UNSIGNED_LONG_LONG_INT@
+HAVE_USLEEP = @HAVE_USLEEP@
+HAVE_WCHAR_H = @HAVE_WCHAR_H@
+HAVE_WCHAR_T = @HAVE_WCHAR_T@
+HAVE_WCRTOMB = @HAVE_WCRTOMB@
+HAVE_WCSNRTOMBS = @HAVE_WCSNRTOMBS@
+HAVE_WCSRTOMBS = @HAVE_WCSRTOMBS@
+HAVE_WCTYPE_H = @HAVE_WCTYPE_H@
+HAVE_WINT_T = @HAVE_WINT_T@
+HAVE__BOOL = @HAVE__BOOL@
+HAVE__EXIT = @HAVE__EXIT@
+INCLUDE_NEXT = @INCLUDE_NEXT@
+INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBDAP_VERSION = @LIBDAP_VERSION@
+LIBINTL = @LIBINTL@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LOCALCHARSET_TESTS_ENVIRONMENT = @LOCALCHARSET_TESTS_ENVIRONMENT@
+LOCALE_FR = @LOCALE_FR@
+LOCALE_FR_UTF8 = @LOCALE_FR_UTF8@
+LOCALE_JA = @LOCALE_JA@
+LOCALE_ZH_CN = @LOCALE_ZH_CN@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H = @NEXT_AS_FIRST_DIRECTIVE_LANGINFO_H@
+NEXT_AS_FIRST_DIRECTIVE_STDDEF_H = @NEXT_AS_FIRST_DIRECTIVE_STDDEF_H@
+NEXT_AS_FIRST_DIRECTIVE_STDINT_H = @NEXT_AS_FIRST_DIRECTIVE_STDINT_H@
+NEXT_AS_FIRST_DIRECTIVE_STDLIB_H = @NEXT_AS_FIRST_DIRECTIVE_STDLIB_H@
+NEXT_AS_FIRST_DIRECTIVE_UNISTD_H = @NEXT_AS_FIRST_DIRECTIVE_UNISTD_H@
+NEXT_AS_FIRST_DIRECTIVE_WCHAR_H = @NEXT_AS_FIRST_DIRECTIVE_WCHAR_H@
+NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H = @NEXT_AS_FIRST_DIRECTIVE_WCTYPE_H@
+NEXT_LANGINFO_H = @NEXT_LANGINFO_H@
+NEXT_STDDEF_H = @NEXT_STDDEF_H@
+NEXT_STDINT_H = @NEXT_STDINT_H@
+NEXT_STDLIB_H = @NEXT_STDLIB_H@
+NEXT_UNISTD_H = @NEXT_UNISTD_H@
+NEXT_WCHAR_H = @NEXT_WCHAR_H@
+NEXT_WCTYPE_H = @NEXT_WCTYPE_H@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_MAJOR_VERSION = @PACKAGE_MAJOR_VERSION@
+PACKAGE_MINOR_VERSION = @PACKAGE_MINOR_VERSION@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_SUBMINOR_VERSION = @PACKAGE_SUBMINOR_VERSION@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PKG_CONFIG = @PKG_CONFIG@
+PRAGMA_COLUMNS = @PRAGMA_COLUMNS@
+PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@
+PTHREAD_LIBS = @PTHREAD_LIBS@
+PTRDIFF_T_SUFFIX = @PTRDIFF_T_SUFFIX@
+RANLIB = @RANLIB@
+REPLACE_BTOWC = @REPLACE_BTOWC@
+REPLACE_CALLOC = @REPLACE_CALLOC@
+REPLACE_CANONICALIZE_FILE_NAME = @REPLACE_CANONICALIZE_FILE_NAME@
+REPLACE_CHOWN = @REPLACE_CHOWN@
+REPLACE_CLOSE = @REPLACE_CLOSE@
+REPLACE_DUP = @REPLACE_DUP@
+REPLACE_DUP2 = @REPLACE_DUP2@
+REPLACE_FCHOWNAT = @REPLACE_FCHOWNAT@
+REPLACE_GETCWD = @REPLACE_GETCWD@
+REPLACE_GETDOMAINNAME = @REPLACE_GETDOMAINNAME@
+REPLACE_GETGROUPS = @REPLACE_GETGROUPS@
+REPLACE_GETLOGIN_R = @REPLACE_GETLOGIN_R@
+REPLACE_GETPAGESIZE = @REPLACE_GETPAGESIZE@
+REPLACE_ISWBLANK = @REPLACE_ISWBLANK@
+REPLACE_ISWCNTRL = @REPLACE_ISWCNTRL@
+REPLACE_LCHOWN = @REPLACE_LCHOWN@
+REPLACE_LINK = @REPLACE_LINK@
+REPLACE_LINKAT = @REPLACE_LINKAT@
+REPLACE_LSEEK = @REPLACE_LSEEK@
+REPLACE_MALLOC = @REPLACE_MALLOC@
+REPLACE_MBRLEN = @REPLACE_MBRLEN@
+REPLACE_MBRTOWC = @REPLACE_MBRTOWC@
+REPLACE_MBSINIT = @REPLACE_MBSINIT@
+REPLACE_MBSNRTOWCS = @REPLACE_MBSNRTOWCS@
+REPLACE_MBSRTOWCS = @REPLACE_MBSRTOWCS@
+REPLACE_MBSTATE_T = @REPLACE_MBSTATE_T@
+REPLACE_MKSTEMP = @REPLACE_MKSTEMP@
+REPLACE_NL_LANGINFO = @REPLACE_NL_LANGINFO@
+REPLACE_NULL = @REPLACE_NULL@
+REPLACE_PREAD = @REPLACE_PREAD@
+REPLACE_PUTENV = @REPLACE_PUTENV@
+REPLACE_PWRITE = @REPLACE_PWRITE@
+REPLACE_READLINK = @REPLACE_READLINK@
+REPLACE_REALLOC = @REPLACE_REALLOC@
+REPLACE_REALPATH = @REPLACE_REALPATH@
+REPLACE_RMDIR = @REPLACE_RMDIR@
+REPLACE_SETENV = @REPLACE_SETENV@
+REPLACE_SLEEP = @REPLACE_SLEEP@
+REPLACE_STRTOD = @REPLACE_STRTOD@
+REPLACE_SYMLINK = @REPLACE_SYMLINK@
+REPLACE_TTYNAME_R = @REPLACE_TTYNAME_R@
+REPLACE_UNLINK = @REPLACE_UNLINK@
+REPLACE_UNLINKAT = @REPLACE_UNLINKAT@
+REPLACE_UNSETENV = @REPLACE_UNSETENV@
+REPLACE_USLEEP = @REPLACE_USLEEP@
+REPLACE_WCRTOMB = @REPLACE_WCRTOMB@
+REPLACE_WCSNRTOMBS = @REPLACE_WCSNRTOMBS@
+REPLACE_WCSRTOMBS = @REPLACE_WCSRTOMBS@
+REPLACE_WCTOB = @REPLACE_WCTOB@
+REPLACE_WCWIDTH = @REPLACE_WCWIDTH@
+REPLACE_WRITE = @REPLACE_WRITE@
+SED = @SED@
+SERVERLIB_AGE = @SERVERLIB_AGE@
+SERVERLIB_CURRENT = @SERVERLIB_CURRENT@
+SERVERLIB_REVISION = @SERVERLIB_REVISION@
+SERVERLIB_VERSION = @SERVERLIB_VERSION@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+SIG_ATOMIC_T_SUFFIX = @SIG_ATOMIC_T_SUFFIX@
+SIZE_T_SUFFIX = @SIZE_T_SUFFIX@
+STDBOOL_H = @STDBOOL_H@
+STDDEF_H = @STDDEF_H@
+STDINT_H = @STDINT_H@
+STRIP = @STRIP@
+UNISTD_H_HAVE_WINSOCK2_H = @UNISTD_H_HAVE_WINSOCK2_H@
+UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS = @UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS@
+UUID_LIBS = @UUID_LIBS@
+VERSION = @VERSION@
+WCHAR_T_SUFFIX = @WCHAR_T_SUFFIX@
+WINT_T_SUFFIX = @WINT_T_SUFFIX@
+XML2_CFLAGS = @XML2_CFLAGS@
+XML2_LIBS = @XML2_LIBS@
+XML2_STATIC_LIBS = @XML2_STATIC_LIBS@
+YACC = @YACC@
+ZLIB_CFLAGS = @ZLIB_CFLAGS@
+ZLIB_LDFLAGS = @ZLIB_LDFLAGS@
+ZLIB_LIBS = @ZLIB_LIBS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+curlprivatelibs = @curlprivatelibs@
+curlprivatereq = @curlprivatereq@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+gl_LIBOBJS = @gl_LIBOBJS@
+gl_LTLIBOBJS = @gl_LTLIBOBJS@
+gltests_LIBOBJS = @gltests_LIBOBJS@
+gltests_LTLIBOBJS = @gltests_LTLIBOBJS@
+gltests_WITNESS = @gltests_WITNESS@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+lispdir = @lispdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+xmlprivatelibs = @xmlprivatelibs@
+xmlprivatereq = @xmlprivatereq@
+noinst_SCRIPTS = cleanup.sh
+EXTRA_DIST = cleanup.sh.in dodsrc dot.index dods_cache_init
+DISTCLEANFILES = cleanup.sh
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+	@for dep in $?; do \
+	  case '$(am__configure_deps)' in \
+	    *$$dep*) \
+	      ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+	        && { if test -f $@; then exit 0; else break; fi; }; \
+	      exit 1;; \
+	  esac; \
+	done; \
+	echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu unit-tests/cache-testsuite/Makefile'; \
+	$(am__cd) $(top_srcdir) && \
+	  $(AUTOMAKE) --gnu unit-tests/cache-testsuite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+	@case '$?' in \
+	  *config.status*) \
+	    cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+	  *) \
+	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+	esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure:  $(am__configure_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+	-rm -f *.lo
+
+clean-libtool:
+	-rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+distdir: $(DISTFILES)
+	@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+	list='$(DISTFILES)'; \
+	  dist_files=`for file in $$list; do echo $$file; done | \
+	  sed -e "s|^$$srcdirstrip/||;t" \
+	      -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+	case $$dist_files in \
+	  */*) $(MKDIR_P) `echo "$$dist_files" | \
+			   sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+			   sort -u` ;; \
+	esac; \
+	for file in $$dist_files; do \
+	  if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+	  if test -d $$d/$$file; then \
+	    dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+	    if test -d "$(distdir)/$$file"; then \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+	      cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
+	      find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
+	    fi; \
+	    cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
+	  else \
+	    test -f "$(distdir)/$$file" \
+	    || cp -p $$d/$$file "$(distdir)/$$file" \
+	    || exit 1; \
+	  fi; \
+	done
+check-am: all-am
+check: check-am
+all-am: Makefile $(SCRIPTS)
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+	@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	  `test -z '$(STRIP)' || \
+	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+	-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+	-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+	-test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
+
+maintainer-clean-generic:
+	@echo "This command is intended for maintainers to use"
+	@echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+	-rm -f Makefile
+distclean-am: clean-am distclean-generic distclean-local
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+	-rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+	clean-local distclean distclean-generic distclean-libtool \
+	distclean-local distdir dvi dvi-am html html-am info info-am \
+	install install-am install-data install-data-am install-dvi \
+	install-dvi-am install-exec install-exec-am install-html \
+	install-html-am install-info install-info-am install-man \
+	install-pdf install-pdf-am install-ps install-ps-am \
+	install-strip installcheck installcheck-am installdirs \
+	maintainer-clean maintainer-clean-generic mostlyclean \
+	mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+	uninstall uninstall-am
+
+
+cleanup.sh: cleanup.sh.in ../../config.status
+	sed -e "s%[@]srcdir[@]%${srcdir}%" $< > cleanup.sh
+	chmod +x cleanup.sh
+
+clean-local: cleanup.sh
+	sh ./cleanup.sh
+
+distclean-local:
+	rm -rf dods_cache
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/unit-tests/cache-testsuite/cleanup.sh.in b/unit-tests/cache-testsuite/cleanup.sh.in
new file mode 100755
index 0000000..836872b
--- /dev/null
+++ b/unit-tests/cache-testsuite/cleanup.sh.in
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# remove stuff that accumulates between runs of the HTTPCacheTest unit tests.
+
+# sometimes have trouble deleting dods_cache during distcheck
+if [ -d dods_cache ]
+then
+    chmod -R +w dods_cache
+fi
+rm -rf dods_cache
+
+# initialize the dods_cache directory
+cp -r @srcdir@/dods_cache_init dods_cache
+# make sure we can write to the directory and sub directories
+chmod -R +w dods_cache
+# remove the .svn directory from dods_cache
+rm -rf `find dods_cache -name .svn`
+
+# remove generated cache directories
+rm -rf gc_cache
+rm -rf purge_cache
+rm -rf header_cache
+rm -rf interrupt_cache
+rm -rf singleton_cache
diff --git a/unit-tests/cache-testsuite/dods_cache_init/.index b/unit-tests/cache-testsuite/dods_cache_init/.index
new file mode 100644
index 0000000..dde714a
--- /dev/null
+++ b/unit-tests/cache-testsuite/dods_cache_init/.index
@@ -0,0 +1 @@
+http://test.opendap.org/test-304.html cache-testsuite/dods_cache/656/dodsKbcD0h "3f62c-157-139c2680" 1121283146 -1 343 0 656 1 7351 1121360379 3723 0
diff --git a/unit-tests/cache-testsuite/dods_cache_init/656/dodsKbcD0h b/unit-tests/cache-testsuite/dods_cache_init/656/dodsKbcD0h
new file mode 100644
index 0000000..ef98f45
--- /dev/null
+++ b/unit-tests/cache-testsuite/dods_cache_init/656/dodsKbcD0h
@@ -0,0 +1,20 @@
+<html>
+
+<head>
+<title>Test getting a 304 response</title>
+</head>
+
+<body>
+The purpose of this page is to generate a 304 response when accessed using a
+given date and an If-Modified-Since header and/or the correct etag. 
+
+<b>Please don't modify this file!</b>
+
+<address>
+James Gallagher<br/>
+jgallagher at gso.uri.edu
+</address>
+
+</body>
+
+</html>
diff --git a/unit-tests/cache-testsuite/dods_cache_init/656/dodsKbcD0h.meta b/unit-tests/cache-testsuite/dods_cache_init/656/dodsKbcD0h.meta
new file mode 100644
index 0000000..8a7d5ca
--- /dev/null
+++ b/unit-tests/cache-testsuite/dods_cache_init/656/dodsKbcD0h.meta
@@ -0,0 +1,8 @@
+Date: Wed, 10 Aug 2005 18:38:05 GMT
+Server: Apache/2.0.46 (Red Hat)
+Last-Modified: Wed, 13 Jul 2005 19:32:26 GMT
+ETag: "3f62c-157-139c2680"
+Accept-Ranges: bytes
+Content-Length: 343
+Content-Type: text/html; charset=UTF-8
+
diff --git a/unit-tests/cache-testsuite/dodsrc b/unit-tests/cache-testsuite/dodsrc
new file mode 100644
index 0000000..d686dd6
--- /dev/null
+++ b/unit-tests/cache-testsuite/dodsrc
@@ -0,0 +1,16 @@
+# DODS client configuation file. See the DODS
+# users guide for information.
+#
+# This is a special dodsrc file used by HTTPConnectTest. That code turns on
+# caching after first running tests with it off (that's why USE_CACHE is set
+# ot zero here). 10/17/02 jhrg
+USE_CACHE=0
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=cache-testsuite/http_connect_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# PROXY_SERVER=<protocol>,<host url>
+# PROXY_FOR=<regex>,<proxy host url>,<flags>
+# NO_PROXY_FOR=<protocol>,<host>
diff --git a/unit-tests/cache-testsuite/dot.index b/unit-tests/cache-testsuite/dot.index
new file mode 100644
index 0000000..3cd09ed
--- /dev/null
+++ b/unit-tests/cache-testsuite/dot.index
@@ -0,0 +1,2 @@
+http://new.url.same.hash/test/collisions.gif cache-testsuite/dods_cache/656/dodsKbcD0h "3f62c-157-139c2680" 1121283146 -1 343 0 656 1 7351 1121360379 3723 0
+
diff --git a/unit-tests/ce-functions-testsuite/geo_grid.das b/unit-tests/ce-functions-testsuite/geo_grid.das
new file mode 100644
index 0000000..7edcb1d
--- /dev/null
+++ b/unit-tests/ce-functions-testsuite/geo_grid.das
@@ -0,0 +1,35 @@
+Attributes {
+    SST1 {
+        lon {
+            String units "degrees_east";
+            String long_name "longitude";
+        }
+        lat{
+            String units "degrees_north";
+            String long_name "latitude";
+        }
+    }
+
+    SST2 {
+        lon {
+            String units "degrees_E";
+            String long_name "longitude";
+        }
+        lat{
+            String units "degrees_N";
+            String long_name "latitude";
+        }
+    }
+
+    SST3 {
+        lon {
+            String units "degree_east";
+            String long_name "longitude";
+        }
+        lat{
+            String units "degree_N";
+            String long_name "latitude";
+        }
+    }
+}
+     
\ No newline at end of file
diff --git a/unit-tests/ce-functions-testsuite/geo_grid.dds b/unit-tests/ce-functions-testsuite/geo_grid.dds
new file mode 100644
index 0000000..6b1a50d
--- /dev/null
+++ b/unit-tests/ce-functions-testsuite/geo_grid.dds
@@ -0,0 +1,38 @@
+Dataset {
+    # SST1 will have a lon map that uses 0/360 notation
+    Grid {
+      Array:
+        Byte SST[lon=10][lat=10];
+      Maps:
+        Float64 lon[10];
+        Float64 lat[10];
+    } SST1;
+    
+    # SST1_1 will have a lon map that uses 0/360 notation; this has lon as its 
+    # rightmost dimension so it can be used with a CE that requires 'stitching'
+    Grid {
+      Array:
+        Byte SST[lat=10][lon=10];
+      Maps:
+        Float64 lat[10];
+        Float64 lon[10];
+    } SST1_1;
+    
+    # SST2 will have a lon map that uses -180/180 notation
+    Grid {
+      Array:
+        Byte SST[lon=10][lat=10];
+      Maps:
+        Float64 lon[10];
+        Float64 lat[10];
+    } SST2;
+    
+    # SST3 will have a lon map that uses 0/360 notation and runs from 20 to 379
+    Grid {
+      Array:
+        Byte SST[lat=10][lon=10];
+      Maps:
+        Float64 lat[10];
+        Float64 lon[10];
+    } SST3;
+} geo_grid;
diff --git a/unit-tests/ce-functions-testsuite/geo_grid_3d.dds b/unit-tests/ce-functions-testsuite/geo_grid_3d.dds
new file mode 100644
index 0000000..fbb3be5
--- /dev/null
+++ b/unit-tests/ce-functions-testsuite/geo_grid_3d.dds
@@ -0,0 +1,11 @@
+Dataset {
+    # SST4 will be a three dimensional Grid
+    Grid {
+      Array:
+        Byte SST4[time=3][lon=5][lat=5];
+      Maps:
+        Int32 time[3];
+        Float64 lon[5];
+        Float64 lat[5];
+    } SST4;
+} geo_grid_3d;
diff --git a/unit-tests/ce-functions-testsuite/geo_grid_coads_lon.dds b/unit-tests/ce-functions-testsuite/geo_grid_coads_lon.dds
new file mode 100644
index 0000000..765115f
--- /dev/null
+++ b/unit-tests/ce-functions-testsuite/geo_grid_coads_lon.dds
@@ -0,0 +1,10 @@
+Dataset {
+    # SST4 will be a three dimensional Grid
+    Grid {
+      Array:
+        Byte SST5[lon=15][lat=5];
+      Maps:
+        Float64 lon[15];
+        Float64 lat[5];
+    } SST5;
+} geo_grid_coads_lon;
diff --git a/unit-tests/ce-functions-testsuite/two_grid.das b/unit-tests/ce-functions-testsuite/two_grid.das
new file mode 100644
index 0000000..923726d
--- /dev/null
+++ b/unit-tests/ce-functions-testsuite/two_grid.das
@@ -0,0 +1,8 @@
+Attributes {
+    a {
+    	a {
+    	    string scale_factor 0.1;
+    	    string add_offset 10;
+    	}
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/ce-functions-testsuite/two_grid.dds b/unit-tests/ce-functions-testsuite/two_grid.dds
new file mode 100644
index 0000000..cbe6d79
--- /dev/null
+++ b/unit-tests/ce-functions-testsuite/two_grid.dds
@@ -0,0 +1,28 @@
+Dataset {
+    Grid {
+      Array:
+        Byte a[first=10];
+      Maps:
+        Float64 first[10];
+    } a;
+    
+    # Use this grid to look at Maps with values that go from big to small,
+    # which should not be an issue, but...
+    Grid {
+      Array:
+        Byte b[first=10];
+      Maps:
+        Float64 first[10];
+    } b;
+    
+    Grid {
+      Array:
+        Byte val[lon=14][lat=14];
+      Maps:
+        Float32 lon[14];
+        Float32 lat[14];
+    } values;
+    
+    Float32 lat[14];
+    Float32 lon[14];
+} two_grids;
diff --git a/unit-tests/cgi-util-tests/01group.hdf b/unit-tests/cgi-util-tests/01group.hdf
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/cgi-util-tests/02group.hdf b/unit-tests/cgi-util-tests/02group.hdf
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/cgi-util-tests/03group.hdf b/unit-tests/cgi-util-tests/03group.hdf
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/cgi-util-tests/group.htm b/unit-tests/cgi-util-tests/group.htm
new file mode 100644
index 0000000..f2e4113
--- /dev/null
+++ b/unit-tests/cgi-util-tests/group.htm
@@ -0,0 +1 @@
+stuff
diff --git a/unit-tests/cgi-util-tests/group01.hdf b/unit-tests/cgi-util-tests/group01.hdf
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/cgi-util-tests/multipart_mime_header1.txt b/unit-tests/cgi-util-tests/multipart_mime_header1.txt
new file mode 100644
index 0000000..20141a3
--- /dev/null
+++ b/unit-tests/cgi-util-tests/multipart_mime_header1.txt
@@ -0,0 +1,6 @@
+--my_boundary
+Content-Type: Text/xml; charset=iso-8859-1
+Content-Description: dap4-ddx
+Content-Id: <1234 at opendap.org>
+
+<?xml version="1.0">
diff --git a/unit-tests/das-testsuite/bad_value_test.1 b/unit-tests/das-testsuite/bad_value_test.1
new file mode 100644
index 0000000..a2de533
--- /dev/null
+++ b/unit-tests/das-testsuite/bad_value_test.1
@@ -0,0 +1,12 @@
+Attributes {
+    bad_values {
+	Byte x 257;
+	Int16 y 60000;
+	UInt16 z 70000;
+	Int32 a 2147483648;
+	UInt32 b 4294967296;
+
+	Float32 c 3.5E+38;
+	Float64 d 1.8E+308;
+    }
+}
diff --git a/unit-tests/das-testsuite/config/unix.exp b/unit-tests/das-testsuite/config/unix.exp
new file mode 100644
index 0000000..5087030
--- /dev/null
+++ b/unit-tests/das-testsuite/config/unix.exp
@@ -0,0 +1,54 @@
+
+# Tcl/Expect code for the DAS test.
+
+# Make sure the global var DASTEST is set correctly.
+
+global DASTEST
+if ![info exists DASTEST] then {
+    set DASTEST [transform ./das-test]
+}
+
+# The four `required' procs are _start, _load, _exit and _version.
+
+proc das-test_start { sw {ifile ""} {ofile ""}} {
+    global verbose
+    global DASTEST
+    global comp_output
+    global spawn_id
+
+    if {$verbose >= 1} {
+	send_user "Testing $ifile $ofile ...\n"
+	exp_internal 1
+    }
+
+    if {$ifile != ""} {
+	set ifile "< $ifile"
+    }
+
+    if {$ofile != ""} {
+	set ofile "> $ofile"
+    }
+
+    switch $sw {
+	p {catch "exec $DASTEST -p $ifile $ofile" comp_output}
+	s {eval "spawn $DASTEST -s"}
+    }
+
+    if {$verbose >= 1} {
+	switch $sw {
+	    p {send_user "Comp output:\n$comp_output\n"}
+	    s {send_user "Program running: spawn_id=$spawn_id\n"}
+	}
+    }
+}
+
+proc das-test_load {} {
+}
+
+proc das-test_exit {} {
+    send -raw ""
+}
+
+proc das-test_version {} {
+    send_user "DAS test suite 1.2\n"
+}
diff --git a/unit-tests/das-testsuite/das b/unit-tests/das-testsuite/das
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.1.exp b/unit-tests/das-testsuite/das-test.0/scanner.1.exp
new file mode 100644
index 0000000..f952a50
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.1.exp
@@ -0,0 +1,47 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.1.exp,v $
+# Revision 1.1  1996/07/16 16:54:31  jimg
+# Added.
+#
+# Revision 1.3  1996/05/14 15:40:41  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.2  1995/10/23  23:47:02  jimg
+# Modified...
+#
+# Revision 1.1  1995/02/16  15:34:43  jimg
+# Added these tests. See comments in files in parent directory.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name scanner.1
+
+set prompt "das-test:"
+set timeout 2
+
+das-test_start s
+
+expect {
+    -re "^$prompt $" { 
+	pass "$test_name" 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	fail "$test_name" 
+    }
+}
+
+das-test_exit
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.2.exp b/unit-tests/das-testsuite/das-test.0/scanner.2.exp
new file mode 100644
index 0000000..22b46ac
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.2.exp
@@ -0,0 +1,163 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.2.exp,v $
+# Revision 1.3  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.2.54.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.2  1997/05/05 20:29:22  jimg
+# *** empty log message ***
+#
+# Revision 1.1  1996/07/16 16:54:33  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.2
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "a\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "averylongidentifierthatishardtoread\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "a_very_long_identifier_that_is_not_hard_to_read\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "One_That_HASCAPITALS\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "One_That_has_1234567890\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "z1234567890\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+# Some things that are *not* identifiers! These should scan as strings.
+# But now (5/5/97) people have convinced me to let these through! Arrgh...
+# jhrg.
+
+if {$pass} {
+    set thing "a0.9\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.3.exp b/unit-tests/das-testsuite/das-test.0/scanner.3.exp
new file mode 100644
index 0000000..d80064c
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.3.exp
@@ -0,0 +1,82 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.3.exp,v $
+# Revision 1.1  1996/07/16 16:54:34  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.3
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "attributes\r\n"
+    send $thing
+
+    expect {
+	-re ".*ATTR\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "Attributes\r\n"
+    send $thing
+
+    expect {
+	-re ".*ATTR\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "ATTRIBUTES\r\n"
+    send $thing
+
+    expect {
+	-re ".*ATTR\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.4.exp b/unit-tests/das-testsuite/das-test.0/scanner.4.exp
new file mode 100644
index 0000000..aa15c64
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.4.exp
@@ -0,0 +1,119 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.4.exp,v $
+# Revision 1.3  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.2.54.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.2  1997/05/05 20:29:11  jimg
+# *** empty log message ***
+#
+# Revision 1.1  1996/07/16 16:54:35  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.4
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "\"Attributes\"\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+# Check that all the special characters pass through the scanner. *DON'T*
+# mess with the strings THING and THING2! In THING2 all the special chars are
+# prefixed by `\\' except `[' which is prefixed by `\\\'; the first two `\'s'
+# yeild a single `\', the third `\' escapes the `['. NB: the `[' in THING is
+# also escaped. The left bracket is special in Tcl even in a string
+
+if {$pass} {
+    set thing "\"This is a long nasty string that has some special characters\
+    embedded:!@#$%^&*()_+|~-=`,./;'\[]{}:<>?\"\r\n"
+
+    set thing2 "\"This is a long nasty string that has some special characters\
+    embedded:!@#\\$\\%\\^\\&\\*\\(\\)\\_\\+\\|\\~\\-\\=\\`\\,\\.\\/\\;\\'\\\[\\]\\{\\}\\:\\<\\>\\?\"\r\n"
+
+
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+# Strange case where unquoted sequence of characters `falls through' the
+# scanner cases for WORD, Float and int and winds up a string. Maybe we should
+# not allow this to happen? 7/15/96
+
+if {$pass} {
+    set thing "a_0.9\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.5.exp b/unit-tests/das-testsuite/das-test.0/scanner.5.exp
new file mode 100644
index 0000000..1f54b93
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.5.exp
@@ -0,0 +1,80 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.5.exp,v $
+# Revision 1.1  1996/07/16 16:54:36  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.5
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "byte\r\n"
+    send $thing
+
+    expect {
+	-re ".*BYTE\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "Byte\r\n"
+    send $thing
+
+    expect {
+	-re ".*BYTE\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "BYTE\r\n"
+    send $thing
+
+    expect {
+	-re ".*BYTE\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.6.exp b/unit-tests/das-testsuite/das-test.0/scanner.6.exp
new file mode 100644
index 0000000..f19540a
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.6.exp
@@ -0,0 +1,80 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.6.exp,v $
+# Revision 1.1  1996/07/16 16:54:37  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.6
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "int32\r\n"
+    send $thing
+
+    expect {
+	-re ".*INT32\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "Int32\r\n"
+    send $thing
+
+    expect {
+	-re ".*INT32\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "INT32\r\n"
+    send $thing
+
+    expect {
+	-re ".*INT32\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.7.exp b/unit-tests/das-testsuite/das-test.0/scanner.7.exp
new file mode 100644
index 0000000..e13cea8
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.7.exp
@@ -0,0 +1,80 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.7.exp,v $
+# Revision 1.1  1996/07/16 16:54:38  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.7
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "float64\r\n"
+    send $thing
+
+    expect {
+	-re ".*FLOAT64\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "Float64\r\n"
+    send $thing
+
+    expect {
+	-re ".*FLOAT64\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "FLOAT64\r\n"
+    send $thing
+
+    expect {
+	-re ".*FLOAT64\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.8.exp b/unit-tests/das-testsuite/das-test.0/scanner.8.exp
new file mode 100644
index 0000000..5643f3b
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.8.exp
@@ -0,0 +1,80 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.8.exp,v $
+# Revision 1.1  1996/07/16 16:54:39  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.8
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "string\r\n"
+    send $thing
+
+    expect {
+	-re ".*STRING\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "String\r\n"
+    send $thing
+
+    expect {
+	-re ".*STRING\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "STRING\r\n"
+    send $thing
+
+    expect {
+	-re ".*STRING\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.9.exp b/unit-tests/das-testsuite/das-test.0/scanner.9.exp
new file mode 100644
index 0000000..2b6a16f
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.9.exp
@@ -0,0 +1,80 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.9.exp,v $
+# Revision 1.1  1996/07/16 16:54:40  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.9
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "url\r\n"
+    send $thing
+
+    expect {
+	-re ".*URL\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "Url\r\n"
+    send $thing
+
+    expect {
+	-re ".*URL\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "URL\r\n"
+    send $thing
+
+    expect {
+	-re ".*URL\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.a.exp b/unit-tests/das-testsuite/das-test.0/scanner.a.exp
new file mode 100644
index 0000000..532fa18
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.a.exp
@@ -0,0 +1,94 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.a.exp,v $
+# Revision 1.1  1996/07/16 16:54:41  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.a
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "\{\r\n"
+    send $thing
+
+    expect {
+	-re ".*Left Brace\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "\}\r\n"
+    send $thing
+
+    expect {
+	-re ".*Right Brace\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing ";\r\n"
+    send $thing
+
+    expect {
+	-re ".*Semicolon\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing ",\r\n"
+    send $thing
+
+    expect {
+	-re ".*Comma\r\n${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.b.exp b/unit-tests/das-testsuite/das-test.0/scanner.b.exp
new file mode 100644
index 0000000..9460a48
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.b.exp
@@ -0,0 +1,199 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.b.exp,v $
+# Revision 1.2  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.1.54.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.1  1996/07/16 16:54:42  jimg
+# Added.
+#
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.b
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "0\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "01\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "0123456789\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "0123456789123456789123456789\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+999\r\n"
+    set thing2 "\\+999\r\n" 
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-999\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+256\r\n"
+    set thing2 "\\+256\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-256\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+255\r\n"
+    set thing2 "\\+255\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-255\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/scanner.c.exp b/unit-tests/das-testsuite/das-test.0/scanner.c.exp
new file mode 100644
index 0000000..ed54a8d
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/scanner.c.exp
@@ -0,0 +1,206 @@
+
+# expect/tcl code to test the das scanner
+# jhrg
+#
+# $Log: scanner.c.exp,v $
+# Revision 1.2  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.1.54.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.1  1996/07/16 16:54:43  jimg
+# Added.
+#
+#
+
+# Some of the float values are not legal but the parser will (should) report
+# those errors.
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+set test_name scanner.c
+
+set prompt "das-test:"
+set timeout 2
+set pass 1
+
+das-test_start s
+
+expect {
+    "${prompt} " { 
+    }
+    timeout { 
+	send_user "Timeout\n"
+	set pass 0
+    }
+}
+
+if {$pass} {
+    set thing "0.0\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing ".1\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+1.0\r\n"
+    set thing2 "\\+1.0\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+1.0e9\r\n"
+    set thing2 "\\+1.0e9\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+1.0e+9\r\n"
+    set thing2 "\\+1.0e\\+9\r\n"
+    send $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-1.0e+9\r\n"
+    set thing2 "-1.0e\\+9\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-1.0e+99\r\n"
+    set thing2 "-1.0e\\+99\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-256.256e-99\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "+255.999e-9999999\r\n"
+    set thing2 "\\+255.999e-9999999\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    set thing "-255.999e+9999999\r\n"
+    set thing2 "-255.999e\\+9999999\r\n"
+    send -- $thing
+
+    expect {
+	-re ".*WORD=${thing2}${prompt} $" { 
+	}
+	timeout { 
+	    send_user "Timeout\n"
+	    set pass 0
+	}
+    }
+}
+
+if {$pass} {
+    pass $test_name
+} else {
+    fail $test_name
+}
+
+das-test_exit
diff --git a/unit-tests/das-testsuite/das-test.0/test.1.exp b/unit-tests/das-testsuite/das-test.0/test.1.exp
new file mode 100644
index 0000000..3127baa
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.1.exp
@@ -0,0 +1,87 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.1.exp,v $
+# Revision 1.9  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.8.38.1  2000/06/15 02:24:56  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.8  1997/05/13 23:29:10  jimg
+# *** empty log message ***
+#
+# Revision 1.7  1996/05/14 15:40:40  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.6  1995/02/10  03:31:11  jimg
+# Modified test cases for type checking.
+#
+# Revision 1.5  1994/12/09  21:45:45  jimg
+# Modified for new unix.exp.
+#
+# Revision 1.4  1994/10/05  16:51:45  jimg
+# Added TYPE to each of the DAS test files.
+# The `expect' files correcly check for that in the output.
+#
+# Revision 1.3  1994/09/27  23:14:13  jimg
+# Changed expected outcomes to match new das.print() mfunc.
+#
+# Revision 1.2  1994/09/09  16:15:20  jimg
+# Fixed namign of the test (was given as $srcdir/$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:19  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.1
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        String name bob;
+        String type human;
+        Int32 age 19;
+    }
+    var2 {
+        String name joe;
+        String type dog;
+        Int32 age 8;
+    }
+    var3 {
+        Int32 size 8;
+        String color red;
+        String type art;
+    }
+    var4 {
+    }
+    var5 {
+        String height 5.0in.;
+        String units inches;
+        Float64 max 5.0;
+        String weight 100lbs;
+        String color red;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/test.11.exp b/unit-tests/das-testsuite/das-test.0/test.11.exp
new file mode 100644
index 0000000..2985717
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.11.exp
@@ -0,0 +1,59 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.11.exp,v $
+# Revision 1.7  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.6.22.1  2000/06/15 02:24:56  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.6  1998/08/13 22:10:13  jimg
+# Bytes now are unsigned (0..255). Fixed this test to check that.
+#
+# Revision 1.5  1997/08/25 18:39:48  jimg
+# Removed errant double semicolon at the end of the Url attribute - replaced
+# it with a single semicolon.
+#
+# Revision 1.4  1997/05/13 23:29:11  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:12  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:12  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:45  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.11
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        String names this, is, a, vector, of, strings;
+        Byte b 1, 0, 127, 255;
+        Int32 int_vec 1, 2, 2147483647;
+        Float64 float_vec 1.0, -1.0, +1.0, 0.2, -0.2, +0.2, .3, -.3, +.3, -3.1415, -3.1415e-99, -3.1415e+99, +3.1415e-99, -3., +2., 4.;
+        Url where http://bozo.place.com/home.html;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.12.exp b/unit-tests/das-testsuite/das-test.0/test.12.exp
new file mode 100644
index 0000000..b5c78c6
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.12.exp
@@ -0,0 +1,85 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.12.exp,v $
+# Revision 1.10  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.9.4.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.9  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.8  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.7.10.1  2000/06/15 02:24:56  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.7  1999/03/24 23:42:22  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.6  1997/05/13 23:29:12  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:53  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:40  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:14  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/05/14 15:40:42  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:47  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.12
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        var1_dods_errors {
+            Float64 f1 3.0.0;
+            String f1_explanation \"`3.0.0' is not a Float64 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.13.exp b/unit-tests/das-testsuite/das-test.0/test.13.exp
new file mode 100644
index 0000000..25ce364
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.13.exp
@@ -0,0 +1,85 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.13.exp,v $
+# Revision 1.10  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.9.4.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.9  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.8  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.7.10.1  2000/06/15 02:24:56  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.7  1999/03/24 23:42:22  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.6  1997/05/13 23:29:13  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:54  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:41  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:15  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/05/14 15:40:44  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:48  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.13
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        var1_dods_errors {
+            Float64 f1 -3..0;
+            String f1_explanation \"`-3..0' is not a Float64 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.14.exp b/unit-tests/das-testsuite/das-test.0/test.14.exp
new file mode 100644
index 0000000..fb6dd09
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.14.exp
@@ -0,0 +1,47 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.14.exp,v $
+# Revision 1.4  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.3.38.1  2000/06/15 02:24:56  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.3  1997/05/13 23:29:15  jimg
+# *** empty log message ***
+#
+# Revision 1.2  1996/05/14 15:40:45  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:49  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.14
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Float64 f1 3;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.15.exp b/unit-tests/das-testsuite/das-test.0/test.15.exp
new file mode 100644
index 0000000..c78ced3
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.15.exp
@@ -0,0 +1,85 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.15.exp,v $
+# Revision 1.10  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.9.4.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.9  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.8  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.7.10.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.7  1999/03/24 23:42:22  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.6  1997/05/13 23:29:16  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:55  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:42  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:16  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/05/14 15:40:46  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:50  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.15
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        var1_dods_errors {
+            Int32 i1 3.0;
+            String i1_explanation \"`3.0' is not an Int32 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.16.exp b/unit-tests/das-testsuite/das-test.0/test.16.exp
new file mode 100644
index 0000000..605a1bb
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.16.exp
@@ -0,0 +1,71 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.16.exp,v $
+# Revision 1.9  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.8.6.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.8  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.7.4.1  2000/11/30 05:20:19  jimg
+# Added
+#
+# Revision 1.7  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.6  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.5.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.5  1997/05/13 23:29:17  jimg
+# *** empty log message ***
+#
+# Revision 1.4  1997/03/27 18:19:57  jimg
+# Update for version 2.13
+#
+# Revision 1.3  1996/08/12 22:22:17  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/05/14 15:40:47  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:51  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.16
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error parsing the text on line 7
+An attribute called `i' already exists but is of a different type
+"
+
+das-test_start p $srcdir/$test_name
+
+if {$test_out == $comp_output} { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.17.exp b/unit-tests/das-testsuite/das-test.0/test.17.exp
new file mode 100644
index 0000000..da49dc5
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.17.exp
@@ -0,0 +1,90 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.17.exp,v $
+# Revision 1.10  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.9.4.1  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.9  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.8  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.7.10.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.7  1999/03/24 23:42:22  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.6  1997/05/13 23:29:18  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:58  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:44  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:18  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:13  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:52  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.17
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        test_dods_errors {
+            Byte b \"this is not a byte\";
+            String b_explanation \"`\"this is not a byte\"' is not a Byte value.\";
+            Byte c -256;
+            String c_explanation \"`-256' is not a Byte value.\";
+            Byte e 2550;
+            String e_explanation \"`2550' is not a Byte value.\";
+            Byte f 2.55;
+            String f_explanation \"`2.55' is not a Byte value.\";
+        }
+        Byte d 255;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.18.exp b/unit-tests/das-testsuite/das-test.0/test.18.exp
new file mode 100644
index 0000000..d291ce7
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.18.exp
@@ -0,0 +1,58 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.18.exp,v $
+# Revision 1.2  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.1.6.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.1  1999/04/29 00:05:38  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1997/05/13 23:29:18  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:58  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:44  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:18  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:13  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:52  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.18
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        Float32 f 2.55;
+        Int16 x 6535;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.19.exp b/unit-tests/das-testsuite/das-test.0/test.19.exp
new file mode 100644
index 0000000..0b0f082
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.19.exp
@@ -0,0 +1,83 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.19.exp,v $
+# Revision 1.5  2001/06/15 23:49:05  jimg
+# Merged with release-3-2-4.
+#
+# Revision 1.3.4.3  2001/06/06 06:40:57  jimg
+# *** empty log message ***
+#
+# Revision 1.3.4.2  2001/06/06 04:12:30  jimg
+# Updated for the new DAS error reporting scheme (Some errors are reported
+# in the DAS itself).
+#
+# Revision 1.4  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.3.4.1  2000/11/30 05:20:19  jimg
+# Added
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.1.6.2  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  2000/03/31 21:07:04  jimg
+# Merged with release-3-1-5
+#
+# Revision 1.1.6.1  2000/03/31 20:03:26  jimg
+# Updated tests for new DAS requirements
+#
+# Revision 1.1  1999/04/29 00:05:39  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1997/05/13 23:29:18  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:58  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:44  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:18  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:13  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:52  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.19
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        Float64 f 2.55E-300;
+        test_dods_errors {
+            Float32 g 2.55E-300;
+            String g_explanation \"`2.55E-300' is not a Float32 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.2.exp b/unit-tests/das-testsuite/das-test.0/test.2.exp
new file mode 100644
index 0000000..c375443
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.2.exp
@@ -0,0 +1,64 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.2.exp,v $
+# Revision 1.8  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.7.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.7  1997/05/13 23:29:20  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1996/05/14 15:40:48  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.5  1994/12/09  21:45:46  jimg
+# Modified for new unix.exp.
+#
+# Revision 1.4  1994/10/05  16:51:47  jimg
+# Added TYPE to each of the DAS test files.
+# The `expect' files correcly check for that in the output.
+#
+# Revision 1.3  1994/09/27  23:14:14  jimg
+# Changed expected outcomes to match new das.print() mfunc.
+#
+# Revision 1.2  1994/09/09  16:15:21  jimg
+# Fixed namign of the test (was given as $srcdir//$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:20  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.2
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    a {
+        String b c;
+        String d 4;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/test.20.exp b/unit-tests/das-testsuite/das-test.0/test.20.exp
new file mode 100644
index 0000000..695e160
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.20.exp
@@ -0,0 +1,82 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.20.exp,v $
+# Revision 1.8  2001/06/15 23:49:05  jimg
+# Merged with release-3-2-4.
+#
+# Revision 1.7.4.2  2001/06/06 06:40:57  jimg
+# *** empty log message ***
+#
+# Revision 1.7.4.1  2001/06/06 04:12:30  jimg
+# Updated for the new DAS error reporting scheme (Some errors are reported
+# in the DAS itself).
+#
+# Revision 1.7  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.6  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.4.6.2  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.5  2000/04/07 00:20:36  jimg
+# Fixed expresion tests.
+#
+# Revision 1.4.6.1  1999/10/19 16:48:40  jimg
+# Version 3.1.2
+#
+# Revision 1.4  1999/04/29 00:05:39  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1997/05/13 23:29:18  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:58  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:44  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:18  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:13  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:52  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.20
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        Int32 x 70000;
+        test_dods_errors {
+            Int16 y 80000;
+            String y_explanation \"`80000' is not an Int16 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.21.exp b/unit-tests/das-testsuite/das-test.0/test.21.exp
new file mode 100644
index 0000000..2bb252f
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.21.exp
@@ -0,0 +1,79 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.21.exp,v $
+# Revision 1.5  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.3.4.2  2002/02/20 19:11:34  jimg
+# Fixed some tests
+#
+# Revision 1.4  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.3.4.1  2000/11/30 05:20:19  jimg
+# Added
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.1.6.2  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  2000/03/31 21:07:04  jimg
+# Merged with release-3-1-5
+#
+# Revision 1.1.6.1  2000/03/31 20:03:26  jimg
+# Updated tests for new DAS requirements
+#
+# Revision 1.1  1999/04/29 00:05:39  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1997/05/13 23:29:18  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:58  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:44  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:18  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:13  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:52  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.21
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        Float64 f 2.55E300;
+        test_dods_errors {
+            Float32 g 2.55E300;
+            String g_explanation \"`2.55E300' is not a Float32 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    xfail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.22.exp b/unit-tests/das-testsuite/das-test.0/test.22.exp
new file mode 100644
index 0000000..25b820e
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.22.exp
@@ -0,0 +1,82 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.22.exp,v $
+# Revision 1.5  2001/06/15 23:49:05  jimg
+# Merged with release-3-2-4.
+#
+# Revision 1.3.4.3  2001/06/06 06:40:57  jimg
+# *** empty log message ***
+#
+# Revision 1.3.4.2  2001/06/06 04:12:30  jimg
+# Updated for the new DAS error reporting scheme (Some errors are reported
+# in the DAS itself).
+#
+# Revision 1.4  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.3.4.1  2000/11/30 05:20:19  jimg
+# Added
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.1.6.2  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  2000/03/31 21:07:04  jimg
+# Merged with release-3-1-5
+#
+# Revision 1.1.6.1  2000/03/31 20:03:26  jimg
+# Updated tests for new DAS requirements
+#
+# Revision 1.1  1999/04/29 00:05:39  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1997/05/13 23:29:18  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:19:58  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:44  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:18  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/04/05 22:00:13  jimg
+# Misc Changes for release 2.0.1 of the core software - for developers.
+#
+# Revision 1.1  1995/02/16  15:34:52  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.22
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    test {
+        test_dods_errors {
+            Float64 f 2.55E400;
+            String f_explanation \"`2.55E400' is not a Float64 value.\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.23.exp b/unit-tests/das-testsuite/das-test.0/test.23.exp
new file mode 100644
index 0000000..be4b13c
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.23.exp
@@ -0,0 +1,39 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.23.exp,v $
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:19  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.23
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+    }
+    Alias var2 var1;
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.24.exp b/unit-tests/das-testsuite/das-test.0/test.24.exp
new file mode 100644
index 0000000..094a735
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.24.exp
@@ -0,0 +1,44 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.24.exp,v $
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:19  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.24
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name \"A part of the whole\";
+        }
+    }
+    Alias component2 component1;
+}"
+
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.25.exp b/unit-tests/das-testsuite/das-test.0/test.25.exp
new file mode 100644
index 0000000..8456fed
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.25.exp
@@ -0,0 +1,45 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.25.exp,v $
+# Revision 1.3  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.2.6.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.25
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error parsing the text on line 16
+A value cannot be aliased to the top level of the DAS;
+Only containers may be present at that level of the DAS.
+"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.26.exp b/unit-tests/das-testsuite/das-test.0/test.26.exp
new file mode 100644
index 0000000..4e21876
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.26.exp
@@ -0,0 +1,43 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.26.exp,v $
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.26
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        Alias z x;
+        component1 {
+            Float64 g 6.02e23;
+            String name \"A part of the whole\";
+        }
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.27.exp b/unit-tests/das-testsuite/das-test.0/test.27.exp
new file mode 100644
index 0000000..a027691
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.27.exp
@@ -0,0 +1,43 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.27.exp,v $
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.27
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name \"A part of the whole\";
+        }
+        Alias new_name component1;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.28.exp b/unit-tests/das-testsuite/das-test.0/test.28.exp
new file mode 100644
index 0000000..f413c11
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.28.exp
@@ -0,0 +1,44 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.28.exp,v $
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.28
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name \"A part of the whole\";
+        }
+        Alias z component1.g;
+    }
+}"
+
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.29.exp b/unit-tests/das-testsuite/das-test.0/test.29.exp
new file mode 100644
index 0000000..76e084d
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.29.exp
@@ -0,0 +1,44 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.29.exp,v $
+# Revision 1.3  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.2.6.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.29
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error parsing the text on line 15
+Could not find the attribute `var1.comp' in the attribute object.
+"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.3.exp b/unit-tests/das-testsuite/das-test.0/test.3.exp
new file mode 100644
index 0000000..7ca342a
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.3.exp
@@ -0,0 +1,76 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.3.exp,v $
+# Revision 1.9  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.8.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.8  1997/05/13 23:29:24  jimg
+# *** empty log message ***
+#
+# Revision 1.7  1996/05/14 15:40:50  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.6  1995/02/10  03:31:14  jimg
+# Modified test cases for type checking.
+#
+# Revision 1.5  1994/12/09  21:45:47  jimg
+# Modified for new unix.exp.
+#
+# Revision 1.4  1994/10/05  16:51:49  jimg
+# Added TYPE to each of the DAS test files.
+# The `expect' files correcly check for that in the output.
+#
+# Revision 1.3  1994/09/27  23:14:15  jimg
+# Changed expected outcomes to match new das.print() mfunc.
+#
+# Revision 1.2  1994/09/09  16:15:22  jimg
+# Fixed namign of the test (was given as $srcdir//$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:21  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.3
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        String comment \"One thing about these long comments is that they
+might cause problems with memory - overwrites, ...\";
+        String comment2 \"This quote tests a \\\"quote within a quote\\\", he said\";
+        String quote1 \"\\\"\";
+        String quote2 \"\\7 seven\";
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+# send_user "comp output: $comp_output\n"
+# send_user "test out: $test_out\n"
+
+# send_user "result of compare [string compare $test_out $comp_output]\n"
+# send_user "result of match [string match $test_out $comp_output]\n"
+
+if ![string compare $test_out $comp_output] {
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/test.30.exp b/unit-tests/das-testsuite/das-test.0/test.30.exp
new file mode 100644
index 0000000..2331b6a
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.30.exp
@@ -0,0 +1,44 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.30.exp,v $
+# Revision 1.3  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.2.6.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.30
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error parsing the text on line 15
+Could not find the attribute `comp.g' in the attribute object.
+"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.31.exp b/unit-tests/das-testsuite/das-test.0/test.31.exp
new file mode 100644
index 0000000..82cf8f3
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.31.exp
@@ -0,0 +1,47 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.31.exp,v $
+# Revision 1.2  2001/01/26 19:48:10  jimg
+# Merged with release-3-2-3.
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.31
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Int32 x 14;
+        Int32 y 15, 16, 17;
+        component1 {
+            Float64 g 6.02e23;
+            String name \"A part of the whole\";
+            inner_component {
+                String tag \"xyz123\";
+                Url my_url \"http://dcz.dods.org/\";
+            }
+        }
+        Alias url_info inner_component;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.32.exp b/unit-tests/das-testsuite/das-test.0/test.32.exp
new file mode 100644
index 0000000..9d4468b
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.32.exp
@@ -0,0 +1,42 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.32.exp,v $
+# Revision 1.2  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.1.2.1  2002/03/14 20:01:16  jimg
+# Added
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.32
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Float64 g 6.02e23;
+        Float64 h NaN;
+        Float32 i NaN;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.33.exp b/unit-tests/das-testsuite/das-test.0/test.33.exp
new file mode 100644
index 0000000..25e5ae7
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.33.exp
@@ -0,0 +1,42 @@
+
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.33.exp,v $
+# Revision 1.2  2002/06/03 22:21:16  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.1.2.1  2002/03/14 20:01:16  jimg
+# Added
+#
+# Revision 1.1.2.1  2000/11/30 05:20:20  jimg
+# Added
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.33
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        Float64 Float64 6.02e23;
+        String Url \"http://www.google.com/\";
+        Url String \"http://huh.com/\";
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
diff --git a/unit-tests/das-testsuite/das-test.0/test.4.exp b/unit-tests/das-testsuite/das-test.0/test.4.exp
new file mode 100644
index 0000000..e81394f
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.4.exp
@@ -0,0 +1,94 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.4
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    a {
+        String b c;
+        Int32 attributes 4;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+# $Log: test.4.exp,v $
+# Revision 1.15  2003/01/10 19:46:43  jimg
+# Merged with code tagged release-3-2-10 on the release-3-2 branch. In many
+# cases files were added on that branch (so they appear on the trunk for
+# the first time).
+#
+# Revision 1.14.4.2  2002/05/31 21:38:42  jimg
+# Removed extra space in test_out. Arrgh...
+#
+# Revision 1.14.4.1  2002/05/31 21:32:58  jimg
+# The reserved word `attributes' can be used as the name of an attribute now.
+#
+# Revision 1.14  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.13  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.12.10.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.12  1999/03/24 23:42:22  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.11  1997/05/13 23:29:26  jimg
+# *** empty log message ***
+#
+# Revision 1.10  1997/03/27 18:19:59  jimg
+# Update for version 2.13
+#
+# Revision 1.9  1996/11/13 19:23:45  jimg
+# *** empty log message ***
+#
+# Revision 1.8  1996/08/12 22:22:19  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.7  1996/05/14 15:40:51  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.6  1994/12/09  21:45:48  jimg
+# Modified for new unix.exp.
+#
+# Revision 1.5  1994/10/13  16:04:12  jimg
+# Now works with the new das-test (but only when das-test is compiled
+# w/o DEBUG and TRACE_NEW).
+#
+# Revision 1.4  1994/10/05  16:51:50  jimg
+# Added TYPE to each of the DAS test files.
+# The `expect' files correcly check for that in the output.
+#
+# Revision 1.3  1994/09/27  23:14:16  jimg
+# Changed expected outcomes to match new das.print() mfunc.
+#
+# Revision 1.2  1994/09/09  16:15:23  jimg
+# Fixed namign of the test (was given as $srcdir//$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:22  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
diff --git a/unit-tests/das-testsuite/das-test.0/test.5.exp b/unit-tests/das-testsuite/das-test.0/test.5.exp
new file mode 100644
index 0000000..2e3f51f
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.5.exp
@@ -0,0 +1,62 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.5.exp,v $
+# Revision 1.7  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.6.10.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.6  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.5.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.5  1997/05/13 23:29:27  jimg
+# *** empty log message ***
+#
+# Revision 1.4  1996/05/14 15:40:52  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.3  1994/12/09  21:45:50  jimg
+# Modified for new unix.exp.
+#
+# Revision 1.2  1994/09/09  16:15:25  jimg
+# Fixed namign of the test (was given as $srcdir//$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:23  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.5
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error scanning DAS object text: Unterminated quote (starts on line 6)
+"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/test.6.exp b/unit-tests/das-testsuite/das-test.0/test.6.exp
new file mode 100644
index 0000000..b0a3719
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.6.exp
@@ -0,0 +1,94 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.6
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error *"
+
+das-test_start p $srcdir/$test_name
+
+if [string match $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+# $Log: test.6.exp,v $
+# Revision 1.15  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.14.4.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.14  2003/01/10 07:15:53  jimg
+# resolved conflicts from the merge with release-3-2-10.
+#
+# Revision 1.13  2001/08/24 17:46:23  jimg
+# Resolved conflicts from the merge of release 3.2.6
+#
+# Revision 1.12.4.1  2001/06/23 00:52:32  jimg
+# Added tests for `#' in IDs.
+#
+# Revision 1.12.4.2  2002/06/11 00:31:20  jimg
+# Fixed this test. It's better to test just for the Error word at the start of
+# the das-test program's output. That way the same test can keep on working as
+# long as the error message continues to start with that word. I also moved the
+# log file to end of the file.
+#
+# Revision 1.12  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.11  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.10.10.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.10  1999/03/24 23:42:23  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.9  1997/05/13 23:29:28  jimg
+# *** empty log message ***
+#
+# Revision 1.8  1997/03/27 18:20:00  jimg
+# Update for version 2.13
+#
+# Revision 1.7  1996/11/13 19:23:46  jimg
+# *** empty log message ***
+#
+# Revision 1.6  1996/08/12 22:22:20  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.5  1996/05/14 15:40:53  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.4  1995/02/10  03:31:16  jimg
+# Modified test cases for type checking.
+#
+# Revision 1.3  1994/12/09  21:45:51  jimg
+# Modified for new unix.exp.
+#
+# Revision 1.2  1994/09/09  16:15:26  jimg
+# Fixed namign of the test (was given as $srcdir//$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:24  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
diff --git a/unit-tests/das-testsuite/das-test.0/test.7.exp b/unit-tests/das-testsuite/das-test.0/test.7.exp
new file mode 100644
index 0000000..779bf60
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.7.exp
@@ -0,0 +1,106 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.7.exp,v $
+# Revision 1.10  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.9.10.1  2003/10/03 16:26:30  jimg
+# Fixed tests; I changed the text of das-test just a little and so these
+# had to be updated. I wanted to be sure that the error message was from
+# an exception and not just a write to stderr.
+#
+# Revision 1.9  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.8  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.7.10.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.7  1999/03/24 23:42:23  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.6  1997/05/13 23:29:30  jimg
+# *** empty log message ***
+#
+# Revision 1.5  1997/03/27 18:20:02  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/11/13 19:23:47  jimg
+# *** empty log message ***
+#
+# Revision 1.3  1996/08/12 22:22:21  jimg
+# Changed for the new error message text from the parser.
+#
+# Revision 1.2  1996/05/14 15:40:54  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:53  jimg
+# Added these tests. See comments in files in parent directory.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.7
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Caught Error object:
+Error parsing the text on line 10 at or near: my_test
+Expected an attribute type (Byte, Int16, UInt16, Int32, UInt32, Float32,
+Float64, String or Url) followed by a name and value."
+
+das-test_start p $srcdir/$test_name
+
+set comp_output [string trim $comp_output]
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    set tlen [string length $test_out]
+    set clen [string length $comp_output]
+
+    set len $tlen;			# used by for loop below
+
+    if {$clen < $tlen} {
+	set len $clen;			# set if needed
+
+	set size [expr $tlen - $clen]
+	send_user "comp_output is smaller (by $size chars) than expected!\n"
+	send_user "Here's the excess: '"
+	send_user [string range $test_out [expr $clen -1] end]
+ 	send_user "'\n"
+    } elseif {$tlen < $clen} {
+	set size [expr $clen - $tlen]
+	send_user "comp_output is larger (by $size chars) than expected!\n"
+	send_user "Here's the excess: '"
+	send_user [string range $comp_output [expr $tlen -1] end]
+	send_user "'\n"
+    }
+
+    # $len is set to the smallest of $tlen or $clen to avoid running off the
+    # end either of the strings.
+    for {set i 0} {$i < $len} {incr i} {
+	set c [string index $comp_output $i]
+	set t [string index $test_out $i]
+	if {$t != $c} {
+	    send_user "comp_output ($c) and test_out ($t) differ at $i.\n"
+	}
+    }
+    
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/test.8.exp b/unit-tests/das-testsuite/das-test.0/test.8.exp
new file mode 100644
index 0000000..71b1841
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.8.exp
@@ -0,0 +1,63 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.8.exp,v $
+# Revision 1.4  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.3.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.3  1997/05/13 23:29:31  jimg
+# *** empty log message ***
+#
+# Revision 1.2  1996/05/14 15:40:56  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:54  jimg
+# Added these tests. See comments in files in parent directory.
+#
+# Revision 1.4  1994/10/05  16:51:45  jimg
+# Added TYPE to each of the DAS test files.
+# The `expect' files correcly check for that in the output.
+#
+# Revision 1.3  1994/09/27  23:14:13  jimg
+# Changed expected outcomes to match new das.print() mfunc.
+#
+# Revision 1.2  1994/09/09  16:15:20  jimg
+# Fixed namign of the test (was given as $srcdir//$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:19  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.8
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var0 {
+        String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/das-test.0/test.9.exp b/unit-tests/das-testsuite/das-test.0/test.9.exp
new file mode 100644
index 0000000..9b6a0c2
--- /dev/null
+++ b/unit-tests/das-testsuite/das-test.0/test.9.exp
@@ -0,0 +1,71 @@
+# expect/tcl code to test the das parser and scanner
+# jhrg
+#
+# $Log: test.9.exp,v $
+# Revision 1.4  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.3.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.3  1997/05/13 23:29:32  jimg
+# *** empty log message ***
+#
+# Revision 1.2  1996/05/14 15:40:57  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1995/02/16  15:34:55  jimg
+# Added these tests. See comments in files in parent directory.
+#
+# Revision 1.4  1994/10/05  16:51:45  jimg
+# Added TYPE to each of the DAS test files.
+# The `expect' files correcly check for that in the output.
+#
+# Revision 1.3  1994/09/27  23:14:13  jimg
+# Changed expected outcomes to match new das.print() mfunc.
+#
+# Revision 1.2  1994/09/09  16:15:20  jimg
+# Fixed namign of the test (was given as $srcdir/$test_name, should have been
+# $srcdir$test_name).
+#
+# Revision 1.1  1994/08/29  19:57:19  jimg
+# Test procedures for the DAS parser, scanner and C++ class.
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.9
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Attributes {
+    var1 {
+        String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+    }
+    var2 {
+        String day Monday, Tuesday, Wed;
+        String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+        String name bob;
+        Int32 num 10;
+        String irrational 3.1415, 2.718, 1.414;
+        Float64 irrational_numbers 3.1415, 2.718, 1.414;
+    }
+}"
+
+das-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/das-testsuite/special.test.das b/unit-tests/das-testsuite/special.test.das
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/das-testsuite/special.test.hdf b/unit-tests/das-testsuite/special.test.hdf
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/das-testsuite/test.1 b/unit-tests/das-testsuite/test.1
new file mode 100644
index 0000000..01f7a42
--- /dev/null
+++ b/unit-tests/das-testsuite/test.1
@@ -0,0 +1,54 @@
+
+
+#  -*- C++ -*-
+#
+#    This is a test of the das scanner and parser software. This file tests
+#    comments, attribute lists with missing parts, and multiple attribute
+#    lists (they should all coalesce into one attribute table.
+
+attributes {# weird
+    var1 {#test
+    	string name bob;	# bob is the only name allowed
+	string type human;	# for people ... 
+	int32 age 19;
+    }
+    var2 {
+	string name joe;
+	string type dog;   
+	int32 age 8;
+    }
+}   
+
+# This is a C++ type comment.
+# The scanner and parser should handle a text file with several
+# attribute-definintion sections.
+
+Attributes {
+    var3 {
+    	int32 size 8;
+	string color red;
+	string type art;
+    }
+    var4 {
+    }
+}
+
+ATTRIBUTES {
+    var5 {
+    	string height 5.0in.;
+	string units inches;
+	float64 max 5.0;
+    }
+}
+
+attributes {
+}
+
+attributes {
+    var5 {
+	string weight 100lbs;
+	string color red;
+    }
+}
+#
+# EOF must be at the end of this line (not on the line after)
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.1.das b/unit-tests/das-testsuite/test.1.das
new file mode 100644
index 0000000..32c9c4d
--- /dev/null
+++ b/unit-tests/das-testsuite/test.1.das
@@ -0,0 +1,6 @@
+Attributes{
+    DODS_GLOBAL {
+	String About "This is used to test find_ancillary_das()";
+    }
+}
+
diff --git a/unit-tests/das-testsuite/test.1.gz b/unit-tests/das-testsuite/test.1.gz
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/das-testsuite/test.11 b/unit-tests/das-testsuite/test.11
new file mode 100644
index 0000000..94bb19e
--- /dev/null
+++ b/unit-tests/das-testsuite/test.11
@@ -0,0 +1,15 @@
+
+# -*- Perl -*-
+# test all sorts of numbers (do they all parse correctly?)
+
+Attributes {
+    test {
+	String names this, is, a, vector, of, strings;
+	Byte b 1, 0, 127, 255;
+	Int32 int_vec 1, 2, 2147483647; # nearly the bigest int32 allowed
+	Float64 float_vec 1.0, -1.0, +1.0, 0.2, -0.2, +0.2, .3, -.3, +.3,
+	                  -3.1415, -3.1415e-99, -3.1415e+99, +3.1415e-99,
+	                  -3., +2., 4.; # big float vector
+        Url where http://bozo.place.com/home.html;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.12 b/unit-tests/das-testsuite/test.12
new file mode 100644
index 0000000..830c23b
--- /dev/null
+++ b/unit-tests/das-testsuite/test.12
@@ -0,0 +1,8 @@
+
+# test for bad floating point values
+
+Attributes {
+    var1 {
+        Float64 f1 3.0.0;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.13 b/unit-tests/das-testsuite/test.13
new file mode 100644
index 0000000..4f6d891
--- /dev/null
+++ b/unit-tests/das-testsuite/test.13
@@ -0,0 +1,8 @@
+
+# more float testing
+
+Attributes {
+    var1 {
+        Float64 f1 -3..0;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.14 b/unit-tests/das-testsuite/test.14
new file mode 100644
index 0000000..0dd134d
--- /dev/null
+++ b/unit-tests/das-testsuite/test.14
@@ -0,0 +1,8 @@
+
+# still more ... This should work
+
+Attributes {
+    var1 {
+        Float64 f1 3;
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.15 b/unit-tests/das-testsuite/test.15
new file mode 100644
index 0000000..336ec02
--- /dev/null
+++ b/unit-tests/das-testsuite/test.15
@@ -0,0 +1,8 @@
+
+# floats as ints; should not work
+
+Attributes {
+    var1 {
+        Int32 i1 3.0;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.16 b/unit-tests/das-testsuite/test.16
new file mode 100644
index 0000000..14bf10c
--- /dev/null
+++ b/unit-tests/das-testsuite/test.16
@@ -0,0 +1,13 @@
+
+# Test variable redefinition error
+
+Attributes {
+    var1 {
+        Int32 i 1;
+	Float64 i 10.8; # this is an error since `i' is already an Int32
+	Float64 j 100.98;
+    }
+    var2 {
+	 Float64 i 1.8; # not an error; different variable
+    }
+}
diff --git a/unit-tests/das-testsuite/test.17 b/unit-tests/das-testsuite/test.17
new file mode 100644
index 0000000..4fcc8dc
--- /dev/null
+++ b/unit-tests/das-testsuite/test.17
@@ -0,0 +1,13 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Byte b "this is not a byte";
+	byte c -256;
+	byte d 255;		# This on is OK; 4/5/96 NO, see dods-limits.h
+	byte e 2550;
+	byte f 2.55;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.18 b/unit-tests/das-testsuite/test.18
new file mode 100644
index 0000000..99cf481
--- /dev/null
+++ b/unit-tests/das-testsuite/test.18
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float32 f 2.55;
+	Int16 x 6535;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.19 b/unit-tests/das-testsuite/test.19
new file mode 100644
index 0000000..b732fce
--- /dev/null
+++ b/unit-tests/das-testsuite/test.19
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float64 f 2.55E-300;
+	Float32 g 2.55E-300;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.2 b/unit-tests/das-testsuite/test.2
new file mode 100644
index 0000000..6f3158b
--- /dev/null
+++ b/unit-tests/das-testsuite/test.2
@@ -0,0 +1,8 @@
+attributes {
+    a {
+	string b c;
+	string d 4;
+    }
+}
+
+# single letter ID's and EOF w/o a preceding return
diff --git a/unit-tests/das-testsuite/test.20 b/unit-tests/das-testsuite/test.20
new file mode 100644
index 0000000..5e41993
--- /dev/null
+++ b/unit-tests/das-testsuite/test.20
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Int32 x 70000;
+	Int16 y 80000;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.21 b/unit-tests/das-testsuite/test.21
new file mode 100644
index 0000000..da6c8d2
--- /dev/null
+++ b/unit-tests/das-testsuite/test.21
@@ -0,0 +1,10 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float64 f 2.55E300;
+	Float32 g 2.55E300;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.22 b/unit-tests/das-testsuite/test.22
new file mode 100644
index 0000000..7ba6c8d
--- /dev/null
+++ b/unit-tests/das-testsuite/test.22
@@ -0,0 +1,9 @@
+
+# -*- Perl -*-
+# byte values that should not parse, in various ways...
+
+Attributes {
+    test {
+	Float64 f 2.55E400;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.23 b/unit-tests/das-testsuite/test.23
new file mode 100644
index 0000000..4146e5f
--- /dev/null
+++ b/unit-tests/das-testsuite/test.23
@@ -0,0 +1,13 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+    }
+    
+    # Alias `var2' to the existing `var1'.
+    Alias var2 var1;
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.24 b/unit-tests/das-testsuite/test.24
new file mode 100644
index 0000000..a535fa8
--- /dev/null
+++ b/unit-tests/das-testsuite/test.24
@@ -0,0 +1,17 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+    
+    # Alias `var2' to the existing `var1.component'.
+    Alias component2 var1.component1;
+}
diff --git a/unit-tests/das-testsuite/test.25 b/unit-tests/das-testsuite/test.25
new file mode 100644
index 0000000..5b4cc45
--- /dev/null
+++ b/unit-tests/das-testsuite/test.25
@@ -0,0 +1,17 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+    
+    # Alias `name' to the existing `var1.component1.name'.
+    Alias name var1.component1.name;
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.26 b/unit-tests/das-testsuite/test.26
new file mode 100644
index 0000000..63da382
--- /dev/null
+++ b/unit-tests/das-testsuite/test.26
@@ -0,0 +1,15 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	alias z x;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.27 b/unit-tests/das-testsuite/test.27
new file mode 100644
index 0000000..81be287
--- /dev/null
+++ b/unit-tests/das-testsuite/test.27
@@ -0,0 +1,15 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+	Alias new_name component1;
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.28 b/unit-tests/das-testsuite/test.28
new file mode 100644
index 0000000..3c227c9
--- /dev/null
+++ b/unit-tests/das-testsuite/test.28
@@ -0,0 +1,16 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+	
+	Alias z component1.g;
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.29 b/unit-tests/das-testsuite/test.29
new file mode 100644
index 0000000..d0e4071
--- /dev/null
+++ b/unit-tests/das-testsuite/test.29
@@ -0,0 +1,16 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+    }
+    # This should fail since var1.comp does not exist.
+    alias var2 var1.comp;
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.3 b/unit-tests/das-testsuite/test.3
new file mode 100644
index 0000000..294a21b
--- /dev/null
+++ b/unit-tests/das-testsuite/test.3
@@ -0,0 +1,12 @@
+
+#  Test Quotes.
+
+Attributes {
+    var1 {
+	string comment "One thing about these long comments is that they
+might cause problems with memory - overwrites, ...";
+	string comment2 "This quote tests a \"quote within a quote\", he said";
+	string quote1 "\"";		# tricky
+	string quote2 "\7 seven";
+    }
+}
diff --git a/unit-tests/das-testsuite/test.3.Z b/unit-tests/das-testsuite/test.3.Z
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/das-testsuite/test.3.Z.das b/unit-tests/das-testsuite/test.3.Z.das
new file mode 100644
index 0000000..e69de29
diff --git a/unit-tests/das-testsuite/test.30 b/unit-tests/das-testsuite/test.30
new file mode 100644
index 0000000..5b4bdfa
--- /dev/null
+++ b/unit-tests/das-testsuite/test.30
@@ -0,0 +1,17 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	}
+	
+	# This should fail.
+	Alias z comp.g;
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.31 b/unit-tests/das-testsuite/test.31
new file mode 100644
index 0000000..9ff5bb5
--- /dev/null
+++ b/unit-tests/das-testsuite/test.31
@@ -0,0 +1,20 @@
+# -*- perl -*-
+#
+# Test aliases
+
+Attributes {
+    var1 {
+        Int32 x 14;
+	Int32 y 15, 16, 17;
+	component1 {
+	    Float64 g 6.02e23;
+	    String name "A part of the whole";
+	    inner_component {
+		String tag "xyz123";
+		URL my_url "http://dcz.dods.org/";
+	    }
+	}
+	
+	Alias url_info var1.component1.inner_component;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.32 b/unit-tests/das-testsuite/test.32
new file mode 100644
index 0000000..710a48c
--- /dev/null
+++ b/unit-tests/das-testsuite/test.32
@@ -0,0 +1,10 @@
+# -*- perl -*-
+#
+
+Attributes {
+    var1 {
+	 Float64 g 6.02e23;
+	 Float64 h NaN;
+	 Float32 i NaN;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.33 b/unit-tests/das-testsuite/test.33
new file mode 100644
index 0000000..7a6b6f7
--- /dev/null
+++ b/unit-tests/das-testsuite/test.33
@@ -0,0 +1,10 @@
+# -*- perl -*-
+#
+
+Attributes {
+    var1 {
+	 Float64 Float64 6.02e23;
+	 String Url "http://www.google.com/";
+	 Url String "http://huh.com/";
+    }
+}
diff --git a/unit-tests/das-testsuite/test.34 b/unit-tests/das-testsuite/test.34
new file mode 100644
index 0000000..fdeb15d
--- /dev/null
+++ b/unit-tests/das-testsuite/test.34
@@ -0,0 +1,10 @@
+Attributes {
+    var1 {
+        Int32 y#z 15;
+        component1 {
+	    inner%20component {
+	        String tag "xyz123";
+	    }
+        }
+    }
+}
\ No newline at end of file
diff --git a/unit-tests/das-testsuite/test.4 b/unit-tests/das-testsuite/test.4
new file mode 100644
index 0000000..e3b3e92
--- /dev/null
+++ b/unit-tests/das-testsuite/test.4
@@ -0,0 +1,8 @@
+# This should work (now, it used to generate an error because `attributes'
+# is a reserved word.
+attributes {
+    a {
+	string b c;
+	int32 attributes 4;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.5 b/unit-tests/das-testsuite/test.5
new file mode 100644
index 0000000..04648c4
--- /dev/null
+++ b/unit-tests/das-testsuite/test.5
@@ -0,0 +1,9 @@
+# Test unterminated quote
+
+attributes {
+    var10 {
+	string attr woof;
+	string quote "this quote has no end;
+    }
+}
+
diff --git a/unit-tests/das-testsuite/test.6 b/unit-tests/das-testsuite/test.6
new file mode 100644
index 0000000..2004581
--- /dev/null
+++ b/unit-tests/das-testsuite/test.6
@@ -0,0 +1,10 @@
+
+#  Test unterminated comments. Old test, should fail miserably
+
+attributes {
+    var_11 {
+	string slota val1;
+	string slotb val2; /* a bad comment
+    }
+}
+
diff --git a/unit-tests/das-testsuite/test.7 b/unit-tests/das-testsuite/test.7
new file mode 100644
index 0000000..8fab860
--- /dev/null
+++ b/unit-tests/das-testsuite/test.7
@@ -0,0 +1,12 @@
+# -*- C++ -*-
+
+#  Test missing type specifier.
+
+Attributes {
+    aa {
+	int32 i 10;
+	float64 f 12.9;
+	string test test;
+	test2 my_test;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.8 b/unit-tests/das-testsuite/test.8
new file mode 100644
index 0000000..813eacf
--- /dev/null
+++ b/unit-tests/das-testsuite/test.8
@@ -0,0 +1,9 @@
+#  -*- C++ -*-
+
+# Test attribute vectors.
+
+Attributes {
+    var0 {
+	String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+    }
+}
diff --git a/unit-tests/das-testsuite/test.9 b/unit-tests/das-testsuite/test.9
new file mode 100644
index 0000000..66b87ee
--- /dev/null
+++ b/unit-tests/das-testsuite/test.9
@@ -0,0 +1,18 @@
+
+#  -*- C++ -*-
+#
+# Test attribute vectors.
+
+Attributes {
+    var1 {
+	String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+    }
+    var2 {
+	String day Monday, Tuesday, Wed;
+	String month Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Nov, Dec;
+	String name bob;
+	Int32 num 10;
+	String irrational 3.1415, 2.718, 1.414;
+	Float64 irrational_numbers 3.1415, 2.718, 1.414;
+    }
+}
diff --git a/unit-tests/dasT.cc b/unit-tests/dasT.cc
new file mode 100644
index 0000000..270434c
--- /dev/null
+++ b/unit-tests/dasT.cc
@@ -0,0 +1,176 @@
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+// #define DODS_DEBUG
+
+#include "DAS.h"
+
+#include "testFile.cc"
+
+using namespace std;
+using namespace libdap;
+
+string dprint = "\
+Attributes {\n\
+    c1 {\n\
+        v1 {\n\
+            String v1a1 \"v1a1val\";\n\
+            String v1a2 \"v1a2val\";\n\
+            String v1a3 \"v1a3val\";\n\
+            String v1a4 \"v1a4val\";\n\
+            v1v1 {\n\
+                String v1v1a1 \"v1v1a1val\";\n\
+                String v1v1a2 \"v1v1a2val\";\n\
+            }\n\
+        }\n\
+    }\n\
+    c2 {\n\
+        v2 {\n\
+            String v2a1 \"v2a1val\";\n\
+            String v2a2 \"v2a2val\";\n\
+        }\n\
+        v3 {\n\
+            String v3a1 \"v3a1val\";\n\
+            String v3a2 \"v3a2val\";\n\
+            v3v1 {\n\
+                String v3v1a1 \"v3v1a1val\";\n\
+            }\n\
+        }\n\
+    }\n\
+}\n\
+" ;
+
+class dasT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( dasT ) ;
+CPPUNIT_TEST( dasT_test ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+private:
+    /* TEST PRIVATE DATA */
+    
+public:
+    void setUp()
+    {
+    }
+
+    void tearDown() 
+    {
+    }
+
+    void dasT_test()
+    {
+	DAS das ;
+	CPPUNIT_ASSERT( das.get_size() == 0 ) ;
+	CPPUNIT_ASSERT( das.container_name().empty() ) ;
+	CPPUNIT_ASSERT( das.container() == 0 ) ;
+
+	// set container to c1 and make sure set correctly
+	das.container_name( "c1" ) ;
+	CPPUNIT_ASSERT( das.container_name() == "c1" ) ;
+	CPPUNIT_ASSERT( das.container() ) ;
+	CPPUNIT_ASSERT( das.container()->get_name() == "c1" ) ;
+	CPPUNIT_ASSERT( das.get_size() == 0 ) ;
+
+	// set back to upermost attribute table and test
+	das.container_name( "" ) ;
+	CPPUNIT_ASSERT( das.container_name().empty() ) ;
+	CPPUNIT_ASSERT( !das.container() ) ;
+	CPPUNIT_ASSERT( das.get_size() == 1 ) ;
+	
+	// change to c2
+	das.container_name( "c2" ) ;
+	CPPUNIT_ASSERT( das.container_name() == "c2" ) ;
+	CPPUNIT_ASSERT( das.container() ) ;
+	CPPUNIT_ASSERT( das.container()->get_name() == "c2" ) ;
+	CPPUNIT_ASSERT( das.get_size() == 0 ) ;
+
+	// set back to upermost attribute table and test
+	das.container_name( "" ) ;
+	CPPUNIT_ASSERT( das.container_name().empty() ) ;
+	CPPUNIT_ASSERT( !das.container() ) ;
+	CPPUNIT_ASSERT( das.get_size() == 2 ) ;
+	
+	// change back to c1, make sure not another c1 added
+	das.container_name( "c1" ) ;
+	CPPUNIT_ASSERT( das.container_name() == "c1" ) ;
+	CPPUNIT_ASSERT( das.container() ) ;
+	CPPUNIT_ASSERT( das.container()->get_name() == "c1" ) ;
+	CPPUNIT_ASSERT( das.get_size() == 0 ) ;
+
+	// set back to upermost attribute table and test
+	das.container_name( "" ) ;
+	CPPUNIT_ASSERT( das.container_name().empty() ) ;
+	CPPUNIT_ASSERT( !das.container() ) ;
+	CPPUNIT_ASSERT( das.get_size() == 2 ) ;
+	
+	// add stuff to das, should go to c1
+	das.container_name( "c1" ) ;
+	AttrTable *v1 = new AttrTable ;
+	das.add_table( "v1", v1 ) ;
+	v1->append_attr( "v1a1", "String", "v1a1val" ) ;
+	v1->append_attr( "v1a2", "String", "v1a2val" ) ;
+	v1->append_attr( "v1a3", "String", "v1a3val" ) ;
+	v1->append_attr( "v1a4", "String", "v1a4val" ) ;
+	AttrTable *v1v1 = v1->append_container( "v1v1" ) ;
+	v1v1->append_attr( "v1v1a1", "String", "v1v1a1val" ) ;
+	v1v1->append_attr( "v1v1a2", "String", "v1v1a2val" ) ;
+
+	// check container and das size
+	CPPUNIT_ASSERT( das.get_size() == 1 ) ;
+	das.container_name( "" ) ;
+	CPPUNIT_ASSERT( das.get_size() == 2 ) ;
+
+	// add stuff to das, should go to c2
+	das.container_name( "c2" ) ;
+	AttrTable *v2 = new AttrTable ;
+	das.add_table( "v2", v2 ) ;
+	v2->append_attr( "v2a1", "String", "v2a1val" ) ;
+	v2->append_attr( "v2a2", "String", "v2a2val" ) ;
+	AttrTable *v3 = new AttrTable ;
+	das.add_table( "v3", v3 ) ;
+	v3->append_attr( "v3a1", "String", "v3a1val" ) ;
+	v3->append_attr( "v3a2", "String", "v3a2val" ) ;
+	AttrTable *v3v1 = v3->append_container( "v3v1" ) ;
+	v3v1->append_attr( "v3v1a1", "String", "v3v1a1val" ) ;
+
+	// check container and das size
+	CPPUNIT_ASSERT( das.get_size() == 2 ) ;
+	das.container_name( "" ) ;
+	CPPUNIT_ASSERT( das.get_size() == 2 ) ;
+
+	// print to stream and compare results
+	ostringstream strm ;
+	das.print( strm ) ;
+	cout << strm.str() << endl ;
+	cout << dprint << endl ;
+	CPPUNIT_ASSERT( strm.str() == dprint ) ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( dasT ) ;
+
+/* NOTHING NEEDS TO BE CHANGED BELOW HERE */
+
+int main( int, char ** )
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( 
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/dds-testsuite/3B42.980909.5.HDF.das b/unit-tests/dds-testsuite/3B42.980909.5.HDF.das
new file mode 100644
index 0000000..36ecd48
--- /dev/null
+++ b/unit-tests/dds-testsuite/3B42.980909.5.HDF.das
@@ -0,0 +1,626 @@
+Attributes {
+    HDF_GLOBAL {
+    }
+    CoreMetadata {
+        OrbitNumber {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeBeginningDate {
+            String Value 1998/09/09;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeBeginningTime {
+            String Value 00:00:00;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeEndingDate {
+            String Value 1998/09/10;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeEndingTime {
+            String Value 00:00:00;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GranulePointer {
+            String Value "3B42.980909.5.HDF";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ShortName {
+            String Value "Surface Rain from Geostationary Satellites C";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SizeMBECSDataGranule {
+            Float64 Value 0.220007;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LongitudeOfMaximumLatitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SpatialCoverageType {
+            String Value "Horizontal";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EllipsoidName {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EquatorialRadius {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DenominatorFlatteningRatio {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitalModelName {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SemiMajorAxis {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MeanAnomaly {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RightAscensionNode {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ArgumentOfPerigee {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        Eccentricity {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        Inclination {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EpochTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EpochDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EpochMillisec {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        WestBoundingCoordinate {
+            Int32 Value -180;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EastBoundingCoordinate {
+            Int32 Value 180;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NorthBoundingCoordinate {
+            Int32 Value 40;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SouthBoundingCoordinate {
+            Int32 Value -40;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterLatitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterLongitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadiusValue {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LatitudeResolution {
+            String Value "1deg";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LongitudeResolution {
+            String Value "1deg";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GeographicCoordinateUnits {
+            String Value "Decimal Degrees";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        TemporalRangeType {
+            String Value "Continuous Range";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        QualityAssuranceParameterName {
+            String Value "ScienceQualityFlag";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        QualityAssuranceParameterValue {
+            String Value "NOT BEING INVESTIGATED";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ReprocessingActual {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        BrowsePointer {
+            String Value "3B42_BR.980909.5.BRO";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ScienceContact {
+            String Value "George Huffman";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MeanMotion {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitAdjustFlag {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AttitudeModeFlag {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SolarBetaAngleAtBeginningOfGranule {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SolarBetaAngleAtEndOfGranule {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SensorAlignment {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SensorAlignmentChannelOffsets {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ScanPathModel {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ScanPathModelParam {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        EphemerisFileID {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+    }
+    ArchiveMetadata {
+        DataGaps {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NumberOfDataGaps {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AlgorithmVersion {
+            String Value "4.51";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ProductVersion {
+            Int32 Value 5;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        ToolkitVersion {
+            String Value "5.6";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CalibrationCoefficientVersion {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MissingData {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        PercentOfBadOrMissingPixels {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MaximumValidValueofChannel {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MinimumValidValueofChannel {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MinMaxUnits {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitSize {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarWavelength {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        MinimumReflectivityThreshold {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AlgorithmID {
+            String Value "3B42m2";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DataAccuracy {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        InputFiles {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DateOfGenerationOfInputFiles {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DataCenterSourceOfInputFiles {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GenerationDate {
+            String Value 2000-02-09T11:00:04.000Z;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DayNight {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SolarChannelGains {
+            String Value "(-9999.9,-9999.9,-9999.9,-9999.9)";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        TMIRolloverCoef {
+            String Value "(-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9,-9999.9)";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstScanUTCDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstScanUTCTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstScanUTCMilliseconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstSCSecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitFirstSCSubsecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastScanUTCDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastScanUTCTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastScanUTCmilliseconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastSCSecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        OrbitLastSCSubsecs {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCFSeconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCFSubseconds {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCFflag {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LeapSecondsFlag {
+            String Value Data_Location, "Error processing EOS attributes", "Error processing EOS attributes";
+            String PGE "Error processing EOS attributes";
+            String Mandatory FALSE;
+        }
+        RadarSiteName {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarCity {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarState {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarCountry {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NumberOfVOS {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridOriginLatitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridOriginLongitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridOriginAltitude {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSpacingX {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSpacingY {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSpacingZ {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSizeX {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSizeY {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RadarGridSizeZ {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DZCal {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        GVL1C_Scale {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        Alpha {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RuntimeOptions {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        AnomalyFlag {
+            String Value "NOT EMPTY";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        SoftwareVersion {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        DatabaseVersion {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        TotalQualityCode {
+            String Value "NULL";
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LongitudeOnEquator {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCDateOnEquator {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCTimeOnEquator {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        UTCMillisecsOnEquator {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterScanUTCDate {
+            String Value 9999/99/99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterScanUTCTime {
+            String Value 99:99:99;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        CenterScanUTCMillisec {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        FirstScanLat {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        FirstScanLon {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LastScanLat {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        LastScanLon {
+            Float64 Value -9999.9;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        NumberOfRainScans {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+    }
+    percipitate_dim_0 {
+        String name "scan";
+    }
+    percipitate_dim_1 {
+        String name "longitude";
+    }
+    percipitate_dim_2 {
+        String name "latitude";
+    }
+    relError_dim_0 {
+        String name "scan";
+    }
+    relError_dim_1 {
+        String name "longitude";
+    }
+    relError_dim_2 {
+        String name "latitude";
+    }
+}
diff --git a/unit-tests/dds-testsuite/3B42.980909.5.HDF.dds b/unit-tests/dds-testsuite/3B42.980909.5.HDF.dds
new file mode 100644
index 0000000..259a06a
--- /dev/null
+++ b/unit-tests/dds-testsuite/3B42.980909.5.HDF.dds
@@ -0,0 +1,8 @@
+Dataset {
+    Structure {
+        Structure {
+            Float32 percipitate[scan = 1][longitude = 360][latitude = 80];
+            Float32 relError[scan = 1][longitude = 360][latitude = 80];
+        } PlanetaryGrid;
+    } DATA_GRANULE;
+} 3B42.980909.5.HDF;
diff --git a/unit-tests/dds-testsuite/3B42.980909.5.hacked.HDF.das b/unit-tests/dds-testsuite/3B42.980909.5.hacked.HDF.das
new file mode 100644
index 0000000..3409a57
--- /dev/null
+++ b/unit-tests/dds-testsuite/3B42.980909.5.hacked.HDF.das
@@ -0,0 +1,34 @@
+Attributes {
+    HDF_GLOBAL {
+    }
+    CoreMetadata {
+        OrbitNumber {
+            Int32 Value -9999;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+        RangeBeginningDate {
+            String Value 1998/09/09;
+            String Data_Location PGE;
+            String Mandatory FALSE;
+        }
+    }
+    percipitate_dim_0 {
+        String name "scan";
+    }
+    percipitate_dim_1 {
+        String name "longitude";
+    }
+    percipitate_dim_2 {
+        String name "latitude";
+    }
+    relError_dim_0 {
+        String name "scan";
+    }
+    relError_dim_1 {
+        String name "longitude";
+    }
+    relError_dim_2 {
+        String name "latitude";
+    }
+}
diff --git a/unit-tests/dds-testsuite/AsciiOutputTest1.dds b/unit-tests/dds-testsuite/AsciiOutputTest1.dds
new file mode 100644
index 0000000..fa8652b
--- /dev/null
+++ b/unit-tests/dds-testsuite/AsciiOutputTest1.dds
@@ -0,0 +1,33 @@
+# Used for the AsciiOutput unit tests.
+
+dataset {
+    Int32 a;
+
+    Structure {
+        Int32 b;
+        Float64 c;
+        String d;
+    } e;
+ 
+    Structure {
+        Int32 b;
+        Float64 c;
+        String d;
+    } f;
+
+    Grid {
+      array:
+        Byte xy[x=12][y=12];
+      maps:
+        Float64 x[12];
+	Float64 y[12];
+    } g;
+
+    Sequence {
+        Int16 j;
+	Sequence {
+	    Int16 i;
+        } h;
+    } k;
+
+} ascii_output_test;
diff --git a/unit-tests/dds-testsuite/S2000415.HDF.das b/unit-tests/dds-testsuite/S2000415.HDF.das
new file mode 100644
index 0000000..f51918e
--- /dev/null
+++ b/unit-tests/dds-testsuite/S2000415.HDF.das
@@ -0,0 +1,316 @@
+Attributes {
+    HDF_GLOBAL {
+        String Producer_Agency "NASA\\000";
+        String Producer_Institution "JPL\\000";
+        String Sensor_Name "NSCAT\\000";
+        String Project_ID "NSCAT\\000";
+        String SIS_ID "597-512-24/1996-07-01\\000";
+        String Build_ID "3.2.1/1996-11-05\\000";
+        String ADEOS_Data_Package_ID "S2\\000";
+        String ADEOS_Data_Package_Type "S\\000";
+        String Product_Creation_Time "1996-318T01:35:16.000\\000";
+        String Data_Type "L2\\000";
+        String Data_Status "COMPLETE\\000";
+        Int32 First_Rev_Number 415;
+        String First_Rev_Eq_Crossing_Time "1996-259T04:01:28.226\\000";
+        Float32 First_Rev_Eq_Crossing_Lon 279.983;
+        String First_Data_Time "1996-259T03:43:48.945\\000";
+        String Last_Data_Time "1996-259T05:09:48.997\\000";
+        Int32 Num_Expected_Output_Records 458;
+        Int32 Num_Actual_Output_Records 458;
+        String Ambig_Removal_Method "Baseline used\\000";
+        String HDF_Build_ID "JPL D-xxxxx 12/15/94\\000";
+        String HDF_SIS_ID "JPL D-12060 12/15/94\\000";
+        String HDF_Conversion_Organization "JPL PO.DAAC\\000";
+        String HDF_Conversion_Time "1996-320T17:32:34       ";
+        String Data_Format_Type "HDF\\000";
+    }
+    WVC_Lat {
+        String long_name "latitude";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Int16 valid_range -9000, 7771;
+    }
+    WVC_Lat_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Lat_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    WVC_Lon {
+        String long_name "longitude";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Uint16 valid_range 0, 31242;
+    }
+    WVC_Lon_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Lon_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Sigma0 {
+        String long_name "The total number of sigma-0 measurements";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 19;
+    }
+    Num_Sigma0_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Sigma0_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_12 {
+        String long_name "The total number of sigma-0s received from beam 1 or 2";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_12_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_12_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_34 {
+        String long_name "The total number of sigma-0s received from beam 3 or 4";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_34_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_34_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_56 {
+        String long_name "The total number of sigma-0s received from beam 5 or 6";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_56_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_56_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Num_Beam_78 {
+        String long_name "The total number of sigma-0s received from beam 7 or 8";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 6;
+    }
+    Num_Beam_78_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Beam_78_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    WVC_Quality_Flag {
+        String long_name "WVC Quality Flag";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 3;
+    }
+    WVC_Quality_Flag_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Quality_Flag_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Mean_Wind {
+        String long_name "Mean Wind Speed";
+        String units "m/s";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2374;
+    }
+    Mean_Wind_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Mean_Wind_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Wind_Speed {
+        String long_name "Wind speed associated with a WVC";
+        String units "m/s";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2571;
+    }
+    Wind_Speed_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Wind_Speed_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Wind_Speed_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Wind_Dir {
+        String long_name "Wind direction solution associated with a WVC";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 35997;
+    }
+    Wind_Dir_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Wind_Dir_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Wind_Dir_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Error_Speed {
+        String long_name "Uncertainty estimated for the wind speed value";
+        String units "m/s";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2410;
+    }
+    Error_Speed_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Error_Speed_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Error_Speed_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Error_Dir {
+        String long_name "Uncertainty estimated for the wind direction value";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 23;
+        Uint16 valid_range 0, 2435;
+    }
+    Error_Dir_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Error_Dir_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    Error_Dir_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    MLE_Likelihood {
+        String long_name "Relative likelihood that a given win vector solution is correct";
+        Float64 scale_factor 0.1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Int16 valid_range -32768, 2825;
+    }
+    MLE_Likelihood_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    MLE_Likelihood_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+    MLE_Likelihood_dim_2 {
+        String name "position";
+        String long_name "position of the ambiguities";
+    }
+    Num_Ambigs {
+        String long_name "Number of ambiguous wind vectors reported for a given cell";
+        String units "counts";
+        Float64 scale_factor 1;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 21;
+        Byte valid_range 0, 4;
+    }
+    Num_Ambigs_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    Num_Ambigs_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+}
diff --git a/unit-tests/dds-testsuite/S2000415.HDF.dds b/unit-tests/dds-testsuite/S2000415.HDF.dds
new file mode 100644
index 0000000..6eeadc8
--- /dev/null
+++ b/unit-tests/dds-testsuite/S2000415.HDF.dds
@@ -0,0 +1,35 @@
+Dataset {
+    Structure {
+        Int16 WVC_Lat[row = 458][WVC = 24];
+        UInt16 WVC_Lon[row = 458][WVC = 24];
+        Byte Num_Sigma0[row = 458][WVC = 24];
+        Byte Num_Beam_12[row = 458][WVC = 24];
+        Byte Num_Beam_34[row = 458][WVC = 24];
+        Byte Num_Beam_56[row = 458][WVC = 24];
+        Byte Num_Beam_78[row = 458][WVC = 24];
+        Byte WVC_Quality_Flag[row = 458][WVC = 24];
+        UInt16 Mean_Wind[row = 458][WVC = 24];
+        UInt16 Wind_Speed[row = 458][WVC = 24][position = 4];
+        UInt16 Wind_Dir[row = 458][WVC = 24][position = 4];
+        UInt16 Error_Speed[row = 458][WVC = 24][position = 4];
+        UInt16 Error_Dir[row = 458][WVC = 24][position = 4];
+        Int16 MLE_Likelihood[row = 458][WVC = 24][position = 4];
+        Byte Num_Ambigs[row = 458][WVC = 24];
+        Sequence {
+            Structure {
+                Int16 begin__0;
+            } begin;
+        } SwathIndex;
+        Sequence {
+            Structure {
+                String Mean_Time__0;
+            } Mean_Time;
+            Structure {
+                UInt32 Low_Wind_Speed_Flag__0;
+            } Low_Wind_Speed_Flag;
+            Structure {
+                UInt32 High_Wind_Speed_Flag__0;
+            } High_Wind_Speed_Flag;
+        } NSCAT%20L2;
+    } NSCAT%20Rev%2020;
+} S2000415.HDF;
diff --git a/unit-tests/dds-testsuite/S2000415.HDF.test1.das b/unit-tests/dds-testsuite/S2000415.HDF.test1.das
new file mode 100644
index 0000000..065d146
--- /dev/null
+++ b/unit-tests/dds-testsuite/S2000415.HDF.test1.das
@@ -0,0 +1,20 @@
+Attributes {
+    WVC_Lat {
+        String long_name "latitude";
+        String units "deg";
+        Float64 scale_factor 0.01;
+        Float64 scale_factor_err 0;
+        Float64 add_offset 0;
+        Float64 add_offset_err 0;
+        Int32 calibrated_nt 22;
+        Int16 valid_range -9000, 7771;
+    }
+    WVC_Lat_dim_0 {
+        String name "row";
+        String long_name "WVC row";
+    }
+    WVC_Lat_dim_1 {
+        String name "WVC";
+        String long_name "WVC index";
+    }
+}
diff --git a/unit-tests/dds-testsuite/coads_climatology.nc.das b/unit-tests/dds-testsuite/coads_climatology.nc.das
new file mode 100644
index 0000000..810bd57
--- /dev/null
+++ b/unit-tests/dds-testsuite/coads_climatology.nc.das
@@ -0,0 +1,50 @@
+Attributes {
+    COADSX {
+        String units "degrees_east";
+        String modulo " ";
+        String point_spacing "even";
+    }
+    COADSY {
+        String units "degrees_north";
+        String point_spacing "even";
+    }
+    TIME {
+        String units "hour since 0000-01-01 00:00:00";
+        String time_origin "1-JAN-0000 00:00:00";
+        String modulo " ";
+    }
+    SST {
+        Float32 missing_value -9.999999790e+33;
+        Float32 _FillValue -9.999999790e+33;
+        String long_name "SEA SURFACE TEMPERATURE";
+        String history "From coads_climatology";
+        String units "Deg C";
+    }
+    AIRT {
+        Float32 missing_value -9.999999790e+33;
+        Float32 _FillValue -9.999999790e+33;
+        String long_name "AIR TEMPERATURE";
+        String history "From coads_climatology";
+        String units "DEG C";
+    }
+    UWND {
+        Float32 missing_value -9.999999790e+33;
+        Float32 _FillValue -9.999999790e+33;
+        String long_name "ZONAL WIND";
+        String history "From coads_climatology";
+        String units "M/S";
+    }
+    VWND {
+        Float32 missing_value -9.999999790e+33;
+        Float32 _FillValue -9.999999790e+33;
+        String long_name "MERIDIONAL WIND";
+        String history "From coads_climatology";
+        String units "M/S";
+    }
+    NC_GLOBAL {
+        String history "FERRET V4.30 (debug/no GUI) 15-Aug-96";
+    }
+    DODS_EXTRA {
+        String Unlimited_Dimension "TIME";
+    }
+}
diff --git a/unit-tests/dds-testsuite/coads_climatology.nc.dds b/unit-tests/dds-testsuite/coads_climatology.nc.dds
new file mode 100644
index 0000000..5524a6b
--- /dev/null
+++ b/unit-tests/dds-testsuite/coads_climatology.nc.dds
@@ -0,0 +1,34 @@
+Dataset {
+    Grid {
+      Array:
+        Float32 SST[TIME = 12][COADSY = 90][COADSX = 180];
+      Maps:
+        Float64 TIME[TIME = 12];
+        Float64 COADSY[COADSY = 90];
+        Float64 COADSX[COADSX = 180];
+    } SST;
+    Grid {
+      Array:
+        Float32 AIRT[TIME = 12][COADSY = 90][COADSX = 180];
+      Maps:
+        Float64 TIME[TIME = 12];
+        Float64 COADSY[COADSY = 90];
+        Float64 COADSX[COADSX = 180];
+    } AIRT;
+    Grid {
+      Array:
+        Float32 UWND[TIME = 12][COADSY = 90][COADSX = 180];
+      Maps:
+        Float64 TIME[TIME = 12];
+        Float64 COADSY[COADSY = 90];
+        Float64 COADSX[COADSX = 180];
+    } UWND;
+    Grid {
+      Array:
+        Float32 VWND[TIME = 12][COADSY = 90][COADSX = 180];
+      Maps:
+        Float64 TIME[TIME = 12];
+        Float64 COADSY[COADSY = 90];
+        Float64 COADSX[COADSX = 180];
+    } VWND;
+} coads_climatology.nc;
diff --git a/unit-tests/dds-testsuite/config/unix.exp b/unit-tests/dds-testsuite/config/unix.exp
new file mode 100644
index 0000000..1c5c786
--- /dev/null
+++ b/unit-tests/dds-testsuite/config/unix.exp
@@ -0,0 +1,55 @@
+
+# Tcl/Expect code for the DDS test.
+
+# Make sure the global var DDSTEST is set correctly.
+
+global DDSTEST
+if ![info exists DDSTEST] then {
+    set DDSTEST [transform ./dds-test]
+}
+
+# The four required proc for dds-test.
+
+proc dds-test_start { options {ifile ""} {ofile ""}} {
+    global verbose
+    global DDSTEST
+    global comp_output
+    # spawn_id *MUST* be decalred as global for spawn to work in a proc!!
+    global spawn_id
+
+    if {$verbose >= 1} {
+	verbose "Starting ./$DDSTEST $options $ifile $ofile ...\n"
+	exp_internal 1
+    }
+
+    if {$ifile != ""} {
+	set ifile "< $ifile"
+    }
+
+    if {$ofile != ""} {
+	set ofile "> $ofile"
+    }
+
+    switch $options {
+	p {catch "exec $DDSTEST -p $ifile $ofile" comp_output}
+	s {spawn $DDSTEST -s}
+    }
+
+    if {$verbose >= 1} {
+	switch $options {
+	    p {send_user "Comp output:\n$comp_output\n"}
+	    s {send_user "Program running: spawn_id=$spawn_id\n"}
+	}
+    }
+}
+
+proc dds-test_load {} {
+}
+
+proc dds-test_exit {} {
+    send -raw ""
+}
+
+proc dds-test_version {} {
+    send_user "DDS testsuite version 1.2\n"
+}
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.1.exp b/unit-tests/dds-testsuite/dds-test.0/test.1.exp
new file mode 100644
index 0000000..47c2f86
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.1.exp
@@ -0,0 +1,51 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.1.exp,v $
+# Revision 1.4  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.2.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  1996/05/14 15:41:32  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:25  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.1
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Byte b;
+    Int32 i;
+    Int32 j;
+} data1;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.10.exp b/unit-tests/dds-testsuite/dds-test.0/test.10.exp
new file mode 100644
index 0000000..c428944
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.10.exp
@@ -0,0 +1,113 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.10.exp,v $
+# Revision 1.9  2003/05/16 00:15:57  jimg
+# Test changes because List has been removed from the DAP.
+#
+# Revision 1.8  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.7  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.6.6.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.6  1999/04/29 02:29:39  jimg
+# Merge of no-gnu branch
+#
+# Revision 1.5  1997/03/27 18:20:07  jimg
+# Update for version 2.13
+#
+# Revision 1.4  1996/05/14 15:41:33  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.3  1995/12/06  21:58:47  jimg
+# Removed `List List' variables.
+#
+# Revision 1.2  1995/01/19  22:05:20  jimg
+# Fixed for new class hierarchy.
+#
+# Revision 1.1  1994/12/21  17:01:26  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.10
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 i;
+        Int32 j;
+    } test;
+    Sequence {
+        Int32 i;
+        Int32 j\[10\];
+    } test2;
+    Grid {
+     ARRAY:
+        Float64 f\[10\]\[10\];
+     MAPS:
+        Int32 g\[10\];
+        Int32 h\[10\];
+    } test4;
+    Sequence {
+        String name;
+        Int32 age;
+    } person;
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f\[10\];
+        } data;
+    } exp;
+    Grid {
+     ARRAY:
+        Float64 g\[10\]\[10\]\[10\];
+     MAPS:
+        Float64 lat\[10\];
+        Float64 lon\[10\];
+        Float64 weirdness\[10\];
+    } strange;
+} data6;"
+
+dds-test_start p $srcdir/$test_name
+
+#send_user "comp_output: $comp_output\n"
+#send_user "test_out: $test_out\n"
+#send_user "Result of compare: [string compare $test_out $comp_output]\n"
+#send_user "Length of test_out: [string length $test_out]\n"
+#send_user "Length of comp_output: [string length $comp_output]\n"
+#
+#set test_out [string trim $test_out]
+#set comp_output [string trim $comp_output]
+#
+#send_user "Result of compare: [string compare $test_out $comp_output]\n"
+#send_user "Length of test_out: [string length $test_out]\n"
+#send_user "Length of comp_output: [string length $comp_output]\n"
+#send_user "Result of first: [string first $test_out $comp_output]\n"
+#send_user "Result of last: [string last $test_out $comp_output]\n"
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.11.exp b/unit-tests/dds-testsuite/dds-test.0/test.11.exp
new file mode 100644
index 0000000..a873cec
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.11.exp
@@ -0,0 +1,74 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.11.exp,v $
+# Revision 1.4  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.2.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  1996/05/14 15:41:34  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:27  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.11
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 long_one;
+        Int32 long_two;
+        Int32 long_three;
+        Int32 long_four;
+        Int32 long_five;
+        Int32 long_six;
+        Float64 long_one_float;
+        Float64 long_two_float;
+        Float64 long_three_float;
+    } long_names_one;
+    Structure {
+        Int32 long_one_float1;
+        Int32 long_two_float1;
+        Int32 long_three_float3;
+        Int32 long_four;
+        Int32 long_five;
+        Int32 long_six;
+        Float64 long_one_float;
+        Float64 long_two_float;
+        Float64 long_three_float;
+    } long_names_one_and_a_half;
+    Structure {
+        Int32 a_very_long_name_given_what_it_accomplishes;
+        Int32 another_name_nearly_as_pointless;
+    } long_names_two;
+} long_identifier_test_data_set;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.12.exp b/unit-tests/dds-testsuite/dds-test.0/test.12.exp
new file mode 100644
index 0000000..a30496d
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.12.exp
@@ -0,0 +1,53 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.12.exp,v $
+# Revision 1.5  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.4  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.3.38.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.3  1996/05/14 15:41:35  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.2  1995/03/16  17:44:44  jimg
+# Fixed spaces in variable name printout.
+#
+# Revision 1.1  1994/12/21  17:01:28  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.12
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i;
+    Float64 f\[latitude = 20\]\[longitude = 10\];
+} data5;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.13.exp b/unit-tests/dds-testsuite/dds-test.0/test.13.exp
new file mode 100644
index 0000000..87bd7c9
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.13.exp
@@ -0,0 +1,66 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.13.exp,v $
+# Revision 1.9  2002/05/23 01:29:05  jimg
+# Updated using code from C++.
+#
+# Revision 1.8  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.7  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.6  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.5.22.1  2000/06/15 02:24:57  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.5  1998/08/13 22:09:36  jimg
+# Fixed test after fixing misspelled error message.
+#
+# Revision 1.4  1997/03/27 18:20:08  jimg
+# Update for version 2.13
+#
+# Revision 1.3  1996/08/13 16:38:16  jimg
+# Fixed tests so that they match the output of the parser.
+#
+# Revision 1.2  1996/05/14 15:41:37  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:29  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.13
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Error parsing the text on line 5 at or near: 10
+In the dataset descriptor object:
+Expected an array subscript.
+
+"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    xfail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.14.exp b/unit-tests/dds-testsuite/dds-test.0/test.14.exp
new file mode 100644
index 0000000..85304cf
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.14.exp
@@ -0,0 +1,48 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.14.exp,v $
+# Revision 1.4  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.2.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  1996/05/14 15:41:38  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:31  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.14
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+} data5;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.15.exp b/unit-tests/dds-testsuite/dds-test.0/test.15.exp
new file mode 100644
index 0000000..ad6813f
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.15.exp
@@ -0,0 +1,54 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.15.exp,v $
+# Revision 1.3  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.2  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.1.10.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.1  1999/03/24 23:42:23  jimg
+# Added or updated for the new simple types (Int16, UInt16 and Float32)
+#
+# Revision 1.2  1996/05/14 15:41:38  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:31  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.15
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int16 x;
+    UInt16 y;
+    Float32 f;
+} data5;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.16.exp b/unit-tests/dds-testsuite/dds-test.0/test.16.exp
new file mode 100644
index 0000000..8080cf7
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.16.exp
@@ -0,0 +1,55 @@
+#
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Id: test.16.exp 11906 2005-08-08 19:51:43Z root $
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.16
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i.x\[10\];
+    Int32 j.x\[20\];
+    Byte b.x;
+    String name.x;
+    Structure {
+        Float64 f;
+        Float64 g;
+        Float64 h.x;
+    } x;
+    Grid {
+     ARRAY:
+        Byte temp\[100\]\[7\];
+     MAPS:
+        Float64 steps\[100\];
+        String colors\[7\];
+    } oddTemp.y;
+} data2;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+# $Log: test.16.exp,v $
+# Revision 1.2  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.1  2000/08/16 18:30:22  jimg
+# Added tests for dots in variable names and fancier error messages
+#
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.17.exp b/unit-tests/dds-testsuite/dds-test.0/test.17.exp
new file mode 100644
index 0000000..77c8d49
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.17.exp
@@ -0,0 +1,68 @@
+#
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Id: test.17.exp 11906 2005-08-08 19:51:43Z root $
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.17
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "Error parsing the text on line 8 at or near: Map
+In the dataset descriptor object: Expected a variable declaration
+(e.g., Int32 i;).
+"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    xfail "$test_name"
+}
+
+# $Log: test.17.exp,v $
+# Revision 1.5  2002/05/23 01:29:05  jimg
+# Updated using code from C++.
+#
+# Revision 1.3.4.2  2001/11/01 00:43:52  jimg
+# Fixes to the scanners and parsers so that dataset variable names may
+# start with digits. I've expanded the set of characters that may appear
+# in a variable name and made it so that all except `#' may appear at
+# the start. Some characters are not allowed in variables that appear in
+# a DDS or CE while they are allowed in the DAS. This makes it possible
+# to define containers with names like `COARDS:long_name.' Putting a colon
+# in a variable name makes the CE parser much more complex. Since the set
+# of characters that people want seems pretty limited (compared to the
+# complete ASCII set) I think this is an OK approach. If we have to open
+# up the expr.lex scanner completely, then we can but not without adding
+# lots of action clauses to teh parser. Note that colon is just an example,
+# there's a host of characters that are used in CEs that are not allowed
+# in IDs.
+#
+# Revision 1.4  2001/08/24 17:46:24  jimg
+# Resolved conflicts from the merge of release 3.2.6
+#
+# Revision 1.3.4.1  2001/06/23 00:52:32  jimg
+# Added tests for `#' in IDs.
+#
+# Revision 1.3  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.2  2000/09/22 02:52:59  jimg
+# Fixes to the tests to recognize some of the new error messages. Also,
+# the test drivers were modified to catch the exceptions now thrown by
+# some of the parsers.
+#
+# Revision 1.1  2000/08/16 18:30:22  jimg
+# Added tests for dots in variable names and fancier error messages
+#
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.18.exp b/unit-tests/dds-testsuite/dds-test.0/test.18.exp
new file mode 100644
index 0000000..d17b710
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.18.exp
@@ -0,0 +1,46 @@
+#
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Id: test.18.exp 11906 2005-08-08 19:51:43Z root $
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.18
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Grid {
+     ARRAY:
+        Byte temp\[100\]\[7\];
+     MAPS:
+        Float64 steps\[100\];
+        String colors\[7\];
+    } oddTemp;
+} 123;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+# $Log: test.18.exp,v $
+# Revision 1.2  2001/06/15 23:49:06  jimg
+# Merged with release-3-2-4.
+#
+# Revision 1.1.2.1  2001/05/08 19:11:50  jimg
+# Added test for integer dataset names.
+#
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.19.exp b/unit-tests/dds-testsuite/dds-test.0/test.19.exp
new file mode 100644
index 0000000..0d7117b
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.19.exp
@@ -0,0 +1,54 @@
+#
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Id: test.19.exp 11906 2005-08-08 19:51:43Z root $
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.19
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 a;
+    Int32 b%23c\[10\];
+    Float64 c%23d;
+    Grid {
+     ARRAY:
+        Byte Image%23data\[512\];
+     MAPS:
+        String colors\[512\];
+    } huh;
+} test.19;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+# $Log: test.19.exp,v $
+# Revision 1.2  2001/08/24 17:46:24  jimg
+# Resolved conflicts from the merge of release 3.2.6
+#
+# Revision 1.1.2.2  2001/07/28 01:12:28  jimg
+# Updated to work with the new escaping code. Some of our tests assumed
+# that dashes (-) were not OK in symbol names. However, changes in the
+# DAP parsers along with changes in the escaping functions now make this
+# possible.
+#
+# Revision 1.1.2.1  2001/06/23 00:52:32  jimg
+# Added tests for `#' in IDs.
+#
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.2.exp b/unit-tests/dds-testsuite/dds-test.0/test.2.exp
new file mode 100644
index 0000000..b29032f
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.2.exp
@@ -0,0 +1,50 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.2.exp,v $
+# Revision 1.4  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.2.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  1996/05/14 15:41:39  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:32  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.2
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i\[10\];
+    Int32 j\[20\];
+} data2;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.20.exp b/unit-tests/dds-testsuite/dds-test.0/test.20.exp
new file mode 100644
index 0000000..27186e5
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.20.exp
@@ -0,0 +1,50 @@
+#
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Id: test.20.exp 11906 2005-08-08 19:51:43Z root $
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.20
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 a;
+    Grid {
+     ARRAY:
+        Byte Image%23data\[size*10 = 512\];
+     MAPS:
+        String colors\[size*10 = 512\];
+    } huh;
+} test.20;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+# $Log: test.20.exp,v $
+# Revision 1.2  2003/01/10 19:46:43  jimg
+# Merged with code tagged release-3-2-10 on the release-3-2 branch. In many
+# cases files were added on that branch (so they appear on the trunk for
+# the first time).
+#
+# Revision 1.1.2.2  2002/06/11 00:39:01  jimg
+# Fixed...
+#
+# Revision 1.1.2.1  2002/06/11 00:38:06  jimg
+# Added
+#
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.3.exp b/unit-tests/dds-testsuite/dds-test.0/test.3.exp
new file mode 100644
index 0000000..b69f043
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.3.exp
@@ -0,0 +1,50 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.3.exp,v $
+# Revision 1.4  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.3  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.2.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.2  1996/05/14 15:41:42  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.1  1994/12/21  17:01:33  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.3
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i\[10\];
+    Float64 f\[20\];
+} data3;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.4.exp b/unit-tests/dds-testsuite/dds-test.0/test.4.exp
new file mode 100644
index 0000000..d13738d
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.4.exp
@@ -0,0 +1,58 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.4.exp,v $
+# Revision 1.6  2003/05/16 00:15:57  jimg
+# Test changes because List has been removed from the DAP.
+#
+# Revision 1.5  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.4  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.3.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.3  1996/05/14 15:41:43  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.2  1995/01/19  22:05:21  jimg
+# Fixed for new class hierarchy.
+#
+# Revision 1.1  1994/12/21  17:01:34  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.4
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Int32 i;
+    Byte b;
+    String s;
+    Url u;
+} data4;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.6.exp b/unit-tests/dds-testsuite/dds-test.0/test.6.exp
new file mode 100644
index 0000000..c40782e
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.6.exp
@@ -0,0 +1,58 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.6.exp,v $
+# Revision 1.6  2003/05/16 00:15:57  jimg
+# Test changes because List has been removed from the DAP.
+#
+# Revision 1.5  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.4  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.3.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.3  1996/05/14 15:41:46  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.2  1995/12/06  21:58:50  jimg
+# Removed `List List' variables.
+#
+# Revision 1.1  1994/12/21  17:01:37  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.6
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 i;
+    } exp;
+} data6;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.7.exp b/unit-tests/dds-testsuite/dds-test.0/test.7.exp
new file mode 100644
index 0000000..e9197eb
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.7.exp
@@ -0,0 +1,65 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.7.exp,v $
+# Revision 1.7  2003/05/16 00:15:57  jimg
+# Test changes because List has been removed from the DAP.
+#
+# Revision 1.6  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.5  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.4.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.4  1996/05/14 15:41:47  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.3  1995/12/06  21:58:51  jimg
+# Removed `List List' variables.
+#
+# Revision 1.2  1995/01/19  22:05:23  jimg
+# Fixed for new class hierarchy.
+#
+# Revision 1.1  1994/12/21  17:01:39  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.7
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f\[10\];
+        } data;
+    } exp;
+} data6;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.8.exp b/unit-tests/dds-testsuite/dds-test.0/test.8.exp
new file mode 100644
index 0000000..87af129
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.8.exp
@@ -0,0 +1,69 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.8.exp,v $
+# Revision 1.7  2003/05/16 00:15:57  jimg
+# Test changes because List has been removed from the DAP.
+#
+# Revision 1.6  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.5  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.4.38.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.4  1996/05/14 15:41:49  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.3  1995/12/06  21:58:54  jimg
+# Removed `List List' variables.
+#
+# Revision 1.2  1995/01/19  22:05:24  jimg
+# Fixed for new class hierarchy.
+#
+# Revision 1.1  1994/12/21  17:01:40  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.8
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Sequence {
+        String name;
+        Int32 age;
+    } person;
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f\[10\];
+        } data;
+    } exp;
+} data6;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/dds-test.0/test.9.exp b/unit-tests/dds-testsuite/dds-test.0/test.9.exp
new file mode 100644
index 0000000..0e6d098
--- /dev/null
+++ b/unit-tests/dds-testsuite/dds-test.0/test.9.exp
@@ -0,0 +1,80 @@
+# expect/tcl code to test the dds parser and scanner
+# jhrg
+#
+# $Log: test.9.exp,v $
+# Revision 1.8  2003/05/16 00:15:57  jimg
+# Test changes because List has been removed from the DAP.
+#
+# Revision 1.7  2000/10/03 22:18:04  jimg
+# Fixes to the tests to accomodate debugging fixes in DDS.cc
+#
+# Revision 1.6  2000/06/16 18:15:01  jimg
+# Merged with 3.1.7
+#
+# Revision 1.5.2.1  2000/06/15 02:24:58  jimg
+# Fixed the tests: problems with PATH, etc. broke the tests on my new machine
+#
+# Revision 1.5  1999/07/22 17:08:17  jimg
+# *** empty log message ***
+#
+# Revision 1.4  1996/05/14 15:41:50  jimg
+# These changes have already been checked in once before. However, I
+# corrupted the source repository and restored it from a 5/9/96 backup
+# tape. The previous version's log entry should cover the changes.
+#
+# Revision 1.3  1995/12/06  21:58:55  jimg
+# Removed `List List' variables.
+#
+# Revision 1.2  1995/01/19  22:05:25  jimg
+# Fixed for new class hierarchy.
+#
+# Revision 1.1  1994/12/21  17:01:41  jimg
+# Added these to the testsuite.
+#
+
+global comp_output		# contains output from dds-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+
+# The variable `test_name' is the name of the das input file for this test.
+
+set test_name test.9
+
+# The variable `test_out' is a string that contains the text that should be
+# stored in comp_output by das-test_start. The two strings should match
+# exactly.
+
+set test_out "DDS past semantic check
+DDS past full semantic check
+Dataset {
+    Sequence {
+        String name;
+        Int32 age;
+    } person;
+    Structure {
+        Int32 j;
+        Int32 i;
+        Structure {
+            Int32 i;
+            Float64 f\[10\];
+        } data;
+    } exp;
+    Grid {
+     ARRAY:
+        Float64 g\[10\]\[10\]\[10\];
+     MAPS:
+        Float64 lat\[10\];
+        Float64 lon\[10\];
+        Float64 weirdness\[10\];
+    } strange;
+} data6;"
+
+dds-test_start p $srcdir/$test_name
+
+if ![string compare $test_out $comp_output] { # check comp_output
+    pass "$test_name"
+} else {
+    fail "$test_name"
+}
+
+
diff --git a/unit-tests/dds-testsuite/fnoc1.nc.das b/unit-tests/dds-testsuite/fnoc1.nc.das
new file mode 100644
index 0000000..0407143
--- /dev/null
+++ b/unit-tests/dds-testsuite/fnoc1.nc.das
@@ -0,0 +1,32 @@
+Attributes {
+    u {
+        String units "meter per second";
+        String long_name "Vector wind eastward component";
+        String missing_value "-32767";
+        String scale_factor "0.005";
+        String DODS_Name "UWind";
+    }
+    v {
+        String units "meter per second";
+        String long_name "Vector wind northward component";
+        String missing_value "-32767";
+        String scale_factor "0.005";
+        String DODS_Name "VWind";
+    }
+    lat {
+        String units "degree North";
+    }
+    lon {
+        String units "degree East";
+    }
+    time {
+        String units "hours from base_time";
+    }
+    NC_GLOBAL {
+        String base_time "88- 10-00:00:00";
+        String title " FNOC UV wind components from 1988- 10 to 1988- 13.";
+    }
+    DODS_EXTRA {
+        String Unlimited_Dimension "time_a";
+    }
+}
diff --git a/unit-tests/dds-testsuite/fnoc1.nc.dds b/unit-tests/dds-testsuite/fnoc1.nc.dds
new file mode 100644
index 0000000..8c41e1b
--- /dev/null
+++ b/unit-tests/dds-testsuite/fnoc1.nc.dds
@@ -0,0 +1,7 @@
+Dataset {
+    Int16 u[time_a = 16][lat = 17][lon = 21];
+    Int16 v[time_a = 16][lat = 17][lon = 21];
+    Float32 lat[lat = 17];
+    Float32 lon[lon = 21];
+    Float32 time[time = 16];
+} fnoc1.nc;
diff --git a/unit-tests/dds-testsuite/hdf_dimension_attribute_grid.das b/unit-tests/dds-testsuite/hdf_dimension_attribute_grid.das
new file mode 100644
index 0000000..6840800
--- /dev/null
+++ b/unit-tests/dds-testsuite/hdf_dimension_attribute_grid.das
@@ -0,0 +1,12 @@
+Attributes {
+    g {
+        String long_name "test_varaible";
+    }
+    
+    g_dim_0 {
+    	String long_name "test_first_dimension";
+    }
+    g_dim_1 {
+    	String long_name "test_second_dimension";
+    }
+}
diff --git a/unit-tests/dds-testsuite/hdf_dimension_attribute_grid.dds b/unit-tests/dds-testsuite/hdf_dimension_attribute_grid.dds
new file mode 100644
index 0000000..2e08696
--- /dev/null
+++ b/unit-tests/dds-testsuite/hdf_dimension_attribute_grid.dds
@@ -0,0 +1,11 @@
+# Used for the find_hdf4_dimension_attribute_home unit tests.
+
+dataset {
+    Grid {
+      array:
+        Byte xy[x=12][y=12];
+      maps:
+        Float64 x[12];
+	Float64 y[12];
+    } g;
+} ascii_output_test;
diff --git a/unit-tests/dds-testsuite/test.1 b/unit-tests/dds-testsuite/test.1
new file mode 100644
index 0000000..465ac61
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.1
@@ -0,0 +1,7 @@
+dataset {
+    Byte b;
+    int32 i;
+    int32 j;
+} data1;
+
+
diff --git a/unit-tests/dds-testsuite/test.10 b/unit-tests/dds-testsuite/test.10
new file mode 100644
index 0000000..db4c7eb
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.10
@@ -0,0 +1,45 @@
+# -*- C++ -*-
+
+dataset {
+    structure {
+	Int32 i;
+	int32 j;
+    } test;
+
+    sequence {
+	int32 i;
+	int32 j[10];
+    } test2;
+
+    grid {
+      array:
+	float64 f[10][10];
+      maps:
+	int32 g[10];
+	int32 h[10];
+    } test4;
+
+    Sequence {
+	String name;
+	Int32 age;
+    } person;
+
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+
+    Grid {
+      Array:
+	float64 g[10][10][10];
+      Maps:
+	float64 lat[10];
+	float64 lon[10];
+	float64 weirdness[10];
+    } strange;
+
+} data6;
diff --git a/unit-tests/dds-testsuite/test.11 b/unit-tests/dds-testsuite/test.11
new file mode 100644
index 0000000..9b863cf
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.11
@@ -0,0 +1,37 @@
+# -*- C++ -*-
+
+# Test identifier length
+
+dataset {
+    structure {
+	int32 long_one;
+	int32 long_two;
+	int32 long_three;
+	int32 long_four;
+	int32 long_five;
+	int32 long_six;
+	float64 long_one_float;
+	float64 long_two_float;
+	float64 long_three_float;
+    } long_names_one;
+    
+    structure {
+	int32 long_one_float1;
+	int32 long_two_float1;
+	int32 long_three_float3;
+	int32 long_four;
+	int32 long_five;
+	int32 long_six;
+	float64 long_one_float;
+	float64 long_two_float;
+	float64 long_three_float;
+    } long_names_one_and_a_half;
+ 
+    structure {
+	int32 a_very_long_name_given_what_it_accomplishes;
+	int32 another_name_nearly_as_pointless;
+    } long_names_two;
+
+    
+} long_identifier_test_data_set;
+
diff --git a/unit-tests/dds-testsuite/test.12 b/unit-tests/dds-testsuite/test.12
new file mode 100644
index 0000000..131dfb6
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.12
@@ -0,0 +1,6 @@
+# test arrays with named dimensions.
+
+dataset {
+    int32 i;
+    float64 f[latitude=20][ longitude = 10 ];
+} data5;
diff --git a/unit-tests/dds-testsuite/test.13 b/unit-tests/dds-testsuite/test.13
new file mode 100644
index 0000000..bd400aa
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.13
@@ -0,0 +1,6 @@
+# test problems with named dimensions.
+
+dataset {
+    int32 i;
+    float64 f[ longitude 10 ];
+} data5;
diff --git a/unit-tests/dds-testsuite/test.14 b/unit-tests/dds-testsuite/test.14
new file mode 100644
index 0000000..4ceac1d
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.14
@@ -0,0 +1,4 @@
+# test null dataset
+
+dataset {
+} data5;
diff --git a/unit-tests/dds-testsuite/test.15 b/unit-tests/dds-testsuite/test.15
new file mode 100644
index 0000000..31fa2f5
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.15
@@ -0,0 +1,8 @@
+#
+# Test new datatypes (int16, uint16, float32)
+
+Dataset {
+    int16 x;
+    uint16 y;
+    float32 f;
+} data5;
diff --git a/unit-tests/dds-testsuite/test.16 b/unit-tests/dds-testsuite/test.16
new file mode 100644
index 0000000..61a360f
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.16
@@ -0,0 +1,21 @@
+#
+# Test dots (.) in variable names.
+
+Dataset {
+    Int32 i.x[10];
+    Int32 j.x[20];
+    Byte b.x;
+    String name.x;
+    Structure {
+        Float64 f;
+	Float64 g;
+	Float64 h.x;
+    } x;
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Maps:
+        Float64 steps[100];
+	String colors[7];
+    } oddTemp.y;
+} data2;
diff --git a/unit-tests/dds-testsuite/test.17 b/unit-tests/dds-testsuite/test.17
new file mode 100644
index 0000000..ef53e89
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.17
@@ -0,0 +1,12 @@
+#
+# Test error messages; When `Maps' is misspelled.
+
+Dataset {
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Map:
+        Float64 steps[100];
+	String colors[7];
+    } oddTemp;
+} data2;
diff --git a/unit-tests/dds-testsuite/test.18 b/unit-tests/dds-testsuite/test.18
new file mode 100644
index 0000000..ca4e7a4
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.18
@@ -0,0 +1,12 @@
+#
+# Test dataset filenames that are numbers.
+
+Dataset {
+    Grid {
+      Array:
+        Byte temp[100][7];
+      Maps:
+        Float64 steps[100];
+	String colors[7];
+    } oddTemp;
+} 123;
diff --git a/unit-tests/dds-testsuite/test.19 b/unit-tests/dds-testsuite/test.19
new file mode 100644
index 0000000..b87cca0
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19
@@ -0,0 +1,14 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+   Int32 b#c[10];
+   Float64 c#d;
+   Grid {
+     Array:
+       Byte Image#data[512];
+     Maps:
+       String colors[512];
+   } huh;
+} test.19;
diff --git a/unit-tests/dds-testsuite/test.19b b/unit-tests/dds-testsuite/test.19b
new file mode 100644
index 0000000..6d05cf7
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19b
@@ -0,0 +1,14 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+   Int32 b#c[10];
+   Float64 c%20d;
+   Grid {
+     Array:
+       Byte Image#data[512];
+     Maps:
+       String colors[512];
+   } huh;
+} test.19;
diff --git a/unit-tests/dds-testsuite/test.19b.das b/unit-tests/dds-testsuite/test.19b.das
new file mode 100644
index 0000000..d60630d
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19b.das
@@ -0,0 +1,33 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    NC_GLOBAL {
+        String long_name "Attribute merge test";
+        Int32 primes 2, 3, 5, 7, 11;
+    }
+
+    a {
+    }
+
+    b#c {
+        String long_name "b pound c";
+    }
+
+    c%20d {
+        String long_name "c d with a WWW escape sequence";
+	sub {
+	    String about "Attributes inside attributes";
+	    Float64 pi 3.1415;
+        }
+    }
+
+    huh {
+        String long_name "The Grid huh";
+	    colors {
+	        String long_name "The color map vector";
+        }
+	    Image#data {
+	    }
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19c b/unit-tests/dds-testsuite/test.19c
new file mode 100644
index 0000000..aeadda8
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19c
@@ -0,0 +1,6 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+} test.19c;
diff --git a/unit-tests/dds-testsuite/test.19c.das b/unit-tests/dds-testsuite/test.19c.das
new file mode 100644
index 0000000..a68eb99
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19c.das
@@ -0,0 +1,12 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    NC_GLOBAL {
+        String long_name "Attribute merge test";
+        Int32 primes 2, 3, 5, 7, 11;
+    }
+
+    a {
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19d b/unit-tests/dds-testsuite/test.19d
new file mode 100644
index 0000000..39ab9a2
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19d
@@ -0,0 +1,6 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 b#c[10];
+} test.19d;
diff --git a/unit-tests/dds-testsuite/test.19d.das b/unit-tests/dds-testsuite/test.19d.das
new file mode 100644
index 0000000..544c7f0
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19d.das
@@ -0,0 +1,8 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    b#c {
+        String long_name "b pound c";
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19d1.das b/unit-tests/dds-testsuite/test.19d1.das
new file mode 100644
index 0000000..2708a76
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19d1.das
@@ -0,0 +1,11 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    b#c {
+        String long_name "b pound c";
+    }
+    b#c_dim_0 {
+        Float64 add_offset 0.125;
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19e b/unit-tests/dds-testsuite/test.19e
new file mode 100644
index 0000000..6fe1619
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19e
@@ -0,0 +1,6 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Float64 c%20d;
+} test.19e;
diff --git a/unit-tests/dds-testsuite/test.19e.das b/unit-tests/dds-testsuite/test.19e.das
new file mode 100644
index 0000000..91ef182
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19e.das
@@ -0,0 +1,12 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    c%20d {
+        String long_name "c d with a WWW escape sequence";
+	    sub {
+	        String about "Attributes inside attributes";
+	        Float64 pi 3.1415;
+        }
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19f b/unit-tests/dds-testsuite/test.19f
new file mode 100644
index 0000000..ecc435a
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19f
@@ -0,0 +1,11 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   Grid {
+     Array:
+       Byte Image#data[512];
+     Maps:
+       String colors[512];
+   } huh;
+} test.19f;
diff --git a/unit-tests/dds-testsuite/test.19f.das b/unit-tests/dds-testsuite/test.19f.das
new file mode 100644
index 0000000..2d75fce
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19f.das
@@ -0,0 +1,13 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    huh {
+        String long_name "The Grid huh";
+	colors {
+	    String long_name2 "The color map vector";
+        }
+	Image#data {
+	}
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19f1.das b/unit-tests/dds-testsuite/test.19f1.das
new file mode 100644
index 0000000..e8a7038
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19f1.das
@@ -0,0 +1,16 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+    huh {
+        String long_name "The Grid huh";
+	colors {
+	    String long_name2 "The color map vector";
+        }
+	Image#data {
+	}
+    }
+    huh_dim_0 {
+        String units "m/s";
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.19g b/unit-tests/dds-testsuite/test.19g
new file mode 100644
index 0000000..c5f6211
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19g
@@ -0,0 +1,14 @@
+#
+# Test identifiers with `#' in them. 6/22/2001 jhrg
+
+Dataset {
+   	Structure {
+   		Int32 b#c[10];
+   		Grid {
+     		Array:
+       		Byte Image#data[512];
+     		Maps:
+       		String colors[512];
+   		} huh;
+   } s;
+} test.19;
diff --git a/unit-tests/dds-testsuite/test.19g.das b/unit-tests/dds-testsuite/test.19g.das
new file mode 100644
index 0000000..40e1273
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.19g.das
@@ -0,0 +1,23 @@
+# This DAS is used to test merging attributes into an existing DDS. It's
+# designed to work with the DDS in test.19b.
+
+Attributes {
+
+    b#c {
+        String long_name "b pound c";
+    }
+    b#c_dim_0 {
+        Float64 add_offset 0.125;
+    }
+    huh {
+        String long_name "The Grid huh";
+		colors {
+	    	String long_name2 "The color map vector";
+        }
+		Image#data {
+		}
+    }
+    huh_dim_0 {
+        String units "m/s";
+    }
+}
diff --git a/unit-tests/dds-testsuite/test.2 b/unit-tests/dds-testsuite/test.2
new file mode 100644
index 0000000..f262371
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.2
@@ -0,0 +1,4 @@
+Dataset {
+    Int32 i[10];
+    Int32 j[20];
+} data2;
diff --git a/unit-tests/dds-testsuite/test.20 b/unit-tests/dds-testsuite/test.20
new file mode 100644
index 0000000..c02f7bb
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.20
@@ -0,0 +1,12 @@
+#
+# Test identifiers with '*' in them. 6/22/2001 jhrg
+
+Dataset {
+   Int32 a;
+   Grid {
+     Array:
+       Byte Image#data[size*10=512];
+     Maps:
+       String colors[size*10=512];
+   } huh;
+} test.20;
diff --git a/unit-tests/dds-testsuite/test.3 b/unit-tests/dds-testsuite/test.3
new file mode 100644
index 0000000..11491a7
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.3
@@ -0,0 +1,4 @@
+Dataset {
+    Int32 i[10];
+    Float64 f[20];
+} data3;
diff --git a/unit-tests/dds-testsuite/test.4 b/unit-tests/dds-testsuite/test.4
new file mode 100644
index 0000000..0f69969
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.4
@@ -0,0 +1,6 @@
+dataset {
+    int32 i;
+    byte b;
+    String s;
+    url u;
+} data4;
diff --git a/unit-tests/dds-testsuite/test.6 b/unit-tests/dds-testsuite/test.6
new file mode 100644
index 0000000..1b9285d
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.6
@@ -0,0 +1,6 @@
+dataset {
+    Structure {
+	Int32 j;
+	Int32 i;
+    } exp;
+} data6;
diff --git a/unit-tests/dds-testsuite/test.7 b/unit-tests/dds-testsuite/test.7
new file mode 100644
index 0000000..325934a
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.7
@@ -0,0 +1,10 @@
+dataset {
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+} data6;
diff --git a/unit-tests/dds-testsuite/test.8 b/unit-tests/dds-testsuite/test.8
new file mode 100644
index 0000000..a19c747
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.8
@@ -0,0 +1,14 @@
+dataset {
+    Sequence {
+	String name;
+	Int32 age;
+    } person;
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+} data6;
diff --git a/unit-tests/dds-testsuite/test.9 b/unit-tests/dds-testsuite/test.9
new file mode 100644
index 0000000..335d15f
--- /dev/null
+++ b/unit-tests/dds-testsuite/test.9
@@ -0,0 +1,22 @@
+dataset {
+    Sequence {
+	String name;
+	Int32 age;
+    } person;
+    Structure {
+	Int32 j;
+	Int32 i;
+	Structure {
+	    int32 i;
+	    float64 f[10];
+	} data;
+    } exp;
+    Grid {
+      Array:
+	float64 g[10][10][10];
+      Maps:
+	float64 lat[10];
+	float64 lon[10];
+	float64 weirdness[10];
+    } strange;
+} data6;
diff --git a/unit-tests/ddsT.cc b/unit-tests/ddsT.cc
new file mode 100644
index 0000000..2f703f2
--- /dev/null
+++ b/unit-tests/ddsT.cc
@@ -0,0 +1,630 @@
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include <iostream>
+#include <fstream>
+#include <sstream>
+
+// #define DODS_DEBUG
+
+#include "DDS.h"
+//#include "Pix.h"
+#include "Byte.h"
+#include "Int16.h"
+#include "UInt16.h"
+#include "Int32.h"
+#include "UInt32.h"
+#include "Float32.h"
+#include "Float64.h"
+#include "Str.h"
+#include "Url.h"
+#include "Array.h"
+#include "Structure.h"
+#include "Sequence.h"
+#include "Grid.h"
+
+#include "TestArray.h"
+#include "TestInt16.h"
+#include "TestStr.h"
+#include "TestTypeFactory.h"
+#include "ce_functions.h"
+#include "util.h"
+#include "debug.h"
+
+#include "testFile.cc"
+
+using namespace std;
+using namespace libdap;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts.
+string cprint = "\
+Dataset {\n\
+    Int16 var1;\n\
+    String var6;\n\
+    Int16 var7;\n\
+    Structure {\n\
+        Structure {\n\
+            Int16 var10;\n\
+        } var9;\n\
+    } var8;\n\
+} Test%20Data%20Set;\n\
+" ;
+
+string pprint = "\
+Dataset {\n\
+    Int16 var1;\n\
+    String var6;\n\
+    Int16 var7;\n\
+} Test%20Data%20Set;\n\
+" ;
+
+string nprint = "\
+Dataset {\n\
+} Test%20Data%20Set;\n\
+" ;
+
+string containerprint = "\
+Dataset {\n\
+    Structure {\n\
+        Int16 c1var1;\n\
+        Int16 c1var3;\n\
+    } c1;\n\
+    Structure {\n\
+        String c2var2;\n\
+        Structure {\n\
+            Structure {\n\
+                Int16 c2var3var1var1;\n\
+                Int16 c2var3var1var2;\n\
+            } c2var3var1;\n\
+        } c2var3;\n\
+    } c2;\n\
+    Byte var1;\n\
+    Float64 var2;\n\
+} TestDDS;\n\
+" ;
+
+
+class ddsT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( ddsT ) ;
+CPPUNIT_TEST( ddsT_test ) ;
+CPPUNIT_TEST( ddsT_containers ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+private:
+    /* TEST PRIVATE DATA */
+    TestTypeFactory *factory;
+
+public:
+    void setUp()
+    {
+        factory = new TestTypeFactory;
+    }
+
+    void tearDown()
+    {
+        delete factory; factory = 0;
+    }
+
+    void ddsT_test()
+    {
+	DDS dds( factory, "TestDDS" ) ;
+
+	string dsn = dds.get_dataset_name() ;
+	CPPUNIT_ASSERT( dsn == "TestDDS" ) ;
+
+	dds.set_dataset_name( "Test Data Set" ) ;
+	dsn = dds.get_dataset_name() ;
+	CPPUNIT_ASSERT( dsn == "Test Data Set" ) ;
+
+	string fn = dds.filename() ;
+	CPPUNIT_ASSERT( fn == "" ) ;
+
+	dds.filename( "dds_test.data" ) ;
+	fn = dds.filename() ;
+	CPPUNIT_ASSERT( fn == "dds_test.data" ) ;
+
+	try
+	{
+	    dds.add_var( (BaseType *)NULL ) ;
+	    CPPUNIT_FAIL( "succeeded in adding a null var" ) ;
+	}
+	catch( InternalErr &e )
+	{
+	}
+
+	try
+	{
+	    BaseType *bt = factory->NewInt16( "var1" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewInt16( "var2" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewInt16( "var3" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewInt16( "var4" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewInt16( "var5" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewStr( "var6" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewArray( "var7", factory->NewInt16( "" ) ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewStructure( "var8" ) ;
+	    Structure *s = (Structure *)bt ;
+	    BaseType *bts1 = factory->NewStructure( "var9" ) ;
+	    Structure *s1 = (Structure *)bts1 ;
+	    BaseType *bts2 = factory->NewInt16( "var10" ) ;
+	    s1->add_var( bts2 ) ;
+	    delete bts2 ; bts2 = 0 ;
+	    s->add_var( bts1 ) ;
+	    delete bts1 ; bts1 = 0 ;
+	    dds.add_var( bt ) ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "failed to add a var" ) ;
+	}
+
+	int nv = dds.num_var() ;
+	CPPUNIT_ASSERT( nv == 8 ) ;
+
+	vector<string> vs ;
+	typedef std::vector<string>::const_iterator vs_citer ;
+	typedef std::vector<string>::iterator vs_iter ;
+	vs.push_back( "var1" ) ;
+	vs.push_back( "var2" ) ;
+	vs.push_back( "var3" ) ;
+	vs.push_back( "var4" ) ;
+	vs.push_back( "var5" ) ;
+	vs.push_back( "var6" ) ;
+	vs.push_back( "var7" ) ;
+	vs.push_back( "var8" ) ;
+
+	DDS::Vars_iter dvsc = dds.var_begin() ;
+	vs_citer vsc = vs.begin() ;
+	for( ; dvsc != dds.var_end() && vsc != vs.end(); dvsc++, vsc++ )
+	{
+	    CPPUNIT_ASSERT( (*dvsc)->name() == *vsc ) ;
+	}
+	CPPUNIT_ASSERT( dvsc == dds.var_end() && vsc == vs.end() ) ;
+	if( dvsc != dds.var_end() && vsc == vs.end() )
+	{
+	    CPPUNIT_FAIL( "Too many vars" ) ;
+	}
+	else if( dvsc == dds.var_end() && vsc != vs.end() )
+	{
+	    CPPUNIT_FAIL( "Too few vars" ) ;
+	}
+
+	for( vsc = vs.begin(); vsc != vs.end(); vsc++ )
+	{
+	    if( *vsc == "var2" )
+	    {
+		vs_iter &vsi = (vs_iter &)vsc ;
+		vs.erase( vsi ) ;
+		break ;
+	    }
+	}
+
+        dvsc = dds.var_begin() ;
+        vsc = vs.begin() ;
+        for( ; dvsc != dds.var_end() && vsc != vs.end(); dvsc++, vsc++ )
+        {
+            if( (*dvsc)->name() == "var2" )
+            {
+                DDS::Vars_iter &dvsi = (DDS::Vars_iter &)dvsc ;
+                dds.del_var( dvsi ) ;
+            }
+            CPPUNIT_ASSERT( (*dvsc)->name() == *vsc ) ;
+        }
+
+	nv = dds.num_var() ;
+	CPPUNIT_ASSERT( nv == 7 ) ;
+	if( nv != 7 )
+	{
+	    for( dvsc = dds.var_begin(); dvsc != dds.var_end(); dvsc++ )
+	    {
+		DBG2( cerr << "    " << (*dvsc)->name() << endl ) ;
+	    }
+	}
+
+	for( vsc = vs.begin(); vsc != vs.end(); vsc++ )
+	{
+	    if( *vsc == "var3" )
+	    {
+		vs_iter &vsi = (vs_iter &)vsc ;
+		vs.erase( vsi ) ;
+		break ;
+	    }
+	}
+	dvsc = dds.var_begin() ;
+	vsc = vs.begin() ;
+	for( ; dvsc != dds.var_end() && vsc != vs.end(); dvsc++, vsc++ )
+	{
+	    if( (*dvsc)->name() == "var3" )
+	    {
+		DDS::Vars_iter &dvsi = (DDS::Vars_iter &)dvsc ;
+		dds.del_var( dvsi ) ;
+	    }
+	    CPPUNIT_ASSERT( (*dvsc)->name() == *vsc ) ;
+	}
+
+	nv = dds.num_var() ;
+	CPPUNIT_ASSERT( nv == 6 ) ;
+	if( nv != 6 )
+	{
+	    for( dvsc = dds.var_begin(); dvsc != dds.var_end(); dvsc++ )
+	    {
+		DBG2( cerr << "    " << (*dvsc)->name() << endl ) ;
+	    }
+	}
+
+	for( vsc = vs.begin(); vsc != vs.end(); vsc++ )
+	{
+	    if( *vsc == "var4" )
+	    {
+		vs_citer vsc2 = vsc ;
+		vsc2++ ;
+		vsc2++ ;
+		vs_iter &vsi = (vs_iter &)vsc ;
+		vs_iter &vsi2 = (vs_iter &)vsc2 ;
+		vs.erase( vsi, vsi2 ) ;
+		break ;
+	    }
+	}
+	dvsc = dds.var_begin() ;
+	vsc = vs.begin() ;
+	for( ; dvsc != dds.var_end() && vsc != vs.end(); dvsc++, vsc++ )
+	{
+	    if( (*dvsc)->name() == "var4" )
+	    {
+		DDS::Vars_iter dvsc2 = dvsc ;
+		dvsc2++ ;
+		dvsc2++ ;
+		DDS::Vars_iter &dvsi = (DDS::Vars_iter &)dvsc ;
+		DDS::Vars_iter &dvsi2 = (DDS::Vars_iter &)dvsc2 ;
+		dds.del_var( dvsi, dvsi2 ) ;
+	    }
+	    CPPUNIT_ASSERT( (*dvsc)->name() == *vsc ) ;
+	}
+
+	nv = dds.num_var() ;
+	CPPUNIT_ASSERT( nv == 4 ) ;
+	if( nv != 4 )
+	{
+	    for( dvsc = dds.var_begin(); dvsc != dds.var_end(); dvsc++ )
+	    {
+		DBG2( cerr << "    " << (*dvsc)->name() << endl ) ;
+	    }
+	}
+
+	BaseType *bt = dds.var( "varnot" ) ;
+	CPPUNIT_ASSERT( !bt ) ;
+
+	bt = dds.var( "var6" ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	if( bt )
+	{
+	    CPPUNIT_ASSERT( bt->name() == "var6" ) ;
+	}
+
+	string find_var = "var6" ;
+	bt = dds.var( find_var ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	if( bt )
+	{
+	    CPPUNIT_ASSERT( bt->name() == "var6" ) ;
+	}
+
+	find_var = "var10" ;
+	bt = dds.var( find_var ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	if( bt )
+	{
+	    CPPUNIT_ASSERT( bt->name() == "var10" ) ;
+	}
+
+	find_var = "var10" ;
+	BaseType::btp_stack btps ;
+	bt = dds.var( find_var, &btps ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	if( bt )
+	{
+	    CPPUNIT_ASSERT( bt->name() == "var10" ) ;
+	    if( bt->name() == "var10" )
+	    {
+		CPPUNIT_ASSERT( btps.size() == 2 ) ;
+		if( btps.size() == 2 )
+		{
+		    CPPUNIT_ASSERT( btps.top()->name() == "var8" ) ;
+		    btps.pop() ;
+		    CPPUNIT_ASSERT( btps.top()->name() == "var9" ) ;
+		    btps.pop() ;
+		}
+	    }
+	}
+
+	find_var = "var8.var9.var10" ;
+	bt = dds.var( find_var, &btps ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	if( bt )
+	{
+	    CPPUNIT_ASSERT( bt->name() == "var10" ) ;
+	    if( bt->name() == "var10" )
+	    {
+		CPPUNIT_ASSERT( btps.size() == 2 ) ;
+		if( btps.size() == 2 )
+		{
+		    CPPUNIT_ASSERT( btps.top()->name() == "var9" ) ;
+		    btps.pop() ;
+		    CPPUNIT_ASSERT( btps.top()->name() == "var8" ) ;
+		    btps.pop() ;
+		}
+	    }
+	}
+
+	{
+            ostringstream sof;
+            dds.print( sof );
+            CPPUNIT_ASSERT(sof.str().find(cprint) != string::npos);
+	}
+
+	{
+            ostringstream sof;
+            dds.print_constrained( sof );
+            CPPUNIT_ASSERT(sof.str().find(nprint) != string::npos);
+	}
+
+	dds.mark_all( true ) ;
+
+	{
+            ostringstream sof;
+            dds.print_constrained( sof );
+            CPPUNIT_ASSERT(sof.str().find(cprint) != string::npos);
+	}
+
+	bool mark_ret = dds.mark( "var8", false ) ;
+	CPPUNIT_ASSERT( mark_ret == true ) ;
+
+	{
+            ostringstream sof;
+            dds.print_constrained( sof );
+            CPPUNIT_ASSERT(sof.str().find(pprint) != string::npos);
+	}
+    }
+
+    void ddsT_containers()
+    {
+	DDS dds( factory, "TestDDS" ) ;
+
+	// set the container to c1 and make sure the container is created
+	dds.container_name( "c1" ) ;
+	CPPUNIT_ASSERT( dds.container_name() == "c1" ) ;
+
+	Structure *c1 = dds.container() ;
+	CPPUNIT_ASSERT( c1 ) ;
+	CPPUNIT_ASSERT( c1->name() == "c1" ) ;
+
+	CPPUNIT_ASSERT( dds.num_var() == 1 ) ;
+
+	// set the container to c2 and make sure the container is created
+	dds.container_name( "c2" ) ;
+	CPPUNIT_ASSERT( dds.container_name() == "c2" ) ;
+
+	Structure *c2 = dds.container() ;
+	CPPUNIT_ASSERT( c2 ) ;
+	CPPUNIT_ASSERT( c2->name() == "c2" ) ;
+
+	CPPUNIT_ASSERT( dds.num_var() == 2 ) ;
+
+	// set back to c1, make sure new one not created
+	dds.container_name( "c1" ) ;
+	CPPUNIT_ASSERT( dds.container_name() == "c1" ) ;
+
+	c1 = dds.container() ;
+	CPPUNIT_ASSERT( c1 ) ;
+	CPPUNIT_ASSERT( c1->name() == "c1" ) ;
+
+	CPPUNIT_ASSERT( dds.num_var() == 2 ) ;
+
+	// start adding variables and make sure not added directly to dds.
+	// Make sure can find those variables without referencing the
+	// container.
+	try
+	{
+	    BaseType *bt = factory->NewInt16( "c1var1" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewStr( "c1var2" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewArray( "c1var3", factory->NewInt16( "" ) ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "failed to add a var" ) ;
+	}
+	CPPUNIT_ASSERT( dds.num_var() == 2 ) ;
+	CPPUNIT_ASSERT( c1->element_count() == 3 ) ;
+
+	BaseType *bt = dds.var( "c1var1" ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	CPPUNIT_ASSERT( bt->name() == "c1var1" ) ;
+	Int16 *ibt = dynamic_cast<Int16 *>(bt) ;
+	CPPUNIT_ASSERT( ibt ) ;
+
+	bt = dds.var( "c1var2" ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	CPPUNIT_ASSERT( bt->name() == "c1var2" ) ;
+	Str *strbt = dynamic_cast<Str *>(bt) ;
+	CPPUNIT_ASSERT( strbt ) ;
+
+	dds.del_var( "c1var2" ) ;
+	bt = dds.var( "c1var2" ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+	CPPUNIT_ASSERT( dds.num_var() == 2 ) ;
+	CPPUNIT_ASSERT( c1->element_count() == 2 ) ;
+
+	// set container to "", add vars, make sure added directly to dds.
+	// Make sure can find those variables
+	dds.container_name( "" ) ;
+	CPPUNIT_ASSERT( dds.container_name() == "" ) ;
+	CPPUNIT_ASSERT( dds.container() == 0 ) ;
+	try
+	{
+	    BaseType *bt = factory->NewByte( "var1" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewFloat64( "var2" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewUInt32( "var3" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "failed to add a var" ) ;
+	}
+	CPPUNIT_ASSERT( dds.num_var() == 5 ) ;
+	CPPUNIT_ASSERT( c1->element_count() == 2 ) ;
+
+	BaseType::btp_stack btps ;
+	bt = dds.var( "c1var1", btps ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "c1var1" ) ;
+	CPPUNIT_ASSERT( btps.size() == 1 ) ;
+	BaseType *btp = btps.top() ;
+	CPPUNIT_ASSERT( btp && btp->name() == "c1" ) ;
+	btps.pop() ;
+
+	bt = dds.var( "var1" ) ;
+	CPPUNIT_ASSERT( bt ) ;
+	CPPUNIT_ASSERT( bt->name() == "var1" ) ;
+	Byte *bbt = dynamic_cast<Byte *>(bt) ;
+	CPPUNIT_ASSERT( bbt ) ;
+
+	bt = c1->var( "var1" ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+
+	dds.del_var( "var3" ) ;
+	bt = dds.var( "var3" ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+	CPPUNIT_ASSERT( dds.num_var() == 4 ) ;
+	CPPUNIT_ASSERT( c1->element_count() == 2 ) ;
+
+	// set to c2, add variables and make sure not added directly to dds.
+	// Make sure can find those variables without referencing the
+	// container.
+	dds.container_name( "c2" ) ;
+	CPPUNIT_ASSERT( dds.container_name() == "c2" ) ;
+	c2 = dds.container() ;
+	CPPUNIT_ASSERT( c2 && c2->name() == "c2" ) ;
+
+	try
+	{
+	    BaseType *bt = factory->NewInt32( "c2var1" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    bt = factory->NewStr( "c2var2" ) ;
+	    dds.add_var( bt ) ;
+	    delete bt ;
+	    Structure *s = factory->NewStructure( "c2var3" ) ;
+	    Structure *s1 = factory->NewStructure( "c2var3var1" ) ;
+	    bt = factory->NewInt16( "c2var3var1var1" ) ;
+	    s1->add_var( bt ) ;
+	    delete bt ; bt = 0 ;
+	    bt = factory->NewInt16( "c2var3var1var2" ) ;
+	    s1->add_var( bt ) ;
+	    delete bt ; bt = 0 ;
+	    s->add_var( s1 ) ;
+	    delete s1 ; s1 = 0 ;
+	    dds.add_var( s ) ;
+	    delete s ; s = 0 ;
+	}
+	catch( InternalErr &e )
+	{
+	    CPPUNIT_FAIL( "failed to add a var" ) ;
+	}
+	CPPUNIT_ASSERT( dds.num_var() == 4 ) ;
+	CPPUNIT_ASSERT( c2->element_count() == 3 ) ;
+
+	bt = dds.var( "c2var1" ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "c2var1" ) ;
+	Int32 *i32bt = dynamic_cast<Int32 *>( bt ) ;
+	CPPUNIT_ASSERT( i32bt ) ;
+
+	bt = dds.var( "c2var2" ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "c2var2" ) ;
+	strbt = dynamic_cast<Str *>( bt ) ;
+	CPPUNIT_ASSERT( strbt ) ;
+
+	bt = dds.var( "c2var3" ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "c2var3" ) ;
+	Structure *sbt = dynamic_cast<Structure *>( bt ) ;
+	CPPUNIT_ASSERT( sbt ) ;
+
+	bt = dds.var( "var1" ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+
+	bt = dds.var( "var2" ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+
+	bt = dds.var( "c2var3var1var2", btps ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "c2var3var1var2" ) ;
+	CPPUNIT_ASSERT( btps.size() == 3 ) ;
+	btp = btps.top() ;
+	CPPUNIT_ASSERT( btp && btp->name() == "c2" ) ;
+	btps.pop() ;
+	btp = btps.top() ;
+	CPPUNIT_ASSERT( btp && btp->name() == "c2var3" ) ;
+	btps.pop() ;
+	btp = btps.top() ;
+	CPPUNIT_ASSERT( btp && btp->name() == "c2var3var1" ) ;
+	btps.pop() ;
+
+	dds.del_var( "c2var1" ) ;
+	bt = dds.var( "c2var1" ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+	CPPUNIT_ASSERT( dds.num_var() == 4 ) ;
+	CPPUNIT_ASSERT( c2->element_count() == 2 ) ;
+
+	// print the dds and make sure it looks good.
+	ostringstream sstrm ;
+	dds.print( sstrm ) ;
+	cout << sstrm.str() << endl ;
+	CPPUNIT_ASSERT( sstrm.str() == containerprint ) ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( ddsT ) ;
+
+/* NOTHING NEEDS TO BE CHANGED BELOW HERE */
+
+int main( int, char ** )
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter(
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/ddx-testsuite/D1.ddx b/unit-tests/ddx-testsuite/D1.ddx
new file mode 100644
index 0000000..d0df266
--- /dev/null
+++ b/unit-tests/ddx-testsuite/D1.ddx
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="EOSDB.DBO"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Attribute name="_location" type="Container">
+		<Attribute name="Description" type="String">
+			<value>"String describing general location (southern ocean,oregon coast, etc.) of drifter deployment."</value>
+		</Attribute>
+	</Attribute>
+
+	<Sequence name="Drifters">
+		<String name="instrument_id"/>
+		<String name="location"/>
+		<Float64 name="latitude"/>
+		<Float64 name="longitude"/>
+	</Sequence>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/D1.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/DDX_from_dataddx.xml b/unit-tests/ddx-testsuite/DDX_from_dataddx.xml
new file mode 100644
index 0000000..9cd28e7
--- /dev/null
+++ b/unit-tests/ddx-testsuite/DDX_from_dataddx.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="fnoc1.nc"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xsi:schemaLocation="http://xml.OPeNDAP.org/ns/DAP/3.2#
+http://xml.OPeNDAP.org/dap/dap/3.2.xsd"
+xmlns:grddl="http://www.w3.org/2003/g/data-view#"
+grddl:transformation="http://xml.OPeNDAP.org/transforms/ddxToRdfTriples.xsl"
+xmlns="http://xml.OPeNDAP.org/ns/DAP/3.2#"
+xmlns:dap="http://xml.OPeNDAP.org/ns/DAP/3.2#"
+dap_version="3.2">
+    <Attribute name="NC_GLOBAL" type="Container">
+        <Attribute name="base_time" type="String">
+            <value>88- 10-00:00:00</value>
+        </Attribute>
+        <Attribute name="title" type="String">
+            <value> FNOC UV wind components from 1988- 10 to 1988-
+13.</value>
+        </Attribute>
+    </Attribute>
+    <Attribute name="DODS_EXTRA" type="Container">
+        <Attribute name="Unlimited_Dimension" type="String">
+            <value>time_a</value>
+        </Attribute>
+    </Attribute>
+
+    <Structure name="c">
+        <Array name="lat">
+            <Attribute name="units" type="String">
+                <value>degree North</value>
+            </Attribute>
+            <Float32/>
+            <dimension name="lat" size="17"/>
+        </Array>
+    </Structure>
+
+    <blob href="cid:4E58F56D-A77E-444B-9528-586AA1309FD4 at OPeNDAP.org"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/EOSDB.ddx b/unit-tests/ddx-testsuite/EOSDB.ddx
new file mode 100644
index 0000000..f2b68b9
--- /dev/null
+++ b/unit-tests/ddx-testsuite/EOSDB.ddx
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="EOSDB"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Attribute name="Facility" type="Container">
+		<Attribute name="PrincipleInvestigator" type="String">
+			<value>"Mark Abbott"</value>
+		</Attribute>
+		<Attribute name="DataCenter" type="String">
+			<value>"COAS Environmental Computer Facility"</value>
+		</Attribute>
+	</Attribute>
+	<Attribute name="LON" type="Container">
+		<Attribute name="units" type="String">
+			<value>"degrees_east"</value>
+		</Attribute>
+		<Attribute name="modulo" type="String">
+			<value>" "</value>
+		</Attribute>
+		<Attribute name="point_spacing" type="String">
+			<value>"even"</value>
+		</Attribute>
+	</Attribute>
+	<Attribute name="LAT" type="Container">
+		<Attribute name="units" type="String">
+			<value>"degrees_north"</value>
+		</Attribute>
+		<Attribute name="point_spacing" type="String">
+			<value>"even"</value>
+		</Attribute>
+	</Attribute>
+	<Attribute name="TIME" type="Container">
+		<Attribute name="units" type="String">
+			<value>"days since 1700-01-01 00:00:00"</value>
+		</Attribute>
+		<Attribute name="time_origin" type="String">
+			<value>"1-JAN-1700"</value>
+		</Attribute>
+		<Attribute name="point_spacing" type="String">
+			<value>"uneven"</value>
+		</Attribute>
+		<Attribute name="edges" type="String">
+			<value>"TIMEedges"</value>
+		</Attribute>
+	</Attribute>
+	<Attribute name="TIMEedges" type="Container">
+		<Attribute name="edges" type="String">
+			<value>" "</value>
+		</Attribute>
+	</Attribute>
+	<Attribute name="SST" type="Container">
+		<Attribute name="missing_value" type="Float64">
+			<value>-9.9999998e+33</value>
+		</Attribute>
+		<Attribute name="_FillValue" type="Float64">
+			<value>-9.9999998e+33</value>
+		</Attribute>
+		<Attribute name="long_name" type="String">
+			<value>"Sea Surface Temperature"</value>
+		</Attribute>
+		<Attribute name="history" type="String">
+			<value>"From all_coads_grid"</value>
+		</Attribute>
+		<Attribute name="units" type="String">
+			<value>"deg C"</value>
+		</Attribute>
+	</Attribute>
+	<Attribute name="NC_GLOBAL" type="Container">
+		<Attribute name="history" type="String">
+			<value>"FERRET V4.11 (debug/no GUI) 19-Nov-95FERRET V4.20 (debug/no GUI) 12-Mar-96"</value>
+		</Attribute>
+		<Attribute name="title" type="String">
+			<value>"COADS Surface Marine Observations (1854-1993)"</value>
+		</Attribute>
+	</Attribute>
+
+	<Sequence name="Abbott_Image_Data">
+		<String name="Image_Name"/>
+		<String name="Date_Sampled"/>
+		<Float64 name="North_Latitude"/>
+		<Float64 name="South_Latitude"/>
+		<Float64 name="West_Longitude"/>
+		<Float64 name="East_Longitude"/>
+		<String name="Version"/>
+		<Int32 name="Julian_Date"/>
+		<String name="PI"/>
+		<String name="Algorithm_Code"/>
+		<String name="Project"/>
+		<String name="Comments"/>
+	</Sequence>
+	<Sequence name="Sat_Images">
+		<String name="Image_Name"/>
+		<String name="Date_Sampled"/>
+		<Float64 name="North_Latitude"/>
+		<Float64 name="South_Latitude"/>
+		<Float64 name="West_Longitude"/>
+		<Float64 name="East_Longintude"/>
+		<String name="Version"/>
+		<String name="Satellite"/>
+		<String name="Instrument"/>
+		<String name="Channel"/>
+		<String name="Resolution"/>
+		<Int32 name="Image_Size"/>
+		<String name="Image_Type"/>
+		<Int32 name="Image_Bits_Per_Pixel"/>
+		<Int32 name="Image_Width"/>
+		<Int32 name="Image_Height"/>
+		<Array name="Image">
+			<Byte/>
+			<dimension size="1000"/>
+		</Array>
+		<Int32 name="Raw_Image_Size"/>
+		<Array name="Raw_Image_Data">
+			<Byte/>
+			<dimension size="1000"/>
+		</Array>
+		<Int32 name="Year"/>
+		<String name="Month"/>
+		<Int32 name="Day"/>
+		<Int32 name="Hour"/>
+	</Sequence>
+	<Sequence name="Drifters">
+		<String name="Instrument_ID"/>
+		<Float64 name="Battery"/>
+		<Float64 name="Checksum"/>
+		<Float64 name="Date_Age"/>
+		<Float64 name="Ed490"/>
+		<Float64 name="Ed490_stdev"/>
+		<Float64 name="Latitude"/>
+		<Float64 name="Longitude"/>
+		<Float64 name="Lu412"/>
+		<Float64 name="Lu412_stdev"/>
+		<Float64 name="Lu443"/>
+		<Float64 name="Lu443_stdev"/>
+		<Float64 name="Lu490"/>
+		<Float64 name="Lu490_stdev"/>
+		<Float64 name="Lu510"/>
+		<Float64 name="Lu510_stdev"/>
+		<Float64 name="Lu555"/>
+		<Float64 name="Lu555_stdev"/>
+		<Float64 name="Lu670"/>
+		<Float64 name="Lu670_stdev"/>
+		<Float64 name="Lu683"/>
+		<Float64 name="Lu683_stdev"/>
+		<Float64 name="Max_Depth"/>
+		<Float64 name="Night_Len"/>
+		<Float64 name="Number_Samples"/>
+		<Float64 name="Num_Aves"/>
+		<Float64 name="Press_Volts"/>
+		<Float64 name="Sea_Surface_Temperature"/>
+		<Float64 name="Sub_Wait"/>
+		<Float64 name="Surf_Volts"/>
+		<Float64 name="Surface_Average"/>
+		<Float64 name="Surface_Percent"/>
+		<Float64 name="Julian_Greenwich"/>
+		<Float64 name="Sun_Angle"/>
+		<Int32 name="Optical_Flag"/>
+		<Int32 name="Sampling_Flag"/>
+		<Int32 name="Tracking_Flag"/>
+		<Int32 name="Hand_Checked_Flag"/>
+		<Float64 name="Julian_Local_Time"/>
+		<String name="Date_Greenwich"/>
+		<String name="Date_Local_Time"/>
+		<String name="DateStamp"/>
+		<String name="algo_code"/>
+		<Int32 name="GPS_hour"/>
+		<Float64 name="GPS_lat"/>
+		<Float64 name="GPS_lon"/>
+		<Float64 name="rel1_lat"/>
+		<Float64 name="rel1_lon"/>
+		<Float64 name="rel2_lat"/>
+		<Float64 name="rel2_lon"/>
+		<Int32 name="time_to_1st_fix"/>
+		<Int32 name="message_ID"/>
+		<Int32 name="max_GPS_volt"/>
+	</Sequence>
+	<Sequence name="Instrument">
+		<String name="Instrument_ID"/>
+		<String name="Instrument_Type"/>
+		<String name="Sensor_Platform_ID"/>
+		<String name="Comment"/>
+	</Sequence>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/EOSDB.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap b/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap
new file mode 100644
index 0000000..60301bb
Binary files /dev/null and b/unit-tests/ddx-testsuite/dataddx_without_top_headers.dap differ
diff --git a/unit-tests/ddx-testsuite/error.01.ddx b/unit-tests/ddx-testsuite/error.01.ddx
new file mode 100644
index 0000000..90646fb
--- /dev/null
+++ b/unit-tests/ddx-testsuite/error.01.ddx
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+    <BYTE name="b1"/>
+
+    <dataBLOB href="huh.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/error.02.ddx b/unit-tests/ddx-testsuite/error.02.ddx
new file mode 100644
index 0000000..59b27c9
--- /dev/null
+++ b/unit-tests/ddx-testsuite/error.02.ddx
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+    <Byte name="b1">
+        <Attribute name="test" type="Byte">
+	    <value>2</value>
+    </Byte>
+
+    <dataBLOB href="huh.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/error.03.ddx b/unit-tests/ddx-testsuite/error.03.ddx
new file mode 100644
index 0000000..fc8f0af
--- /dev/null
+++ b/unit-tests/ddx-testsuite/error.03.ddx
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+    <Byte name="b1">
+        <Attribute name="test" type="Byte">
+	    <value>2</value>
+	</Attribute>
+    </NOTByte>
+
+    <dataBLOB href="huh.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/error.04.ddx b/unit-tests/ddx-testsuite/error.04.ddx
new file mode 100644
index 0000000..0534375
--- /dev/null
+++ b/unit-tests/ddx-testsuite/error.04.ddx
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+    <Byte name="b1">
+        <Attribute name="test" type="Byte">
+	    <value>2</value>
+	</Attribute>
+	<Attribute name="test2" type="Container">
+	    <Attribute name="test" type="Byte">
+		<value>2</value>
+	    </Attribute>
+	    <Int32 name="bogus"/>
+        </Attribute>	    
+    </Byte>
+
+    <dataBLOB href="huh.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/error.05.ddx b/unit-tests/ddx-testsuite/error.05.ddx
new file mode 100644
index 0000000..cd817c0
--- /dev/null
+++ b/unit-tests/ddx-testsuite/error.05.ddx
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="OneDimensionalSimpleArrays"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Array name="b">
+		<Byte/>
+	</Array>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.02.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/error.06.ddx b/unit-tests/ddx-testsuite/error.06.ddx
new file mode 100644
index 0000000..9599160
--- /dev/null
+++ b/unit-tests/ddx-testsuite/error.06.ddx
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="OneDimensionalSimpleArrays"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+        <Byte/>
+        <dataBLOB href="blah"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.00.ddx b/unit-tests/ddx-testsuite/test.00.ddx
new file mode 100644
index 0000000..750fc2e
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.00.ddx
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes" dapVersion="3.2">
+
+        <Attribute name="PrincipleInvestigator" type="String">
+            <value>"Mark Abbott"</value>
+            <value>"Ph.D"</value>
+        </Attribute>
+
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.01.ddx b/unit-tests/ddx-testsuite/test.01.ddx
new file mode 100644
index 0000000..7e284a5
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.01.ddx
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+	<Attribute name="PrincipleInvestigator" type="String">
+	    <value>"Mark Abbott"</value>
+	    <value>"Ph.D"</value>
+	</Attribute>
+	<Attribute name="DataCenter" type="String">
+	    <value>"COAS Environmental Computer Facility"</value>
+	</Attribute>
+	<Attribute name="DrifterType" type="String">
+	    <value>"MetOcean WOCE/OCM"</value>
+	</Attribute>
+
+    <dataBLOB href="test.01.ddx"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.01.error.ddx b/unit-tests/ddx-testsuite/test.01.error.ddx
new file mode 100644
index 0000000..8570359
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.01.error.ddx
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Attribute name="Facility" type="Container">
+		<Attribute name="PrincipleInvestigator" type="String">
+			<value>"Mark Abbott"</value>
+			<value>"Ph.D"</value>
+		</Attribute>
+		<Attribute name="DataCenter" type="String">
+			<value>"COAS Environmental Computer Facility"</value>
+		</Attribute>
+		<Attribute name="DrifterType" type="String">
+			<value>"MetOcean WOCE/OCM"</value>
+		</Attribute>
+	</Attribute>
+
+	<Byte name="b">
+		<Attribute name="Description" type="String">
+			<value>"A test byte"</value>
+		</Attribute>
+		<Attribute name="units" type="String">
+			<value>unknown</value>
+		</Attribute>
+	</Byte>
+	<Int32 name="i32">
+		<Attribute name="Description" type="String">
+			<value>"A 32 bit test server int"</value>
+		</Attribute>
+		<Attribute name="units" type="String">
+			<value>"unknown"</value>
+		</Attribute>
+	</Int32>
+	<UInt32 name="ui32"/>
+	<Int16 name="i16"/>
+	<UInt16 name="ui16"/>
+	<Float32 name="f32"/>
+	<Float64 name="f64"/>
+	<String name="s"/>
+	<Url name="u"/>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.01.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.01.orig.ddx b/unit-tests/ddx-testsuite/test.01.orig.ddx
new file mode 100644
index 0000000..fe75e98
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.01.orig.ddx
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Attribute name="Facility" type="Container">
+		<Attribute name="PrincipleInvestigator" type="String">
+			<value>"Mark Abbott"</value>
+			<value>"Ph.D"</value>
+		</Attribute>
+		<Attribute name="DataCenter" type="String">
+			<value>"COAS Environmental Computer Facility"</value>
+		</Attribute>
+		<Attribute name="DrifterType" type="String">
+			<value>"MetOcean WOCE/OCM"</value>
+		</Attribute>
+	</Attribute>
+
+	<Byte name="b">
+		<Attribute name="Description" type="String">
+			<value>"A test byte"</value>
+		</Attribute>
+		<Attribute name="units" type="String">
+			<value>unknown</value>
+		</Attribute>
+	</Byte>
+	<Int32 name="i32">
+		<Attribute name="Description" type="String">
+			<value>"A 32 bit test server int"</value>
+		</Attribute>
+		<Attribute name="units" type="String">
+			<value>"unknown"</value>
+		</Attribute>
+	</Int32>
+	<UInt32 name="ui32"/>
+	<Int16 name="i16"/>
+	<UInt16 name="ui16"/>
+	<Float32 name="f32"/>
+	<Float64 name="f64"/>
+	<String name="s"/>
+	<Url name="u"/>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.01.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.02.ddx b/unit-tests/ddx-testsuite/test.02.ddx
new file mode 100644
index 0000000..c6306e2
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.02.ddx
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+    <Attribute name="Facility" type="Container">
+	<Attribute name="PrincipleInvestigator" type="String">
+	    <value>"Mark Abbott"</value>
+	    <value>"Ph.D"</value>
+	</Attribute>
+	<Attribute name="DataCenter" type="String">
+	    <value>"COAS Environmental Computer Facility"</value>
+	</Attribute>
+	<Attribute name="DrifterType" type="String">
+	    <value>"MetOcean WOCE/OCM"</value>
+	</Attribute>
+
+    </Attribute>
+
+    <dataBLOB href="huh.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.03.ddx b/unit-tests/ddx-testsuite/test.03.ddx
new file mode 100644
index 0000000..76da1d4
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.03.ddx
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes">
+
+    <Attribute name="Facility" type="Container">
+	<Attribute name="PrincipleInvestigator" type="String">
+	    <value>"Mark Abbott"</value>
+	    <value>"Ph.D"</value>
+	</Attribute>
+	<Attribute name="DataCenter" type="String">
+	    <value>"COAS Environmental Computer Facility"</value>
+	</Attribute>
+	<Attribute name="DrifterType" type="String">
+	    <value>"MetOcean WOCE/OCM"</value>
+	</Attribute>
+
+	<Alias name="huh" Attribute="DrifterType"/>
+
+    </Attribute>
+
+    <dataBLOB href="huh.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.04.ddx b/unit-tests/ddx-testsuite/test.04.ddx
new file mode 100644
index 0000000..d2cc0d0
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.04.ddx
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Byte name="b"/>
+	<Int32 name="i32"/>
+	<UInt32 name="ui32"/>
+	<Int16 name="i16"/>
+	<UInt16 name="ui16"/>
+	<Float32 name="f32"/>
+	<Float64 name="f64"/>
+	<String name="s"/>
+	<Url name="u"/>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.01.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.05.ddx b/unit-tests/ddx-testsuite/test.05.ddx
new file mode 100644
index 0000000..41c608f
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.05.ddx
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Byte name="b">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</Byte>
+
+	<Int32 name="i32">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</Int32>
+
+	<UInt32 name="ui32">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</UInt32>
+
+	<Int16 name="i16">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</Int16>
+
+	<UInt16 name="ui16">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</UInt16>
+
+	<Float32 name="f32">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</Float32>
+
+	<Float64 name="f64">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</Float64>
+
+	<String name="s">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</String>
+
+	<Url name="u">
+	    <Attribute name="Description" type="String">
+		    <value>"A test byte"</value>
+	    </Attribute>
+	    <Attribute name="units" type="String">
+		    <value>unknown</value>
+	    </Attribute>
+	    <Attribute name="Facility" type="Container">
+		    <Attribute name="PrincipleInvestigator" type="String">
+			    <value>"Mark Abbott"</value>
+			    <value>"Ph.D"</value>
+		    </Attribute>
+		    <Attribute name="DataCenter" type="String">
+			    <value>"COAS Environmental Computer Facility"</value>
+		    </Attribute>
+		    <Attribute name="DrifterType" type="String">
+			    <value>"MetOcean WOCE/OCM"</value>
+		    </Attribute>
+	    </Attribute>
+	</Url>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.01.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.06.ddx b/unit-tests/ddx-testsuite/test.06.ddx
new file mode 100644
index 0000000..093cb88
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.06.ddx
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="OneDimensionalSimpleArrays"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS">
+
+	<Array name="b">
+		<Byte/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="i32">
+		<Int32/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="ui32">
+		<UInt32/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="i16">
+		<Int16/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="ui16">
+		<UInt16/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="f32">
+		<Float32/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="f64">
+		<Float64/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="s">
+		<String/>
+		<dimension size="25"/>
+	</Array>
+	<Array name="u">
+		<Url/>
+		<dimension size="25"/>
+	</Array>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.02.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.07.ddx b/unit-tests/ddx-testsuite/test.07.ddx
new file mode 100644
index 0000000..b179513
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.07.ddx
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="MultiDimensionalSimpleArrays"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+
+	<Array name="b">
+		<Byte/>
+		<dimension size="2"/>
+		<dimension size="3"/>
+		<dimension size="4"/>
+	</Array>
+	<Array name="b2">
+		<Byte/>
+		<dimension size="2"/>
+		<dimension size="3"/>
+	</Array>
+	<Array name="i32">
+		<Int32/>
+		<dimension size="2"/>
+		<dimension size="3"/>
+		<dimension size="4"/>
+	</Array>
+	<Array name="ui32">
+		<UInt32/>
+		<dimension size="2"/>
+		<dimension size="3"/>
+		<dimension size="4"/>
+		<dimension size="3"/>
+		<dimension size="2"/>
+	</Array>
+	<Array name="i16">
+		<Int16/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+	</Array>
+	<Array name="ui16">
+		<UInt16/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+	</Array>
+	<Array name="f32">
+		<Float32/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+	</Array>
+	<Array name="f64">
+		<Float64/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+		<dimension size="2"/>
+	</Array>
+	<Array name="s0">
+		<String/>
+		<dimension size="4"/>
+		<dimension size="5"/>
+		<dimension size="6"/>
+	</Array>
+	<Array name="s1">
+		<String/>
+		<dimension size="10"/>
+		<dimension size="10"/>
+		<dimension size="10"/>
+	</Array>
+	<Array name="u">
+		<Url/>
+		<dimension size="10"/>
+		<dimension size="10"/>
+		<dimension size="10"/>
+	</Array>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/test.03.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.08.ddx b/unit-tests/ddx-testsuite/test.08.ddx
new file mode 100644
index 0000000..4df69f7
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.08.ddx
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="testdata"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Attribute name="stuff" type="String">
+		<value>"Stuff about this stuff"</value>
+		<value>Silly</value>
+		<value>Repitious</value>
+		<value>"testing of stuff"</value>
+	</Attribute>
+	<Attribute name="stuff2" type="String">
+		<value>"More Stuff about this stuff"</value>
+	</Attribute>
+
+	<Array name="somearray">
+		<Attribute name="PrincipleInvestigator" type="Container">
+			<Attribute name="Title" type="String">
+				<value>Dr.</value>
+			</Attribute>
+			<Attribute name="FirstName" type="String">
+				<value>Mark</value>
+			</Attribute>
+			<Attribute name="LastName" type="String">
+				<value>Abbott</value>
+			</Attribute>
+		</Attribute>
+		<Attribute name="CruiseNumber" type="String">
+			<value>WE030702</value>
+		</Attribute>
+		<Byte/>
+		<dimension name="bytes" size="1024"/>
+		<dimension name="bits" size="8"/>
+		<dimension size="256"/>
+	</Array>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/d3.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.09.ddx b/unit-tests/ddx-testsuite/test.09.ddx
new file mode 100644
index 0000000..6738841
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.09.ddx
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="testdata"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Array name="structarray">
+		<Structure>
+			<Float64 name="amp"/>
+			<Float32 name="damp"/>
+			<Float64 name="clamp"/>
+		</Structure>
+		<dimension name="twizzle" size="41024"/>
+		<dimension name="dizzle" size="25211"/>
+	</Array>
+	<Structure name="bunghole">
+	    <Attribute name="leaf04a" type="Float64">
+		<value>1451.87567</value>
+	    </Attribute>
+	    <Attribute name="leaf04b" type="Float64">
+		<value>141.87567</value>
+	    </Attribute>
+	    <Array name="amp">
+		<Float32/>
+		<dimension name="x" size="256"/>
+		<dimension name="y" size="256"/>
+	    </Array>
+	    <Float32 name="JulianDay"/>
+	    <Int16 name="InstrumentNumber"/>
+	    <Structure name="foo">
+		<Float64 name="arf"/>
+		<Array name="barf">
+		    <Attribute name="jimmy" type="Int16">
+		        <value>154</value>
+		    </Attribute>
+		    <Float64/>
+		    <dimension size="2222"/>
+		</Array>
+	    </Structure>
+	</Structure>
+	<Structure name="ragtop">
+	    <Attribute name="Thumping" type="Container">
+		<Attribute name="John" type="String">
+		    <value>"Has Too Much Fun"</value>
+		</Attribute>
+		<Attribute name="Sally" type="String">
+		    <value>"Has No Fun"</value>
+		</Attribute>
+	    </Attribute>
+	    <Byte name="diggle"/>
+	    <Byte name="piggle"/>
+	    <Byte name="wiggle"/>
+	    <Byte name="doo"/>
+	</Structure>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/d3.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.0a.ddx b/unit-tests/ddx-testsuite/test.0a.ddx
new file mode 100644
index 0000000..34cbc7d
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.0a.ddx
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="testdata"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Sequence name="testSeq">
+		<Float64 name="jday">
+		</Float64>
+		<Float32 name="latitude"/>
+		<Float32 name="longitude"/>
+		<Float32 name="SurfaceIrradiance"/>
+		<Structure name="point">
+		    <Int32 name="x"/>
+		    <Int32 name="y"/>
+		</Structure>
+		<Array name="times">
+		    <String/>
+		    <dimension size="1024"/>
+		</Array>
+		<Sequence name="CTDProfile">
+			<Float64 name="depth"/>
+			<Float64 name="temperature"/>
+			<Float64 name="conductivity"/>
+			<Float64 name="fluoresence"/>
+		</Sequence>
+	</Sequence>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/d3.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.0b.ddx b/unit-tests/ddx-testsuite/test.0b.ddx
new file mode 100644
index 0000000..a9fc77b
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.0b.ddx
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="testdata"
+xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://www.dods.org/ns/DODS"
+xsi:schemaLocation="http://www.dods.org/ns/DODS  http://dods.coas.oregonstate.edu:8080/dods/dods.xsd" >
+
+	<Grid  name="sst">
+		<Array name="sst">
+			<Float64/>
+			<dimension name="latitude" size="1024"/>
+			<dimension name="longitude" size="1024"/>
+		</Array>
+		<Map name="latitude">
+			<Float64/>
+			<dimension size="1024"/>
+		</Map>
+		<Map name="longitude">
+			<Float64/>
+			<dimension size="1024"/>
+		</Map>
+	</Grid>
+	<Grid  name="sst2">
+		<Attribute name="Thumping" type="Container">
+			<Attribute name="John" type="String">
+				<value>"Has Too Much Fun"</value>
+			</Attribute>
+			<Attribute name="Sally" type="String">
+				<value>"Has No Fun"</value>
+			</Attribute>
+		</Attribute>
+		<Array name="sst">
+			<Float64/>
+			<dimension name="latitude" size="1024"/>
+			<dimension name="longitude" size="1024"/>
+		</Array>
+		<Map name="latitude">
+			<Float64/>
+			<dimension size="1024"/>
+		</Map>
+		<Map name="longitude">
+			<Float64/>
+			<dimension size="1024"/>
+		</Map>
+	</Grid>
+
+	<dataBLOB href="http://dods.coas.oregonstate.edu:8080/dods/dts/d3.blob"/>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.0c.ddx b/unit-tests/ddx-testsuite/test.0c.ddx
new file mode 100644
index 0000000..fa4f2fb
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.0c.ddx
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- DAP 3.2 response without the BLOB element -->
+
+<Dataset name="SimpleTypes" dapVersion="3.2">
+
+        <Attribute name="PrincipleInvestigator" type="String">
+            <value>"Mark Abbott"</value>
+            <value>"Ph.D"</value>
+        </Attribute>
+
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.0d.ddx b/unit-tests/ddx-testsuite/test.0d.ddx
new file mode 100644
index 0000000..8de857c
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.0d.ddx
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Dataset name="SimpleTypes" dapVersion="3.2">
+
+        <Attribute name="PrincipleInvestigator" type="String">
+            <value>"Mark Abbott"</value>
+            <value>"Ph.D"</value>
+        </Attribute>
+
+        <dataBLOB href="bad element...">
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.1.other_xml.ddx b/unit-tests/ddx-testsuite/test.1.other_xml.ddx
new file mode 100644
index 0000000..6d9d560
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.1.other_xml.ddx
@@ -0,0 +1,15 @@
+<Dataset name="200803061600_HFRadar_USEGC_6km_rtv_SIO.nc"
+    xmlns="http://xml.opendap.org/ns/DAP/3.3#"
+    xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
+    dapVersion="3.3"
+    xmlns:xml="http://www.w3.org/XML/1998/namespace"
+    xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx">
+
+
+        <Attribute name="wcsStuff" type="OtherXML" relationship="is-a">
+            <CoverageDescription xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"
+                                 xmlns:owcs="http://www.opengis.net/wcs/1.1/ows"
+                                 xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink">
+            </CoverageDescription>
+        </Attribute>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.2.other_xml.ddx b/unit-tests/ddx-testsuite/test.2.other_xml.ddx
new file mode 100644
index 0000000..bad93d1
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.2.other_xml.ddx
@@ -0,0 +1,20 @@
+<Dataset name="200803061600_HFRadar_USEGC_6km_rtv_SIO.nc"
+    xmlns="http://xml.opendap.org/ns/DAP/3.3#"
+    xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
+    dapVersion="3.3"
+    xmlns:xml="http://www.w3.org/XML/1998/namespace"
+    xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx">
+
+
+        <Attribute name="wcsStuff" type="OtherXML" relationship="is-a">
+            <CoverageDescription xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"
+                                 xmlns:owcs="http://www.opengis.net/wcs/1.1/ows"
+                                 xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink">
+                <owcs:abstract>This is an abstract</owcs:abstract>
+                <stuff gml:name="barf"/>
+                <Attribute name="nasty" type="String">
+                    <value>this should not be parsed as a DAP attribute.</value>
+                </Attribute>
+            </CoverageDescription>
+        </Attribute>
+</Dataset>
diff --git a/unit-tests/ddx-testsuite/test.3.other_xml.ddx b/unit-tests/ddx-testsuite/test.3.other_xml.ddx
new file mode 100644
index 0000000..e594555
--- /dev/null
+++ b/unit-tests/ddx-testsuite/test.3.other_xml.ddx
@@ -0,0 +1,77 @@
+    <Dataset name="200803061600_HFRadar_USEGC_6km_rtv_SIO.nc"
+    xmlns="http://xml.opendap.org/ns/DAP/3.3#"
+    xmlns:dap="http://xml.opendap.org/ns/DAP/3.3#"
+    dapVersion="3.3"
+    xmlns:xml="http://www.w3.org/XML/1998/namespace"
+    xml:base="http://localhost:8080/opendap/coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc.ddx">
+
+
+        <Attribute name="wcsStuff" type="OtherXML" relationship="is-a">
+            <CoverageDescription xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"
+                                 xmlns:owcs="http://www.opengis.net/wcs/1.1/ows"
+                                 xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink"
+                                 >
+                <ows:Title>Near-Real Time Surface Ocean Velocity</ows:Title>
+                <ows:Abstract>CoverageDescription generated by OPeNDAP WCS UseCase 2.0</ows:Abstract>
+                <Identifier>coverage/200803061600_HFRadar_USEGC_6km_rtv_SIO.nc</Identifier>
+                <Domain>
+                    <SpatialDomain>
+                        <ows:BoundingBox crs="urn:ogc:def:crs:EPSG::4326">
+                            <ows:LowerCorner>-97.8839 21.736</ows:LowerCorner>
+                            <ows:UpperCorner>-57.2312 46.4944</ows:UpperCorner>
+                        </ows:BoundingBox>
+                    </SpatialDomain>
+                    <TemporalDomain>
+                        <gml:timePosition>2008-03-27T16:00:00.000Z</gml:timePosition>
+                    </TemporalDomain>
+                </Domain>
+                <Range>
+                </Range>
+                <SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS>
+                <SupportedFormat>netcdf-cf1.0</SupportedFormat>
+                <SupportedFormat>dap2.0</SupportedFormat>
+            </CoverageDescription>
+        </Attribute>
+
+        <Grid name="u">
+            <Attribute name="one" type="OtherXML" relationship="has-a">
+                <units xmlns="http://my.foo.com/ns/units#" />
+            </Attribute>
+            <Attribute name="two" type="OtherXML" relationship="is-a">
+                <Field xmlns="http://www.opengis.net/wcs/1.1" xmlns:ows="http://www.opengis.net/ows/1.1"
+                                 xmlns:owcs="http://www.opengis.net/wcs/1.1/ows"
+                                 xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:xlink="http://www.w3.org/1999/xlink"
+                                 >
+                    <ows:Title>surface_eastward_sea_water_velocity</ows:Title>
+                    <ows:Abstract>Eastward component of a 2D sea surface velocity vector.</ows:Abstract>
+                    <Identifier>u</Identifier>
+                    <Definition>
+                        <ows:AnyValue/>
+                    </Definition>
+                    <NullValue>-32768</NullValue>
+                    <owcs:InterpolationMethods>
+                        <owcs:DefaultMethod>nearest</owcs:DefaultMethod>
+                    </owcs:InterpolationMethods>
+                </Field>
+            </Attribute>
+            <Array name="u">
+                <Int16/>
+                <dimension name="time" size="1"/>
+                <dimension name="lat" size="460"/>
+                <dimension name="lon" size="701"/>
+            </Array>
+            <Map name="time">
+                <Int32/>
+                <dimension name="time" size="1"/>
+            </Map>
+            <Map name="lat">
+                <Float32/>
+                <dimension name="lat" size="460"/>
+            </Map>
+            <Map name="lon">
+                <Float32/>
+                <dimension name="lon" size="701"/>
+            </Map>
+        </Grid>
+
+    </Dataset>
diff --git a/unit-tests/generalUtilTest.cc b/unit-tests/generalUtilTest.cc
new file mode 100644
index 0000000..bdc6ba8
--- /dev/null
+++ b/unit-tests/generalUtilTest.cc
@@ -0,0 +1,335 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// Tests for the util functions in util.cc and escaping.cc
+
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+// #define DODS_DEBUG
+
+#include "debug.h"
+#include "util.h"
+#include "escaping.h"
+
+#include <cstring>
+#include <string>
+
+using std::cerr;
+using std::endl;
+using std::string;
+
+using namespace CppUnit;
+using namespace libdap;
+
+class generalUtilTest : public TestFixture {
+private:
+
+public:
+    generalUtilTest() {}
+    ~generalUtilTest() {}
+
+    void setUp() {
+    }
+
+    void tearDown() {
+    }
+
+    CPPUNIT_TEST_SUITE(generalUtilTest);
+
+    CPPUNIT_TEST(octal_to_hex_test);
+    CPPUNIT_TEST(prune_spaces_test);
+    CPPUNIT_TEST(path_to_filename_test);
+    CPPUNIT_TEST(hexstring_test);
+    CPPUNIT_TEST(unhexstring_test);
+    CPPUNIT_TEST(id2www_test);
+    CPPUNIT_TEST(www2id_test);
+    CPPUNIT_TEST(ce_string_parse_test);
+    CPPUNIT_TEST(escattr_test);
+    CPPUNIT_TEST(unescattr_test);
+    CPPUNIT_TEST(munge_error_message_test);
+    CPPUNIT_TEST(id2xml_test);
+    CPPUNIT_TEST(xml2id_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    // Tests for methods
+    void octal_to_hex_test() {
+        string hex;
+        hex = octal_to_hex("000");
+        CPPUNIT_ASSERT(hex == "00");
+
+        hex = octal_to_hex("012");
+        CPPUNIT_ASSERT(hex == "0a");
+
+        hex = octal_to_hex("077");
+        CPPUNIT_ASSERT(hex == "3f");
+    }
+
+    void prune_spaces_test() {
+	string test_server = "http://test.opendap.org";
+	CPPUNIT_ASSERT(prune_spaces(test_server) == test_server);
+
+	string test_server_spaces = "   http://test.opendap.org";
+	CPPUNIT_ASSERT(prune_spaces(test_server_spaces) == test_server);
+
+	string test_server_ce = "http://test.opendap.org/file.txt?u,v";
+	CPPUNIT_ASSERT(prune_spaces(test_server_ce) == test_server_ce);
+
+	string test_server_ce_spaces = "http://test.opendap.org/file.txt? u,v";
+	DBG(cerr << "Test Server CE Spaces: "
+	    << prune_spaces(test_server_ce_spaces) << endl);
+	CPPUNIT_ASSERT(prune_spaces(test_server_ce_spaces) == test_server_ce);
+
+	string hdf_two_var = "http://test.opendap.org/dap/data/hdf/S3096277.HDF.Z?Avg_Wind_Speed[0:5][0],RMS_Wind_Speed[0:5][0]";
+	CPPUNIT_ASSERT(prune_spaces(hdf_two_var) == hdf_two_var);
+    }
+
+    void path_to_filename_test() {
+	CPPUNIT_ASSERT(path_to_filename("/this/is/the/end/my.friend") == "my.friend");
+	CPPUNIT_ASSERT(path_to_filename("this.dat") == "this.dat");
+	CPPUNIT_ASSERT(path_to_filename("/this.dat") == "this.dat");
+	CPPUNIT_ASSERT(path_to_filename("/this.dat/") == "");
+    }
+
+    void hexstring_test() {
+	CPPUNIT_ASSERT(hexstring('[') == "5b");
+	CPPUNIT_ASSERT(hexstring(']') == "5d");
+	CPPUNIT_ASSERT(hexstring(' ') == "20");
+	CPPUNIT_ASSERT(hexstring('%') == "25");
+    }
+
+    void unhexstring_test() {
+	CPPUNIT_ASSERT(unhexstring("5b") == "[");
+	CPPUNIT_ASSERT(unhexstring("5d") == "]");
+	CPPUNIT_ASSERT(unhexstring("20") == " ");
+	CPPUNIT_ASSERT(unhexstring("25") == "%");
+	CPPUNIT_ASSERT(unhexstring("5B") == "[");
+	CPPUNIT_ASSERT(unhexstring("5D") == "]");
+    }
+
+    void id2www_test() {
+	CPPUNIT_ASSERT(id2www("this") == "this");
+	CPPUNIT_ASSERT(id2www("This is a test") == "This%20is%20a%20test");
+	CPPUNIT_ASSERT(id2www("This.is") == "This.is");
+	CPPUNIT_ASSERT(id2www("This-is") == "This-is");
+	CPPUNIT_ASSERT(id2www("This_is") == "This_is");
+	CPPUNIT_ASSERT(id2www("This/is") == "This/is");
+	CPPUNIT_ASSERT(id2www("This%is") == "This%25is");
+	CPPUNIT_ASSERT(id2www("This&is") == "This%26is");
+	CPPUNIT_ASSERT(id2www("%This&is") == "%25This%26is");
+    }
+
+    void www2id_test() {
+	CPPUNIT_ASSERT(www2id("This_is_a_test") == "This_is_a_test");
+	CPPUNIT_ASSERT(www2id("This is a test") == "This is a test");
+	CPPUNIT_ASSERT(www2id("%5b") == "[");
+	CPPUNIT_ASSERT(www2id("%5d") == "]");
+	CPPUNIT_ASSERT(www2id("u%5b0%5d") == "u[0]");
+	CPPUNIT_ASSERT(www2id("WVC%20Lat") == "WVC Lat");
+	CPPUNIT_ASSERT(www2id("Grid.Data%20Fields[20][20]")
+	       == "Grid.Data Fields[20][20]");
+
+	CPPUNIT_ASSERT(www2id("Grid.Data%3aFields[20][20]")
+	       == "Grid.Data:Fields[20][20]");
+
+	CPPUNIT_ASSERT(www2id("Grid%3aData%20Fields%5b20%5d[20]", "%", "%20")
+	       == "Grid:Data%20Fields[20][20]");
+
+	CPPUNIT_ASSERT(www2id("Grid%20Data%26Fields[20][20]", "%", "%20")
+	        == "Grid%20Data&Fields[20][20]");
+
+	CPPUNIT_ASSERT(www2id("Grid%20Data%26Fields[20][20]", "%", "%20%26")
+	        == "Grid%20Data%26Fields[20][20]");
+	cerr << "www2id(\"%25This%26is\"): " << www2id("%25This%26is") << endl;
+	CPPUNIT_ASSERT(www2id("%25This%26is") == "%This&is");
+
+    }
+
+    // This is the code in expr.lex that removes enclosing double quotes and
+    // %20 sequences from a string. I copied this here because that actual
+    // function uses globals and would be hard to test. 7/11/2001 jhrg
+    string *store_str(const char *text) {
+	string *s = new string(www2id(string(text)));
+
+	if (*s->begin() == '\"' && *(s->end()-1) == '\"') {
+	    s->erase(s->begin());
+	    s->erase(s->end()-1);
+	}
+
+	return s;
+    }
+
+    // The MS VC++ compiler does not like escapes in string arguments passed
+    // to macros. 04/23/03 jhrg
+    void ce_string_parse_test() {
+	string *str = new string("testing");
+	string *str1 = new string("testing");
+	CPPUNIT_ASSERT(*store_str(str->c_str()) == str1->c_str());
+	*str = "\"testing\"";
+	*str1 = "testing";
+	CPPUNIT_ASSERT(*store_str(str->c_str()) == str1->c_str());
+	*str = "\"test%20ing\"";
+	*str1 = "test ing";
+	CPPUNIT_ASSERT(*store_str(str->c_str()) == str1->c_str());
+	delete str; str = 0;
+	delete str1; str1 = 0;
+    }
+
+    void escattr_test()	{
+	// The backslash escapes the double quote; in the returned string the
+	// first two backslashes are a single escaped bs, the third bs
+	// escapes the double quote.
+	string str = "this_contains a double quote (\")";
+	string str1 = "this_contains a double quote (\\\")";
+	CPPUNIT_ASSERT(escattr(str) == str1);
+
+	str = "this_contains a backslash (\\)";
+	str1 = "this_contains a backslash (\\\\)";
+	CPPUNIT_ASSERT(escattr(str) == str1);
+    }
+
+    void unescattr_test() {
+	CPPUNIT_ASSERT(unescattr("attr") == "attr");
+
+	CPPUNIT_ASSERT(unescattr("\\\\attr") == "\\attr");
+
+	DBG(cerr << "XXX" << unescattr("\\\"attr") << "XXX" << endl);
+	CPPUNIT_ASSERT(unescattr("\\\"attr") == "\"attr");
+
+	char A_200_177[4] = { 128, 127, 'A', '\0'};
+	DBG(cerr << "XXX" << unescattr("\\200\\177A") << "XXX" << endl);
+	CPPUNIT_ASSERT(unescattr("\\200\\177A") == string(A_200_177));
+
+	DBG(cerr << "XXX" << unescattr("\\\\200\\\\177A") << "XXX" << endl);
+	CPPUNIT_ASSERT(unescattr("\\\\200\\\\177A") == string(A_200_177));
+
+
+	DBG(cerr << "XXX" << unescattr("\\\\200\\\\177AZ$&") << "XXX" << endl);
+
+	DBG(cerr << "XXX" << unescattr("\\\\200") << "XXX" << endl);
+    }
+
+    void munge_error_message_test() {
+	string str = "An Error";
+	string str1 = "\"An Error\"";
+	DBG(cerr << "Munge: " << munge_error_message(str) << endl);
+	CPPUNIT_ASSERT(munge_error_message(str) == str1);
+
+	str = "\"An Error\"";
+	str1 = "\"An Error\"";
+	DBG(cerr << "Munge: " << munge_error_message(str) << endl);
+	CPPUNIT_ASSERT(munge_error_message(str) == str1);
+
+	str = "An \"E\"rror";
+	str1 = "\"An \\\"E\\\"rror\"";
+	DBG(cerr << "Munge: " << munge_error_message(str) << endl);
+	CPPUNIT_ASSERT(munge_error_message(str) == str1);
+
+	str = "An \\\"E\\\"rror";
+	str1 = "\"An \\\"E\\\"rror\"";
+	DBG(cerr << "Munge: " << munge_error_message(str) << endl);
+	CPPUNIT_ASSERT(munge_error_message(str) == str1);
+    }
+
+
+#if 0
+    // Moved function to HTTPConect.
+    void get_tempfile_template_test() {
+#ifdef WIN32
+	if (_putenv("TMPDIR=C:\\") == 0) {
+	    DBG(cerr << "TMPDIR: " << getenv("TMPDIR") << endl);
+	    CPPUNIT_ASSERT(strcmp(get_tempfile_template("DODSXXXXXX"),
+			  "C:\\DODSXXXXXX") == 0);
+	}
+	else
+	    cerr << "Did not test setting TMPDIR; no test" << endl;
+#else
+	if (setenv("TMPDIR", "/tmp", 1) == 0) {
+	    DBG(cerr << "TMPDIR: " << getenv("TMPDIR") << endl);
+	    CPPUNIT_ASSERT(strcmp(get_tempfile_template("DODSXXXXXX"),
+			  "/tmp/DODSXXXXXX") == 0);
+	}
+	else
+	    cerr << "Did not test setting TMPDIR; no test" << endl;
+#endif
+
+#if !defined(WIN32) && defined(P_tmpdir)
+	string tmplt = P_tmpdir;
+	tmplt.append("/"); tmplt.append("DODSXXXXXX");
+	putenv("TMPDIR=");
+	CPPUNIT_ASSERT(strcmp(get_tempfile_template("DODSXXXXXX"),
+			      tmplt.c_str()) == 0);
+#endif
+    }
+#endif
+
+    void id2xml_test() {
+	CPPUNIT_ASSERT(id2xml("abcdef") == "abcdef");
+	CPPUNIT_ASSERT(id2xml("abc<def") == "abc<def");
+	CPPUNIT_ASSERT(id2xml("abc>def") == "abc>def");
+	CPPUNIT_ASSERT(id2xml("abc&def") == "abc&def");
+	CPPUNIT_ASSERT(id2xml("abc'def") == "abc'def");
+	CPPUNIT_ASSERT(id2xml("abc\"def") == "abc"def");
+	CPPUNIT_ASSERT(id2xml("abc<<def") == "abc<<def");
+	CPPUNIT_ASSERT(id2xml("abc>>def>") == "abc>>def>");
+	CPPUNIT_ASSERT(id2xml("abc&def&") == "abc&def&");
+	CPPUNIT_ASSERT(id2xml("'abc'def") == "'abc'def");
+	CPPUNIT_ASSERT(id2xml("\"abc\"def\"") == ""abc"def"");
+	// To get '\\' in a string both the backslashes must be escaped.
+	DBG(cerr << id2xml("octal escape: \\\\012") << endl);
+	CPPUNIT_ASSERT(id2xml("octal escape: \\\\012") == "octal escape: \\\\012");
+    }
+
+    void xml2id_test() {
+	CPPUNIT_ASSERT(xml2id("abcdef") == "abcdef");
+	CPPUNIT_ASSERT(xml2id("abc<def") == "abc<def");
+	CPPUNIT_ASSERT(xml2id("abc>def") == "abc>def");
+	CPPUNIT_ASSERT(xml2id("abc&def") == "abc&def");
+	CPPUNIT_ASSERT(xml2id("abc'def") == "abc'def");
+	CPPUNIT_ASSERT(xml2id("abc"def") == "abc\"def");
+	CPPUNIT_ASSERT(xml2id("abc<<def") == "abc<<def");
+	CPPUNIT_ASSERT(xml2id("abc>>def>") == "abc>>def>");
+	CPPUNIT_ASSERT(xml2id("abc&def&") == "abc&def&");
+	CPPUNIT_ASSERT(xml2id("'abc'def") == "'abc'def");
+	CPPUNIT_ASSERT(xml2id(""abc"def"") == "\"abc\"def\"");
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(generalUtilTest);
+
+int
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
+
+
diff --git a/unit-tests/marshT.cc b/unit-tests/marshT.cc
new file mode 100644
index 0000000..adaef90
--- /dev/null
+++ b/unit-tests/marshT.cc
@@ -0,0 +1,486 @@
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include "config.h"
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <iostream>
+#include <fstream>
+#include <cstring>
+
+#include "TestByte.h"
+#include "TestInt16.h"
+#include "TestInt32.h"
+#include "TestUInt16.h"
+#include "TestUInt32.h"
+#include "TestFloat32.h"
+#include "TestFloat64.h"
+#include "TestStr.h"
+#include "TestUrl.h"
+#include "TestArray.h"
+#include "TestStructure.h"
+#include "TestSequence.h"
+#include "DataDDS.h"
+#include "ConstraintEvaluator.h"
+#include "TestTypeFactory.h"
+#include "XDRFileMarshaller.h"
+#include "XDRStreamMarshaller.h"
+#include "XDRFileUnMarshaller.h"
+
+using std::cerr ;
+using std::cout ;
+using std::endl ;
+using std::ofstream ;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts. 
+
+class marshT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( marshT ) ;
+CPPUNIT_TEST( marshT_test ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+public:
+    void setUp()
+    {
+    }
+
+    void tearDown() 
+    {
+    }
+
+    void marshT_test()
+    {
+	TestByte b( "byte" ) ;
+	TestInt16 i16( "i16" ) ;
+	TestInt32 i32( "i32" ) ;
+	TestUInt16 ui16( "ui16" ) ;
+	TestUInt32 ui32( "ui32" ) ;
+	TestFloat32 f32( "f32" ) ;
+	TestFloat64 f64( "f64" ) ;
+	TestStr str( "str" ) ;
+	TestUrl url( "url" ) ;
+	TestByte ab( "ab" ) ;
+
+	TestArray arr( "arr", &ab ) ;
+	arr.append_dim( 5, "dim1" ) ;
+	arr.append_dim( 3, "dim2" ) ;
+
+	TestStructure s( "s" ) ;
+	s.add_var( &i32 ) ;
+	s.add_var( &str ) ;
+	Str *str_p = dynamic_cast<Str *>(s.var( "str" )) ;
+	s.add_var( &arr ) ;
+	s.set_send_p( true ) ;
+
+	ConstraintEvaluator eval ;
+	TestTypeFactory ttf ;
+	DataDDS dds( &ttf, "dds" ) ;
+
+	try
+	{
+	    cout << "serializing using XDRFileMarshaller" << endl ;
+	    FILE *f = fopen( "test.file", "w" ) ;
+	    XDRFileMarshaller fm( f ) ;
+	    cout << " file byte" << endl ;
+	    b.serialize( eval, dds, fm, false ) ;
+	    cout << " file int16" << endl ;
+	    i16.serialize( eval, dds, fm, false ) ;
+	    cout << " file int32" << endl ;
+	    i32.serialize( eval, dds, fm, false ) ;
+	    cout << " file uint16" << endl ;
+	    ui16.serialize( eval, dds, fm, false ) ;
+	    cout << " file uint32" << endl ;
+	    ui32.serialize( eval, dds, fm, false ) ;
+	    cout << " file float32" << endl ;
+	    f32.serialize( eval, dds, fm, false ) ;
+	    cout << " file float64" << endl ;
+	    f64.serialize( eval, dds, fm, false ) ;
+	    cout << " file str" << endl ;
+	    str.serialize( eval, dds, fm, false ) ;
+	    cout << " file url" << endl ;
+	    url.serialize( eval, dds, fm, false ) ;
+	    cout << " file structure" << endl ;
+	    s.serialize( eval, dds, fm, false ) ;
+	    cout << " file array" << endl ;
+	    arr.serialize( eval, dds, fm, false ) ;
+
+	    cout << " file sequence" << endl ;
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+	    seq2.set_send_p( true ) ;
+	    seq.add_var( &seq2 ) ;
+	    seq.set_send_p( true ) ;
+	    seq.set_leaf_sequence() ;
+	    seq.serialize( eval, dds, fm, false ) ;
+
+	    fclose( f ) ;
+	    cout << "done serializing using XDRFileMarshaller" << endl ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+
+	cout << s << endl ;
+
+	try
+	{
+	    cout << "serializing using XDRStreamMarshaller" << endl ;
+	    ofstream strm( "test.strm", ios::out|ios::trunc ) ;
+	    XDRStreamMarshaller sm( strm ) ;
+	    cout << " stream byte" << endl ;
+	    b.serialize( eval, dds, sm, false ) ;
+	    cout << " stream int16" << endl ;
+	    i16.serialize( eval, dds, sm, false ) ;
+	    cout << " stream int32" << endl ;
+	    i32.serialize( eval, dds, sm, false ) ;
+	    cout << " stream uint16" << endl ;
+	    ui16.serialize( eval, dds, sm, false ) ;
+	    cout << " stream uint32" << endl ;
+	    ui32.serialize( eval, dds, sm, false ) ;
+	    cout << " stream float32" << endl ;
+	    f32.serialize( eval, dds, sm, false ) ;
+	    cout << " stream float64" << endl ;
+	    f64.serialize( eval, dds, sm, false ) ;
+	    cout << " stream str" << endl ;
+	    str.serialize( eval, dds, sm, false ) ;
+	    cout << " stream url" << endl ;
+	    url.serialize( eval, dds, sm, false ) ;
+	    cout << " stream structure" << endl ;
+	    s.serialize( eval, dds, sm, false ) ;
+	    cout << " stream array" << endl ;
+	    arr.serialize( eval, dds, sm, false ) ;
+
+	    cout << " stream sequence" << endl ;
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+	    seq2.set_send_p( true ) ;
+	    seq.add_var( &seq2 ) ;
+	    seq.set_send_p( true ) ;
+	    seq.set_leaf_sequence() ;
+	    seq.serialize( eval, dds, sm, false ) ;
+
+	    strm.close() ;
+	    cout << "done serializing using XDRStreamMarshaller" << endl ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+
+	// now read the values in and compare the with each other and the original values
+	try
+	{
+	    cout << "deserializing XDRFileMarshaller built file" << endl ;
+	    FILE *ff = fopen( "test.file", "r" ) ;
+	    XDRFileUnMarshaller um( ff ) ;
+	    cout << " file byte" << endl ;
+	    Byte fb( "fb" ) ;
+	    fb.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fb.value() == b.value() ) ;
+	    cout << " file int16" << endl ;
+	    Int16 fi16( "i16" ) ;
+	    fi16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi16.value() == i16.value() ) ;
+	    cout << " file int32" << endl ;
+	    Int32 fi32( "i32" ) ;
+	    fi32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fi32.value() == i32.value() ) ;
+	    cout << " file uint16" << endl ;
+	    UInt16 fui16( "ui16" ) ;
+	    fui16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui16.value() == ui16.value() ) ;
+	    cout << " file uint32" << endl ;
+	    UInt32 fui32( "ui32" ) ;
+	    fui32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fui32.value() == ui32.value() ) ;
+	    cout << " file float32" << endl ;
+	    Float32 ff32( "f32" ) ;
+	    ff32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff32.value() == f32.value() ) ;
+	    cout << " file float64" << endl ;
+	    Float64 ff64( "f64" ) ;
+	    ff64.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( ff64.value() == f64.value() ) ;
+	    cout << " file str" << endl ;
+	    Str fstr( "str" ) ;
+	    fstr.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( fstr.value() == str.value() ) ;
+	    cout << " file url" << endl ;
+	    Url furl( "url" ) ;
+	    furl.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( furl.value() == url.value() ) ;
+
+	    cout << " file structure" << endl ;
+	    TestStructure fs( "fs" ) ;
+	    TestInt32 fsi32( "fsi32" ) ;
+	    fs.add_var( &fsi32 ) ;
+	    TestStr fsstr( "fsstr" ) ;
+	    fs.add_var( &fsstr ) ;
+	    TestByte fsab( "fsab" ) ;
+	    TestArray fsarr( "fsarr", &fsab ) ;
+	    fsarr.append_dim( 5, "dim1" ) ;
+	    fsarr.append_dim( 3, "dim2" ) ;
+	    fs.add_var( &fsarr ) ;
+	    fs.deserialize( um, &dds, false ) ;
+
+	    Int32 *fsi32_p = dynamic_cast<Int32 *>(fs.var( "fsi32" )) ;
+	    CPPUNIT_ASSERT( fsi32_p ) ;
+	    CPPUNIT_ASSERT( fsi32_p->value() == i32.value() ) ;
+
+	    Str *fsstr_p = dynamic_cast<Str *>(fs.var( "fsstr" )) ;
+	    CPPUNIT_ASSERT( fsstr_p ) ;
+	    CPPUNIT_ASSERT( fsstr_p->value() == str_p->value() ) ;
+
+	    BaseType *bt = fs.var( "fsab" ) ;
+	    CPPUNIT_ASSERT( bt ) ;
+	    Array *fsarr_p = dynamic_cast<Array *>(bt) ;
+	    CPPUNIT_ASSERT( fsarr_p ) ;
+	    dods_byte fdb[fsarr_p->length() * sizeof(dods_byte)] ;
+	    dods_byte db[arr.length() * sizeof(dods_byte)] ;
+	    fsarr_p->value( fdb ) ;
+	    arr.value( db ) ;
+	    CPPUNIT_ASSERT( fsarr_p->length() == arr.length() ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, fsarr_p->length() * sizeof( dods_byte ) ) ) ;
+
+	    cout << " file array" << endl ;
+	    TestByte fab( "ab" ) ;
+	    TestArray farr( "arr", &fab ) ;
+	    farr.append_dim( 5, "dim1" ) ;
+	    farr.append_dim( 3, "dim2" ) ;
+	    farr.deserialize( um, &dds, false ) ;
+	    farr.value( fdb ) ;
+	    CPPUNIT_ASSERT( farr.length() == arr.length() ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, farr.length() * sizeof( dods_byte ) ) ) ;
+
+	    cout << " file sequence" << endl ;
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+	    seq2.set_send_p( true ) ;
+	    seq.add_var( &seq2 ) ;
+	    seq.set_leaf_sequence() ;
+	    seq.deserialize( um, &dds, false ) ;
+	    unsigned int num_rows = seq.number_of_rows() ;
+	    CPPUNIT_ASSERT( num_rows == 4 ) ;
+	    for( unsigned int i = 0; i < num_rows; i++ )
+	    {
+		BaseTypeRow *row = seq.row_value( i ) ;
+		CPPUNIT_ASSERT( row ) ;
+		CPPUNIT_ASSERT( row->size() == 3 ) ;
+		Float64 *f64_p = dynamic_cast<Float64 *>((*row)[0]) ;
+		CPPUNIT_ASSERT( f64_p ) ;
+		CPPUNIT_ASSERT( f64_p->value() == f64.value() ) ;
+		Array *arr_p = dynamic_cast<Array *>((*row)[1]) ;
+		CPPUNIT_ASSERT( arr_p ) ;
+		arr_p->value( fdb ) ;
+		CPPUNIT_ASSERT( arr_p->length() == arr.length() ) ;
+		CPPUNIT_ASSERT( !memcmp( (void *)fdb, (void *)db, arr_p->length() * sizeof( dods_byte ) ) ) ;
+		Sequence *seq_p = dynamic_cast<Sequence *>((*row)[2]) ;
+		CPPUNIT_ASSERT( seq_p ) ;
+		unsigned int num_rows_sub = seq_p->number_of_rows() ;
+		CPPUNIT_ASSERT( num_rows == 4 ) ;
+		for( unsigned int j = 0; j < num_rows_sub; j++ )
+		{
+		    BaseTypeRow *row_sub = seq_p->row_value( j ) ;
+		    CPPUNIT_ASSERT( row_sub ) ;
+		    CPPUNIT_ASSERT( row_sub->size() == 2 ) ;
+		    UInt16 *ui16_p = dynamic_cast<UInt16 *>((*row_sub)[0]) ;
+		    CPPUNIT_ASSERT( ui16_p ) ;
+		    CPPUNIT_ASSERT( ui16_p->value() == ui16.value() ) ;
+		    Url *url_p = dynamic_cast<Url *>((*row_sub)[1]) ;
+		    CPPUNIT_ASSERT( url_p ) ;
+		    CPPUNIT_ASSERT( url_p->value() == url.value() ) ;
+		}
+	    }
+
+	    fclose( ff ) ;
+
+	    cout << "done deserializing XDRFileMarshaller built file" << endl ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+
+	try
+	{
+	    cout << "deserializing XDRStreamMarshaller built file" << endl ;
+	    FILE *sf = fopen( "test.strm", "r" ) ;
+	    XDRFileUnMarshaller um( sf ) ;
+	    cout << " stream byte" << endl ;
+	    Byte sb( "sb" ) ;
+	    sb.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( sb.value() == b.value() ) ;
+	    cout << " stream int16" << endl ;
+	    Int16 si16( "i16" ) ;
+	    si16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( si16.value() == i16.value() ) ;
+	    cout << " stream int32" << endl ;
+	    Int32 si32( "i32" ) ;
+	    si32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( si32.value() == i32.value() ) ;
+	    cout << " stream uint16" << endl ;
+	    UInt16 sui16( "ui16" ) ;
+	    sui16.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( sui16.value() == ui16.value() ) ;
+	    cout << " stream uint32" << endl ;
+	    UInt32 sui32( "ui32" ) ;
+	    sui32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( sui32.value() == ui32.value() ) ;
+	    cout << " stream float32" << endl ;
+	    Float32 sf32( "f32" ) ;
+	    sf32.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( sf32.value() == f32.value() ) ;
+	    cout << " stream float64" << endl ;
+	    Float64 sf64( "f64" ) ;
+	    sf64.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( sf64.value() == f64.value() ) ;
+	    cout << " stream str" << endl ;
+	    Str sstr( "str" ) ;
+	    sstr.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( sstr.value() == str.value() ) ;
+	    cout << " stream url" << endl ;
+	    Url surl( "url" ) ;
+	    surl.deserialize( um, &dds, false ) ;
+	    CPPUNIT_ASSERT( surl.value() == url.value() ) ;
+
+	    cout << " stream structure" << endl ;
+	    TestStructure ss( "ss" ) ;
+	    TestInt32 ssi32( "ssi32" ) ;
+	    ss.add_var( &ssi32 ) ;
+	    TestStr ssstr( "ssstr" ) ;
+	    ss.add_var( &ssstr ) ;
+	    TestByte ssab( "ssab" ) ;
+	    TestArray ssarr( "ssarr", &ssab ) ;
+	    ssarr.append_dim( 5, "dim1" ) ;
+	    ssarr.append_dim( 3, "dim2" ) ;
+	    ss.add_var( &ssarr ) ;
+	    ss.deserialize( um, &dds, false ) ;
+
+	    Int32 *ssi32_p = dynamic_cast<Int32 *>(ss.var( "ssi32" )) ;
+	    CPPUNIT_ASSERT( ssi32_p ) ;
+	    CPPUNIT_ASSERT( ssi32_p->value() == i32.value() ) ;
+
+	    Str *ssstr_p = dynamic_cast<Str *>(ss.var( "ssstr" )) ;
+	    CPPUNIT_ASSERT( ssstr_p ) ;
+	    CPPUNIT_ASSERT( ssstr_p->value() == str_p->value() ) ;
+
+	    BaseType *bt = ss.var( "ssab" ) ;
+	    CPPUNIT_ASSERT( bt ) ;
+	    Array *ssarr_p = dynamic_cast<Array *>(bt) ;
+	    CPPUNIT_ASSERT( ssarr_p ) ;
+	    dods_byte sdb[ssarr_p->length() * sizeof(dods_byte)] ;
+	    dods_byte db[arr.length() * sizeof(dods_byte)] ;
+	    ssarr_p->value( sdb ) ;
+	    arr.value( db ) ;
+	    CPPUNIT_ASSERT( ssarr_p->length() == arr.length() ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)sdb, (void *)db, ssarr_p->length() * sizeof( dods_byte ) ) ) ;
+
+	    cout << " stream array" << endl ;
+	    TestByte sab( "ab" ) ;
+	    TestArray sarr( "arr", &sab ) ;
+	    sarr.append_dim( 5, "dim1" ) ;
+	    sarr.append_dim( 3, "dim2" ) ;
+	    sarr.deserialize( um, &dds, false ) ;
+	    sarr.value( sdb ) ;
+	    CPPUNIT_ASSERT( sarr.length() == arr.length() ) ;
+	    CPPUNIT_ASSERT( !memcmp( (void *)sdb, (void *)db, sarr.length() * sizeof( dods_byte ) ) ) ;
+
+	    cout << " stream sequence" << endl ;
+	    TestSequence seq( "seq" ) ;
+	    seq.add_var( &f64 ) ;
+	    seq.add_var( &arr ) ;
+	    TestSequence seq2( "seq2" ) ;
+	    seq2.add_var( &ui16 ) ;
+	    seq2.add_var( &url ) ;
+	    seq2.set_send_p( true ) ;
+	    seq.add_var( &seq2 ) ;
+	    seq.set_leaf_sequence() ;
+	    seq.deserialize( um, &dds, false ) ;
+	    unsigned int num_rows = seq.number_of_rows() ;
+	    CPPUNIT_ASSERT( num_rows == 4 ) ;
+	    for( unsigned int i = 0; i < num_rows; i++ )
+	    {
+		BaseTypeRow *row = seq.row_value( i ) ;
+		CPPUNIT_ASSERT( row ) ;
+		CPPUNIT_ASSERT( row->size() == 3 ) ;
+		Float64 *f64_p = dynamic_cast<Float64 *>((*row)[0]) ;
+		CPPUNIT_ASSERT( f64_p ) ;
+		CPPUNIT_ASSERT( f64_p->value() == f64.value() ) ;
+		Array *arr_p = dynamic_cast<Array *>((*row)[1]) ;
+		CPPUNIT_ASSERT( arr_p ) ;
+		arr_p->value( sdb ) ;
+		CPPUNIT_ASSERT( arr_p->length() == arr.length() ) ;
+		CPPUNIT_ASSERT( !memcmp( (void *)sdb, (void *)db, arr_p->length() * sizeof( dods_byte ) ) ) ;
+		Sequence *seq_p = dynamic_cast<Sequence *>((*row)[2]) ;
+		CPPUNIT_ASSERT( seq_p ) ;
+		unsigned int num_rows_sub = seq_p->number_of_rows() ;
+		CPPUNIT_ASSERT( num_rows == 4 ) ;
+		for( unsigned int j = 0; j < num_rows_sub; j++ )
+		{
+		    BaseTypeRow *row_sub = seq_p->row_value( j ) ;
+		    CPPUNIT_ASSERT( row_sub ) ;
+		    CPPUNIT_ASSERT( row_sub->size() == 2 ) ;
+		    UInt16 *ui16_p = dynamic_cast<UInt16 *>((*row_sub)[0]) ;
+		    CPPUNIT_ASSERT( ui16_p ) ;
+		    CPPUNIT_ASSERT( ui16_p->value() == ui16.value() ) ;
+		    Url *url_p = dynamic_cast<Url *>((*row_sub)[1]) ;
+		    CPPUNIT_ASSERT( url_p ) ;
+		    CPPUNIT_ASSERT( url_p->value() == url.value() ) ;
+		}
+	    }
+
+	    fclose( sf ) ;
+
+	    cout << "done deserializing XDRStreamMarshaller built file" << endl ;
+	}
+	catch( Error &e )
+	{
+	    string err = "failed:" + e.get_error_message() ;
+	    CPPUNIT_FAIL( err.c_str() ) ;
+	}
+
+	unlink( "test.file" ) ;
+	unlink( "test.strm" ) ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( marshT ) ;
+
+int main(int, char **)
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( 
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
+
diff --git a/unit-tests/parserUtilTest.cc b/unit-tests/parserUtilTest.cc
new file mode 100644
index 0000000..e40a5d7
--- /dev/null
+++ b/unit-tests/parserUtilTest.cc
@@ -0,0 +1,145 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+// 
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+ 
+#include <cppunit/TextTestRunner.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "parser.h"
+
+using namespace CppUnit;
+using namespace libdap;
+
+class parserUtilTest : public TestFixture {
+private:
+
+public: 
+    parserUtilTest() {}
+    ~parserUtilTest() {}
+
+    void setUp() {
+    }
+
+    void tearDown() {
+    }
+
+    CPPUNIT_TEST_SUITE(parserUtilTest);
+
+    CPPUNIT_TEST(check_byte_test);
+    CPPUNIT_TEST(check_float32_test);
+    CPPUNIT_TEST(check_float64_test);
+
+    CPPUNIT_TEST_SUITE_END();
+
+    // Tests for methods
+    void check_byte_test() {
+	CPPUNIT_ASSERT(check_byte("255"));
+	CPPUNIT_ASSERT(!check_byte("256"));
+	CPPUNIT_ASSERT(check_byte("0"));
+	CPPUNIT_ASSERT(check_byte("-127"));
+	CPPUNIT_ASSERT(check_byte("-128"));
+	CPPUNIT_ASSERT(!check_byte("-129"));
+	CPPUNIT_ASSERT(!check_byte("-32767"));
+	CPPUNIT_ASSERT(!check_byte("32767"));
+    }
+
+    void check_float32_test() {
+	CPPUNIT_ASSERT(check_float32("1.0"));
+	CPPUNIT_ASSERT(check_float32("0.0"));
+	CPPUNIT_ASSERT(check_float32("-0.0"));
+	CPPUNIT_ASSERT(check_float32("+0.0"));
+	CPPUNIT_ASSERT(check_float32(".0"));
+
+	CPPUNIT_ASSERT(!check_float64("3.0.0"));
+	CPPUNIT_ASSERT(!check_float64("3..0"));
+
+	CPPUNIT_ASSERT(check_float32("3.402823466E+38"));
+	CPPUNIT_ASSERT(check_float32("-3.402823466E+38"));
+	CPPUNIT_ASSERT(check_float32("1.175494351E-38"));
+	CPPUNIT_ASSERT(check_float32("-1.175494351E-38"));
+
+	CPPUNIT_ASSERT(check_float32("NaN"));
+	CPPUNIT_ASSERT(check_float32("nan"));
+	CPPUNIT_ASSERT(check_float32("Nan"));
+
+	CPPUNIT_ASSERT(!check_float32("3.502823466E+38"));
+	CPPUNIT_ASSERT(!check_float32("-3.502823466E+38"));
+	CPPUNIT_ASSERT(!check_float32("1.0E-38"));
+	CPPUNIT_ASSERT(!check_float32("-1.0E-38"));
+
+	CPPUNIT_ASSERT(!check_float32("1.7976931348623157E+308"));
+	CPPUNIT_ASSERT(!check_float32("-1.7976931348623157E+308"));
+	CPPUNIT_ASSERT(!check_float32("2.2250738585072014E-308"));
+	CPPUNIT_ASSERT(!check_float32("-2.2250738585072014E-308"));
+    }
+	
+    void check_float64_test() {
+	CPPUNIT_ASSERT(check_float64("1.0"));
+	CPPUNIT_ASSERT(check_float64("0.0"));
+	CPPUNIT_ASSERT(check_float64("-0.0"));
+	CPPUNIT_ASSERT(check_float64("+0.0"));
+	CPPUNIT_ASSERT(check_float64(".0"));
+
+	CPPUNIT_ASSERT(!check_float64("3.0.0"));
+	CPPUNIT_ASSERT(!check_float64("3..0"));
+
+	CPPUNIT_ASSERT(check_float64("3.402823466E+38"));
+	CPPUNIT_ASSERT(check_float64("-3.402823466E+38"));
+	CPPUNIT_ASSERT(check_float64("1.175494351E-38"));
+	CPPUNIT_ASSERT(check_float64("-1.175494351E-38"));
+
+	CPPUNIT_ASSERT(check_float64("1.7976931348623157E+308"));
+	CPPUNIT_ASSERT(check_float64("-1.7976931348623157E+308"));
+	CPPUNIT_ASSERT(check_float64("2.2250738585072014E-308"));
+	CPPUNIT_ASSERT(check_float64("-2.2250738585072014E-308"));
+
+	CPPUNIT_ASSERT(check_float64("NaN"));
+	CPPUNIT_ASSERT(check_float64("nan"));
+	CPPUNIT_ASSERT(check_float64("Nan"));
+
+	CPPUNIT_ASSERT(!check_float64("255E400"));
+	CPPUNIT_ASSERT(!check_float64("255E-400"));
+
+	CPPUNIT_ASSERT(!check_float64("1.8E+308"));
+	CPPUNIT_ASSERT(!check_float64("-1.8E+308"));
+	CPPUNIT_ASSERT(!check_float64("2.0E-308"));
+	CPPUNIT_ASSERT(!check_float64("-2.0E-308"));
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION(parserUtilTest);
+
+int 
+main( int, char** )
+{
+    CppUnit::TextTestRunner runner;
+    runner.addTest( CppUnit::TestFactoryRegistry::getRegistry().makeTest() );
+
+    bool wasSuccessful = runner.run( "", false ) ;
+
+    return wasSuccessful ? 0 : 1;
+}
+
+
diff --git a/unit-tests/rcreader-testsuite/dodsrc_ssl_1 b/unit-tests/rcreader-testsuite/dodsrc_ssl_1
new file mode 100644
index 0000000..f9bf167
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/dodsrc_ssl_1
@@ -0,0 +1,17 @@
+# OPeNDAP client configuation file. See the OPeNDAP
+# users guide for information.
+USE_CACHE=0
+# Cache and object size are given in megabytes (20 ==> 20Mb).
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=0
+# Proxy configuration:
+# PROXY_SERVER=<protocol>,<[username:password@]host[:port]>
+# NO_PROXY_FOR=<protocol>,<host|domain>
+# AIS_DATABASE=<file or url>
diff --git a/unit-tests/rcreader-testsuite/dodsrc_ssl_2 b/unit-tests/rcreader-testsuite/dodsrc_ssl_2
new file mode 100644
index 0000000..ff97c71
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/dodsrc_ssl_2
@@ -0,0 +1,19 @@
+# OPeNDAP client configuation file. See the OPeNDAP
+# users guide for information.
+USE_CACHE=0
+# Cache and object size are given in megabytes (20 ==> 20Mb).
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=0
+# blah
+VALIDATE_SSL=1
+# Proxy configuration:
+# PROXY_SERVER=<protocol>,<[username:password@]host[:port]>
+# NO_PROXY_FOR=<protocol>,<host|domain>
+# AIS_DATABASE=<file or url>
diff --git a/unit-tests/rcreader-testsuite/dodsrc_ssl_3 b/unit-tests/rcreader-testsuite/dodsrc_ssl_3
new file mode 100644
index 0000000..92ff105
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/dodsrc_ssl_3
@@ -0,0 +1,19 @@
+# OPeNDAP client configuation file. See the OPeNDAP
+# users guide for information.
+USE_CACHE=0
+# Cache and object size are given in megabytes (20 ==> 20Mb).
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=0
+# blah
+VALIDATE_SSL=0
+# Proxy configuration:
+# PROXY_SERVER=<protocol>,<[username:password@]host[:port]>
+# NO_PROXY_FOR=<protocol>,<host|domain>
+# AIS_DATABASE=<file or url>
diff --git a/unit-tests/rcreader-testsuite/test1.rc b/unit-tests/rcreader-testsuite/test1.rc
new file mode 100644
index 0000000..471f6e8
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/test1.rc
@@ -0,0 +1,19 @@
+# Test DODS client configuation file.
+USE_CACHE=0
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=1
+
+# Proxy configuration:
+# PROXY_SERVER=<protocol>,<host[:port]>
+PROXY_SERVER=http,jimg:mypass at proxy.local.org:8080
+
+NO_PROXY_FOR=http,local.org
+
+# AIS_DATABASE=<file or url>
diff --git a/unit-tests/rcreader-testsuite/test2.rc b/unit-tests/rcreader-testsuite/test2.rc
new file mode 100644
index 0000000..3a66329
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/test2.rc
@@ -0,0 +1,16 @@
+# Test DODS client configuation file.
+USE_CACHE=0
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=1
+
+# Proxy configuration:
+# PROXY_SERVER=<protocol>,<host[:port]>
+PROXY_SERVER=http,proxy.local.org
+
diff --git a/unit-tests/rcreader-testsuite/test3.rc b/unit-tests/rcreader-testsuite/test3.rc
new file mode 100644
index 0000000..6b1800b
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/test3.rc
@@ -0,0 +1,17 @@
+# Test DODS client configuation file.
+USE_CACHE=0
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=1
+
+# Proxy configuration:
+# PROXY_SERVER=<protocol>,<host[:port]>
+PROXY_SERVER=smtp,error:error at proxy.local.org
+
+# AIS_DATABASE=<file or url>
diff --git a/unit-tests/rcreader-testsuite/test4.rc b/unit-tests/rcreader-testsuite/test4.rc
new file mode 100644
index 0000000..11dc84f
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/test4.rc
@@ -0,0 +1,19 @@
+# Test DODS client configuation file.
+USE_CACHE=0
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=1
+
+# Proxy configuration:
+# An alternative form of the PROXY_SERVER that's more intuitive is to not
+# have the protocol given using a comma-separated clause but to include it as
+# part of the host name. Here we test for a mixture of the notations. The new
+# syntax to support is [<protocol>,][http://][user:pw@]host[:port].
+PROXY_SERVER=jimg:test at proxy.local.org:3128
+
diff --git a/unit-tests/rcreader-testsuite/test5.rc b/unit-tests/rcreader-testsuite/test5.rc
new file mode 100644
index 0000000..b4d4800
--- /dev/null
+++ b/unit-tests/rcreader-testsuite/test5.rc
@@ -0,0 +1,19 @@
+# Test DODS client configuation file.
+USE_CACHE=0
+MAX_CACHE_SIZE=20
+MAX_CACHED_OBJ=5
+IGNORE_EXPIRES=0
+CACHE_ROOT=/home/jimg/.dods_cache/
+DEFAULT_EXPIRES=86400
+ALWAYS_VALIDATE=0
+# Request servers compress responses if possible?
+# 1 (yes) or 0 (false).
+DEFLATE=1
+
+# Proxy configuration:
+# An alternative form of the PROXY_SERVER that's more intuitive is to not
+# have the protocol given using a comma-separated clause but to include it as
+# part of the host name. Here we test for a mixture of the notations. The new
+# syntax to support is [<protocol>,][http://][user:pw@]host[:port].
+PROXY_SERVER=http://jimg:test@proxy.local.org:3128
+
diff --git a/unit-tests/sequenceT.cc b/unit-tests/sequenceT.cc
new file mode 100644
index 0000000..f0fe747
--- /dev/null
+++ b/unit-tests/sequenceT.cc
@@ -0,0 +1,143 @@
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include <iostream>
+#include "TestSequence.h"
+#include "TestInt16.h"
+#include "TestStr.h"
+#include "TestTypeFactory.h"
+#include "util.h"
+//#include "Pix.h"
+
+using std::cerr ;
+using std::endl ;
+
+using namespace libdap ;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts. 
+class sequenceT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( sequenceT ) ;
+CPPUNIT_TEST( sequenceT_test ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+private:
+    /* TEST PRIVATE DATA */
+    TestTypeFactory *factory;
+    
+public:
+    void setUp()
+    {
+        factory = new TestTypeFactory;
+    }
+
+    void tearDown() 
+    {
+        delete factory; factory = 0;
+    }
+
+    void sequenceT_test()
+    {
+	TestSequence s( "Supporters" ) ;
+
+	BaseType *nm = factory->NewStr( "Name" ) ;
+	s.add_var( nm ) ;
+
+	BaseType *age = factory->NewInt16( "Age" ) ;
+	s.add_var( age ) ;
+
+	TestSequence *friends = (TestSequence *)factory->NewSequence( "Friends" ) ;
+	friends->add_var( nm ) ;
+	delete nm ; nm = 0 ;
+	friends->add_var( age ) ;
+	delete age ; age = 0 ;
+	s.add_var( friends ) ;
+	delete friends ; friends = 0 ;
+
+	BaseType *bt = s.var( "Age" ) ;
+	CPPUNIT_ASSERT( bt->name( ) == "Age" ) ;
+
+	bt = s.var( "Age", false ) ;
+	CPPUNIT_ASSERT( bt->name( ) == "Age" ) ;
+
+	BaseType::btp_stack btps ;
+	bt = s.var( "Friends.Age", btps ) ;
+	CPPUNIT_ASSERT( bt->name( ) == "Age" ) ;
+	CPPUNIT_ASSERT( btps.size( ) == 2 ) ;
+
+	vector<string> names ;
+	names.push_back( "Friends" ) ;
+	names.push_back( "Supporters" ) ;
+	typedef vector<string>::const_iterator names_iter ;
+	names_iter n = names.begin( ) ;
+	while( !btps.empty( ) && n != names.end( ) )
+	{
+	    BaseType *curr = btps.top( ) ;
+	    CPPUNIT_ASSERT( curr->name( ) == (*n) ) ;
+	    btps.pop( ) ;
+	    n++ ;
+	}
+
+	int num_elems = s.element_count( false ) ;
+	CPPUNIT_ASSERT( num_elems == 3 ) ;
+
+	num_elems = s.element_count( true ) ;
+	CPPUNIT_ASSERT( num_elems == 4 ) ;
+
+#if 0
+	// This is only true on 32 bit machines, on a 64bit machine is will
+	// probably be 24.
+	unsigned int w = s.width( ) ;
+	CPPUNIT_ASSERT( w == 12 ) ;
+#endif
+
+	vector<string> elems ;
+	elems.push_back( "Name" ) ;
+	elems.push_back( "Age" ) ;
+	elems.push_back( "Friends" ) ;
+	typedef vector<string>::const_iterator elems_iter ;
+
+	Sequence::Vars_iter v = s.var_begin() ;
+	elems_iter e = elems.begin() ;
+	for( ; v != s.var_end() && e != elems.end(); v++, e++ )
+	{
+	    CPPUNIT_ASSERT( (*v)->name() == (*e) ) ;
+	}
+	CPPUNIT_ASSERT( v == s.var_end() && e == elems.end() ) ;
+	if( v != s.var_end() && e == elems.end() )
+	{
+	    CPPUNIT_FAIL( "Too many elements" ) ;
+	}
+	else if( v == s.var_end() && e != elems.end() )
+	{
+	    CPPUNIT_FAIL( "Too few elements" ) ;
+	}
+
+	int num_rows = s.number_of_rows( ) ;
+	CPPUNIT_ASSERT( num_rows == 0 ) ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( sequenceT ) ;
+
+/* NOTHING NEEDS TO BE CHANGED BELOW HERE */
+
+int main( int, char ** )
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( 
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/server-testsuite/bears.data b/unit-tests/server-testsuite/bears.data
new file mode 100644
index 0000000..838cdff
--- /dev/null
+++ b/unit-tests/server-testsuite/bears.data
@@ -0,0 +1,9 @@
+The data:
+Grid {
+ ARRAY:
+    String bears[i = 2][j = 3][l = 3];
+ MAPS:
+    Int32 i[i = 2];
+    Float32 j[j = 3];
+    Int16 l[l = 3];
+} bears = { ARRAY: {{{"i", "n", "d"},{"i", "s", "t"},{"i", "n", "g"}},{{"u", "i", "s"},{"h", "a", "b"},{"l", "e", ""}}} MAPS: {10, 20}, {2, 4, 6}, {10, 9, 8} };
diff --git a/unit-tests/server-testsuite/coads.data b/unit-tests/server-testsuite/coads.data
new file mode 100644
index 0000000..effe360
--- /dev/null
+++ b/unit-tests/server-testsuite/coads.data
@@ -0,0 +1 @@
+ncddsserver:couldnotopenfile/usr/local/spool/http/data/coads_climatology.nc
\ No newline at end of file
diff --git a/unit-tests/server-testsuite/coads.data.das b/unit-tests/server-testsuite/coads.data.das
new file mode 100644
index 0000000..32c9c4d
--- /dev/null
+++ b/unit-tests/server-testsuite/coads.data.das
@@ -0,0 +1,6 @@
+Attributes{
+    DODS_GLOBAL {
+	String About "This is used to test find_ancillary_das()";
+    }
+}
+
diff --git a/unit-tests/server-testsuite/config/unix.exp b/unit-tests/server-testsuite/config/unix.exp
new file mode 100644
index 0000000..5e4e223
--- /dev/null
+++ b/unit-tests/server-testsuite/config/unix.exp
@@ -0,0 +1,48 @@
+
+# Tcl/Expect code for the geturl test. This really is designed to test the
+# various servers (hdf, dsp, netcdf, matlab, ...) on serveral different
+# platforms. 
+# 
+# $Id: unix.exp 11906 2005-08-08 19:51:43Z root $
+
+# Make sure the global var GETURL is set correctly.
+
+global GETURL
+if ![info exists GETURL] then {
+    set GETURL [transform ./geturl]
+}
+
+# The four `required' procs are _start, _load, _exit and _version.
+
+proc geturl_start { {switches ""} {urls ""} {file ""}} {
+    global verbose
+    global GETURL
+    global comp_output
+    global spawn_id
+
+    if ![string compare $file ""] {
+	if {$verbose >= 1} {
+	    send_user "Testing geturl $switches $urls ...\n"
+	    exp_internal 1
+	}
+	catch "exec $GETURL $switches $urls" comp_output
+    } else {
+	if {$verbose >= 1} {
+	    send_user "Testing geturl $switches $urls >& $file ...\n"
+	    exp_internal 1
+	}
+	catch "exec $GETURL $switches $urls > $file" comp_output
+    }
+}
+
+proc geturl_load {} {
+}
+
+proc geturl_exit {} {
+    send -raw ""
+}
+
+proc geturl_version {} {
+    send_user "geturl test suite 1.0\n"
+}
+
diff --git a/unit-tests/server-testsuite/dsp_1.data b/unit-tests/server-testsuite/dsp_1.data
new file mode 100644
index 0000000..d253666
--- /dev/null
+++ b/unit-tests/server-testsuite/dsp_1.data
@@ -0,0 +1,2 @@
+The data:
+Byte dsp_band_1[line = 11][pixel = 11] = {{162, 156, 152, 162, 159, 152, 147, 165, 159, 156, 150},{155, 160, 155, 150, 154, 156, 151, 150, 151, 144, 160},{159, 164, 154, 159, 156, 161, 149, 149, 149, 150, 156},{144, 161, 165, 149, 157, 151, 145, 146, 149, 146, 152},{151, 159, 158, 156, 149, 151, 145, 145, 149, 147, 151},{150, 152, 159, 163, 158, 148, 150, 145, 145, 145, 148},{154, 154, 148, 145, 153, 153, 149, 146, 144, 148, 148},{157, 133, 147, 147, 157, 150, 150, 148, 148, 148, 148},{1 [...]
diff --git a/unit-tests/server-testsuite/ff_test1_ce1.data b/unit-tests/server-testsuite/ff_test1_ce1.data
new file mode 100644
index 0000000..fdfc8ab
--- /dev/null
+++ b/unit-tests/server-testsuite/ff_test1_ce1.data
@@ -0,0 +1,5 @@
+The data:
+Sequence {
+    Int32 year;
+} JPL_Pathfinder = { { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { [...]
+
diff --git a/unit-tests/server-testsuite/ff_test1_ce2.data b/unit-tests/server-testsuite/ff_test1_ce2.data
new file mode 100644
index 0000000..fdfc8ab
--- /dev/null
+++ b/unit-tests/server-testsuite/ff_test1_ce2.data
@@ -0,0 +1,5 @@
+The data:
+Sequence {
+    Int32 year;
+} JPL_Pathfinder = { { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { [...]
+
diff --git a/unit-tests/server-testsuite/ff_test2_ce1.data b/unit-tests/server-testsuite/ff_test2_ce1.data
new file mode 100644
index 0000000..a9ac078
--- /dev/null
+++ b/unit-tests/server-testsuite/ff_test2_ce1.data
@@ -0,0 +1,5 @@
+The data:
+Sequence {
+    Int32 year;
+} JPL%20Pathfinder = { { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, [...]
+
diff --git a/unit-tests/server-testsuite/ff_test2_ce2.data b/unit-tests/server-testsuite/ff_test2_ce2.data
new file mode 100644
index 0000000..a9ac078
--- /dev/null
+++ b/unit-tests/server-testsuite/ff_test2_ce2.data
@@ -0,0 +1,5 @@
+The data:
+Sequence {
+    Int32 year;
+} JPL%20Pathfinder = { { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, [...]
+
diff --git a/unit-tests/server-testsuite/ff_test2_ce3.data b/unit-tests/server-testsuite/ff_test2_ce3.data
new file mode 100644
index 0000000..a9ac078
--- /dev/null
+++ b/unit-tests/server-testsuite/ff_test2_ce3.data
@@ -0,0 +1,5 @@
+The data:
+Sequence {
+    Int32 year;
+} JPL%20Pathfinder = { { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, { 1985 }, [...]
+
diff --git a/unit-tests/server-testsuite/fnoc1.data b/unit-tests/server-testsuite/fnoc1.data
new file mode 100644
index 0000000..0d5d9ce
--- /dev/null
+++ b/unit-tests/server-testsuite/fnoc1.data
@@ -0,0 +1,2 @@
+The data:
+Int16 u[time_a = 1][lat = 10][lon = 10] = {{{-1728, -2449, -3099, -3585, -3254, -2406, -1252, 662, 2483, 2910},{-1686, -1985, -2508, -3397, -3501, -3268, -2700, -705, 1834, 2728},{-223, -864, -864, -1152, -1427, -1717, -1992, -1211, 791, 2235},{1924, 1664, 1555, 1551, 1190, 430, -459, -453, 914, 2055},{2869, 3660, 3561, 3069, 2378, 1453, 601, 479, 953, 1237},{2012, 2885, 3172, 2734, 2141, 1453, 795, 420, -98, -415},{685, 1311, 1566, 1458, 1174, 762, 327, -113, -779, -1281},{-135, 336, 40 [...]
diff --git a/unit-tests/server-testsuite/geturl.0/dodsdev.exp b/unit-tests/server-testsuite/geturl.0/dodsdev.exp
new file mode 100644
index 0000000..2077db9
--- /dev/null
+++ b/unit-tests/server-testsuite/geturl.0/dodsdev.exp
@@ -0,0 +1,102 @@
+
+# Copy this file and change the host name and/or the test_dir names to test
+# servers on other hosts or other versions of the servers.
+
+# $Log: dodsdev.exp,v $
+# Revision 1.6  2005/05/23 16:07:06  jimg
+# Now uses local common-tests.exp and test.opendap.org.
+#
+# Revision 1.5  2005/03/30 23:12:02  jimg
+# Modified to use the new factory class.
+#
+# Revision 1.4  2003/12/11 01:08:38  jimg
+# More fixes after resolving conflicts. This code still fails some tests.
+#
+# Revision 1.3.2.1  2003/11/19 18:56:30  jimg
+# Switched back to dodsdev & remote access.
+#
+# Revision 1.3  2003/04/22 19:40:30  jimg
+# Merged with 3.3.1.
+#
+# Revision 1.2.2.1  2003/04/18 03:37:30  jimg
+# Set the host to localhost and the test dir to dods-test (the current
+# release).
+#
+# Revision 1.2  2002/06/03 22:21:17  jimg
+# Merged with release-3-2-9
+#
+# Revision 1.1.2.1  2002/04/16 17:07:20  jimg
+# Added/Fixed tests so that they use the client test data collection on
+# dodsdev. This data collection will form the basis for all the client
+# testing.
+#
+# Revision 1.2.46.2  2001/07/28 01:12:29  jimg
+# Updated to work with the new escaping code. Some of our tests assumed
+# that dashes (-) were not OK in symbol names. However, changes in the
+# DAP parsers along with changes in the escaping functions now make this
+# possible.
+#
+# Revision 1.2.46.1  2001/05/03 20:26:43  jimg
+# These are now more configurable.
+#
+# Revision 1.2  1997/09/22 23:14:45  jimg
+# *** empty log message ***
+#
+
+global comp_output		# contains output from das-test_start
+global verbose			# this and srcdir are set by runtest.exp
+global srcdir
+global host
+
+source common_tests.exp
+
+# Server machine name
+set host "test.opendap.org"
+# set host "localhost"
+# CGI directory on $host
+set test_dir "dods-3.4"
+
+source "server-testsuite/geturl.0/urls.tcl"
+
+set test_name "dodedev"
+
+# The `1' in compare_stdout means call xfail if the test fails.
+
+geturl_start "-D" "${bears}?${bears_ce}"
+compare_stdout "server-testsuite/bears.data" "${test_name}: NetCDF/bears"
+
+geturl_start "-D" "${fnoc1}?${fnoc1_ce}"
+compare_stdout "server-testsuite/fnoc1.data" "$test_name: NetCDF/fnoc1"
+
+geturl_start "-D" "${dsp_1}?${dsp_1_ce}"
+compare_stdout "server-testsuite/dsp_1.data" "$test_name: DSP"
+
+geturl_start "-D" "${nscat_s2}?${nscat_s2_ce}"
+compare_stdout "server-testsuite/nscat_s2.data" "$test_name: Matlab"
+
+geturl_start "-D" "${nscat_hdf}?${nscat_hdf_ce}"
+compare_stdout "server-testsuite/nscat_hdf.data" "$test_name: HDF"
+
+geturl_start "-D" "${jg_test}?${jg_test_ce}"
+compare_stdout "server-testsuite/jg_test.data" "$test_name: JGOFS"
+
+geturl_start "-d" "${ff_test1}"
+compare_stdout $ff_test1_dds "$test_name: FF DDS check"
+
+geturl_start "-D" "${ff_test1}?${ff_test1_ce1}"
+compare_stdout "server-testsuite/ff_test1_ce1.data" "$test_name: FF"
+
+geturl_start "-D" "${ff_test1}?${ff_test1_ce2}"
+compare_stdout "server-testsuite/ff_test1_ce2.data" "$test_name: FF, compund name"
+
+geturl_start "-d" "${ff_test2}"
+compare_stdout $ff_test2_dds "$test_name: FF DDS check"
+
+geturl_start "-D" "${ff_test2}?${ff_test2_ce1}"
+compare_stdout "server-testsuite/ff_test2_ce1.data" "$test_name: FF"
+
+geturl_start "-D" "${ff_test2}?${ff_test2_ce2}"
+compare_stdout "server-testsuite/ff_test2_ce2.data" "$test_name: FF, compund name, with escaped space"
+
+geturl_start "-D" "\"${ff_test2}?${ff_test2_ce3}\""
+compare_stdout "server-testsuite/ff_test2_ce3.data" "$test_name: FF, compund name, with unescaped space"
diff --git a/unit-tests/server-testsuite/geturl.0/urls.tcl b/unit-tests/server-testsuite/geturl.0/urls.tcl
new file mode 100644
index 0000000..ee88d8a
--- /dev/null
+++ b/unit-tests/server-testsuite/geturl.0/urls.tcl
@@ -0,0 +1,275 @@
+
+# $Id: urls.tcl 11906 2005-08-08 19:51:43Z root $
+
+# Datasets and their expected output (the information that writeval sends to
+# stdout - not the stuff that should be going into the file).
+
+# URI/BEARS:
+set bears "http://$host/$test_dir/nph-dods/data/nc/bears.nc"
+set bears_ce "bears"
+set bears_dds "Dataset {
+    Grid {
+     ARRAY:
+        String bears\[i = 2\]\[j = 3\]\[l = 3\];
+     MAPS:
+        Int32 i\[i = 2\];
+        Float64 j\[j = 3\];
+        Int32 l\[l = 3\];
+    } bears;
+    Grid {
+     ARRAY:
+        Int32 order\[i = 2\]\[j = 3\];
+     MAPS:
+        Int32 i\[i = 2\];
+        Float64 j\[j = 3\];
+    } order;
+    Grid {
+     ARRAY:
+        Int32 shot\[i = 2\]\[j = 3\];
+     MAPS:
+        Int32 i\[i = 2\];
+        Float64 j\[j = 3\];
+    } shot;
+    Grid {
+     ARRAY:
+        Float64 aloan\[i = 2\]\[j = 3\];
+     MAPS:
+        Int32 i\[i = 2\];
+        Float64 j\[j = 3\];
+    } aloan;
+    Grid {
+     ARRAY:
+        Float64 cross\[i = 2\]\[j = 3\];
+     MAPS:
+        Int32 i\[i = 2\];
+        Float64 j\[j = 3\];
+    } cross;
+    Int32 i\[i = 2\];
+    Float64 j\[j = 3\];
+    Int32 l\[l = 3\];
+} bears;"
+
+# URI/FNOC
+set fnoc1 "http://$host/$test_dir/nph-dods/data/nc/fnoc1.nc"
+set fnoc1_ce "u\\\[0:0\\\]\\\[0:9\\\]\\\[0:9\\\]"
+set fnoc1_dds "Dataset {
+    Int32 u\[time_a = 16\]\[lat = 17\]\[lon = 21\];
+    Int32 v\[time_a = 16\]\[lat = 17\]\[lon = 21\];
+    Float64 lat\[lat = 17\];
+    Float64 lon\[lon = 21\];
+    Float64 time\[time = 16\];
+} fnoc1;"
+
+# URI/DSP:
+set dsp_1 "http://$host/$test_dir/nph-dods/data/dsp/east.coast.pvu"
+set dsp_1_ce "dsp_band_1\\\[20:30\\\]\\\[20:30\\\]"
+set dsp_1_dds "Dataset {
+    Byte dsp_band_1\\\[line = 512\\\]\\\[pixel = 512\\\];
+} east.coast.pvu;"
+
+# URI/MatLab:
+set nscat_s2 "http://$host/$test_dir/nph-dods/data/mat/NSCAT_S2.mat"
+set nscat_s2_ce "NSCAT_S2\\\[75:75\\\]\\\[0:5\\\]"
+set nscat_s2_dds "Dataset {
+    Float64 NSCAT_S2\[NSCAT_S2_row = 153\]\[NSCAT_S2_column = 843\];
+} NSCAT_S2;"
+
+# URI/NSCAT:
+set nscat_hdf "http://$host/$test_dir/nph-dods/data/hdf/S2000415.HDF"
+set nscat_hdf_ce "WVC_Lat\\\[200:201\\\]\\\[20:21\\\]"
+set nscat_hdf_dds "Dataset {
+    Int32 WVC_Lat\[row = 458\]\[WVC = 24\];
+    UInt32 WVC_Lon\[row = 458\]\[WVC = 24\];
+    UInt32 Num_Sigma0\[row = 458\]\[WVC = 24\];
+    UInt32 Num_Beam_12\[row = 458\]\[WVC = 24\];
+    UInt32 Num_Beam_34\[row = 458\]\[WVC = 24\];
+    UInt32 Num_Beam_56\[row = 458\]\[WVC = 24\];
+    UInt32 Num_Beam_78\[row = 458\]\[WVC = 24\];
+    UInt32 WVC_Quality_Flag\[row = 458\]\[WVC = 24\];
+    UInt32 Mean_Wind\[row = 458\]\[WVC = 24\];
+    UInt32 Wind_Speed\[row = 458\]\[WVC = 24\]\[position = 4\];
+    UInt32 Wind_Dir\[row = 458\]\[WVC = 24\]\[position = 4\];
+    UInt32 Error_Speed\[row = 458\]\[WVC = 24\]\[position = 4\];
+    UInt32 Error_Dir\[row = 458\]\[WVC = 24\]\[position = 4\];
+    Int32 MLE_Likelihood\[row = 458\]\[WVC = 24\]\[position = 4\];
+    UInt32 Num_Ambigs\[row = 458\]\[WVC = 24\];
+    Sequence {
+        Structure {
+            Int32 begin__0;
+        } begin;
+    } SwathIndex;
+    Sequence {
+        Structure {
+            String Mean_Time__0;
+        } Mean_Time;
+        Structure {
+            UInt32 Low_Wind_Speed_Flag__0;
+        } Low_Wind_Speed_Flag;
+        Structure {
+            UInt32 High_Wind_Speed_Flag__0;
+        } High_Wind_Speed_Flag;
+    } NSCAT%20L2;
+} S2000415%2eHDF;"
+
+# URI/NSCAT Level 3 - here to test grids with the hdf server.
+set nscat_l3 "http://$host/$test_dir/nph-dods/data/hdf/S3097057.HDF"
+set nscat_l3_ce1 "WVC_Count\\\[200:201\\\]\\\[20:119\\\]"
+set nscat_l3_ce2 "Avg_Wind_Vel_U\\\[200:201\\\]\\\[20:119\\\]"
+set nscat_l3_dds "Dataset {
+    Grid {
+     ARRAY:
+        UInt32 WVC_Count\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } WVC_Count;
+    Grid {
+     ARRAY:
+        UInt32 Map_Day_Fraction\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Map_Day_Fraction;
+    Grid {
+     ARRAY:
+        UInt32 Avg_Sigma0_Count\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Avg_Sigma0_Count;
+    Grid {
+     ARRAY:
+        Int32 Avg_Wind_Vel_U\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Avg_Wind_Vel_U;
+    Grid {
+     ARRAY:
+        Int32 Avg_Wind_Vel_V\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Avg_Wind_Vel_V;
+    Grid {
+     ARRAY:
+        UInt32 Avg_Wind_Speed\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Avg_Wind_Speed;
+    Grid {
+     ARRAY:
+        UInt32 RMS_Wind_Speed\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } RMS_Wind_Speed;
+    Grid {
+     ARRAY:
+        UInt32 Map_Day_Fraction_StdDev\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Map_Day_Fraction_StdDev;
+    Grid {
+     ARRAY:
+        UInt32 Wind_Vel_U_StdDev\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Wind_Vel_U_StdDev;
+    Grid {
+     ARRAY:
+        UInt32 Wind_Vel_V_StdDev\[row = 300\]\[column = 720\];
+     MAPS:
+        Float64 row\[300\];
+        Float64 column\[720\];
+    } Wind_Vel_V_StdDev;
+    Sequence {
+        Structure {
+            String bin_meth__0;
+        } bin_meth;
+        Structure {
+            String grid_origin__0;
+        } grid_origin;
+        Structure {
+            Float64 hsize__0;
+        } hsize;
+        Structure {
+            Int32 max_east__0;
+        } max_east;
+        Structure {
+            Int32 max_north__0;
+        } max_north;
+        Structure {
+            Int32 max_south__0;
+        } max_south;
+        Structure {
+            Int32 max_west__0;
+        } max_west;
+        Structure {
+            String registration__0;
+        } registration;
+        Structure {
+            Float64 vsize__0;
+        } vsize;
+    } Lat%2fLon;
+} S3097057%2eHDF;"
+
+# URI/JGOFS:
+set jg_test "http://$host/$test_dir/nph-dods/test"
+set jg_test_ce "year,month,lat,lon,sal&lat>37.5&lat<38.0"
+set jg_test_dds "Dataset {
+    Sequence {
+        String leg;
+        String year;
+        String month;
+        Sequence {
+            String station;
+            String lat;
+            String lon;
+            Sequence {
+                String press;
+                String temp;
+                String sal;
+                String o2;
+                String sigth;
+            } Level_2;
+        } Level_1;
+    } Level_0;
+} test;"
+
+# FF server tests. These also test asking for stuff when the variable names
+# contain spaces. 7/26/2001 jhrg
+
+set ff_test1 "http://$host/$test_dir/nph-dods/data/ff/jplpath.dat"
+set ff_test1_ce1 "year"
+set ff_test1_ce2 "JPL_Pathfinder.year"
+set ff_test1_dds "Dataset {
+    Sequence {
+        Int32 year;
+        Int32 day;
+        Int32 hours;
+        Int32 minutes;
+        Int32 seconds;
+        String DODS_URL;
+    } JPL_Pathfinder;
+} jplpath.dat;
+"
+
+set ff_test2 "http://$host/$test_dir/nph-dods/data/ff/jplpath_space.dat"
+set ff_test2_ce1 "year"
+set ff_test2_ce2 "JPL%20Pathfinder.year"
+set ff_test2_ce3 "JPL Pathfinder.year"
+set ff_test2_dds "Dataset {
+    Sequence {
+        Int32 year;
+        Int32 day;
+        Int32 hours;
+        Int32 minutes;
+        Int32 seconds;
+        String DODS_URL;
+    } JPL%20Pathfinder;
+} jplpath_space.dat;
+"
\ No newline at end of file
diff --git a/unit-tests/server-testsuite/jg_diatoms.data b/unit-tests/server-testsuite/jg_diatoms.data
new file mode 100644
index 0000000..121f994
--- /dev/null
+++ b/unit-tests/server-testsuite/jg_diatoms.data
@@ -0,0 +1,7 @@
+The data:
+    Sequence {
+        String sta;
+        String event;
+        String diatom_Nit_bi;
+    } Level_0;
+ = { { 5, 11031315, 21.0 }, { 8, 11032135, 67.8 }, { 11, 11041345, 43.3 }, { 17, 11071306, 66.8 }, { 22, 11080700, 63.5 }, { 25, 11082125, 68.2 }, { 28, 11091230, 54.2 }, { 30, 11100107, 63.5 }, { 33, 11101455, 61.2 }, { 37, 11110740, 50.7 }, { 42, 11120301, 53.7 }, { 51, 11150953, 64.4 }, { 54, 11160237, 38.8 }};
\ No newline at end of file
diff --git a/unit-tests/server-testsuite/jg_test.data b/unit-tests/server-testsuite/jg_test.data
new file mode 100644
index 0000000..8bcd7eb
--- /dev/null
+++ b/unit-tests/server-testsuite/jg_test.data
@@ -0,0 +1,9 @@
+The data:
+Sequence {
+    String year;
+    String month;
+    String lat;
+    String lon;
+    String sal;
+} Level_0 = { { "81", "6", "37.93", "-72.69", "33.787" }, { "81", "6", "37.93", "-72.69", "35.001" }, { "81", "6", "37.93", "-72.69", "35.298" }, { "81", "6", "37.93", "-72.69", "35.426" }, { "81", "6", "37.93", "-72.69", "35.592" }, { "81", "6", "37.93", "-72.69", "35.416" }, { "81", "6", "37.93", "-72.69", "35.119" }, { "81", "6", "37.93", "-72.69", "35.029" }, { "81", "6", "37.93", "-72.69", "34.973" }, { "81", "6", "37.93", "-72.69", "34.973" }, { "81", "6", "37.93", "-72.69", "34.97 [...]
+
diff --git a/unit-tests/server-testsuite/nscat_hdf.data b/unit-tests/server-testsuite/nscat_hdf.data
new file mode 100644
index 0000000..decb61c
--- /dev/null
+++ b/unit-tests/server-testsuite/nscat_hdf.data
@@ -0,0 +1,5 @@
+The data:
+Structure {
+    Int16 WVC_Lat[row = 2][WVC = 2];
+} NSCAT%20Rev%2020 = { {{2611, 2617},{-9000, 2661}} };
+
diff --git a/unit-tests/server-testsuite/nscat_s2.data b/unit-tests/server-testsuite/nscat_s2.data
new file mode 100644
index 0000000..67bb094
--- /dev/null
+++ b/unit-tests/server-testsuite/nscat_s2.data
@@ -0,0 +1,2 @@
+The data:
+Float64 NSCAT_S2[NSCAT_S2_row = 1][NSCAT_S2_column = 6] = {{46002, 96, 9, 15, 18, 50}};
diff --git a/unit-tests/structT.cc b/unit-tests/structT.cc
new file mode 100644
index 0000000..18d93a4
--- /dev/null
+++ b/unit-tests/structT.cc
@@ -0,0 +1,154 @@
+
+#include <cppunit/TestFixture.h>
+#include <cppunit/TestAssert.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <cppunit/ui/text/TestRunner.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/CompilerOutputter.h>
+
+#include <iostream>
+#include <sstream>
+#include "TestStructure.h"
+#include "TestArray.h"
+#include "TestInt16.h"
+#include "TestStr.h"
+#include "TestTypeFactory.h"
+#include "util.h"
+//#include "Pix.h"
+
+using std::cerr ;
+using std::endl ;
+using std::ostringstream ;
+
+int test_variable_sleep_interval = 0; // Used in Test* classes for testing
+				      // timeouts. 
+string ExpectedPrint1( "Structure {\n\
+    Int16 name_int16;\n\
+    String name_str;\n\
+    Int16 array_int[dim1 = 4][dim2 = 3][dim3 = 2];\n\
+} my_structure = { 32000, \"Silly test string: 1\", {{{32000, 32000},{32000, 32000},{32000, 32000}},{{32000, 32000},{32000, 32000},{32000, 32000}},{{32000, 32000},{32000, 32000},{32000, 32000}},{{32000, 32000},{32000, 32000},{32000, 32000}}} };\n") ;
+
+string ExpectedPrint2( "Structure {\n\
+    Int16 name_int16;\n\
+    Int16 array_int[dim1 = 4][dim2 = 3][dim3 = 2];\n\
+} my_structure = { 32000, {{{32000, 32000},{32000, 32000},{32000, 32000}},{{32000, 32000},{32000, 32000},{32000, 32000}},{{32000, 32000},{32000, 32000},{32000, 32000}},{{32000, 32000},{32000, 32000},{32000, 32000}}} };\n") ;
+
+class structT : public CppUnit::TestFixture {
+
+CPPUNIT_TEST_SUITE( structT ) ;
+CPPUNIT_TEST( structT_test ) ;
+CPPUNIT_TEST_SUITE_END( ) ;
+
+private:
+    /* TEST PRIVATE DATA */
+    TestTypeFactory *factory;
+    
+public:
+    void setUp()
+    {
+        factory = new TestTypeFactory;
+    }
+
+    void tearDown() 
+    {
+        delete factory; factory = 0;
+    }
+
+    void structT_test()
+    {
+	TestStructure s( "my_structure" ) ;
+
+	BaseType *bt = factory->NewInt16( "name_int16" ) ;
+	s.add_var( bt ) ;
+	delete bt ; bt = 0 ;
+
+	bt = factory->NewStr( "name_str" ) ;
+	s.add_var( bt ) ;
+	delete bt ; bt = 0 ;
+
+	Array *abt = factory->NewArray( "name_array", factory->NewInt16( "array_int" ) ) ;
+	abt->append_dim( 4, "dim1" ) ;
+	abt->append_dim( 3, "dim2" ) ;
+	abt->append_dim( 2, "dim3" ) ;
+	s.add_var( abt ) ;
+	delete abt ; abt = 0 ;
+
+	bt = 0 ;
+	bt = s.var( "name_str", true ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "name_str" ) ;
+
+	bt = 0 ;
+	bt = s.var( "name_str", false ) ;
+	CPPUNIT_ASSERT( bt && bt->name() == "name_str" ) ;
+
+	vector<string> varnames ;
+	varnames.push_back( "name_int16" ) ;
+	varnames.push_back( "name_str" ) ;
+	varnames.push_back( "array_int" ) ;
+	typedef vector<string>::const_iterator niter ;
+
+	Structure::Vars_iter viter = s.var_begin() ;
+	niter n = varnames.begin() ;
+	for( ; viter != s.var_end() && n != varnames.end(); viter++, n++ )
+	{
+	    CPPUNIT_ASSERT( (*viter)->name() == *n ) ;
+	}
+	CPPUNIT_ASSERT( viter == s.var_end() && n == varnames.end() ) ;
+	if( viter != s.var_end() && n == varnames.end() )
+	{
+	    CPPUNIT_FAIL( "Too many variables" ) ;
+	}
+	else if( viter == s.var_end() && n != varnames.end() )
+	{
+	    CPPUNIT_FAIL( "Too few varialbes" ) ;
+	}
+
+	int num_elems = s.element_count( ) ;
+	CPPUNIT_ASSERT( num_elems == 3 ) ;
+
+	unsigned int w = s.width() ;
+	unsigned int wsb = sizeof(string)
+			   + sizeof(dods_int16)
+			   + 24*sizeof(dods_int16) ;
+	CPPUNIT_ASSERT( w == wsb ) ;
+
+	bool is_read = s.read() ;
+	CPPUNIT_ASSERT( is_read == true ) ;
+
+	ostringstream sstrm1 ;
+	s.print_val( sstrm1 ) ;
+	CPPUNIT_ASSERT( sstrm1.str() == ExpectedPrint1 ) ;
+
+	s.del_var( "name_str" ) ;
+
+	bt = 0 ;
+	bt = s.var( "name_str", false ) ;
+	CPPUNIT_ASSERT( bt == 0 ) ;
+
+	w = s.width() ;
+	wsb = + sizeof(dods_int16) + 24*sizeof(dods_int16) ;
+	CPPUNIT_ASSERT( w == wsb ) ;
+
+	ostringstream sstrm2 ;
+	s.print_val( sstrm2 ) ;
+	CPPUNIT_ASSERT( sstrm2.str() == ExpectedPrint2 ) ;
+    }
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( structT ) ;
+
+/* NOTHING NEEDS TO BE CHANGED BELOW HERE */
+
+int main( int, char ** )
+{
+    CppUnit::TextUi::TestRunner runner ;
+    CppUnit::TestFactoryRegistry &registry =
+	CppUnit::TestFactoryRegistry::getRegistry() ;
+    runner.addTest( registry.makeTest() ) ;
+    runner.setOutputter( CppUnit::CompilerOutputter::defaultOutputter( 
+                                                        &runner.result(),
+                                                        std::cerr ) );
+    bool wasSuccessful = runner.run( "", false ) ;
+    return wasSuccessful ? 0 : 1;
+}
+
diff --git a/unit-tests/testFile.cc b/unit-tests/testFile.cc
new file mode 100644
index 0000000..796c666
--- /dev/null
+++ b/unit-tests/testFile.cc
@@ -0,0 +1,36 @@
+#include "config.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <fstream>
+#include <sstream>
+#include <debug.h>
+
+using namespace std;
+
+#define FILE2string(s,f,c) do {\
+        FILE *(f) = fopen("testout", "w");\
+        c;\
+        fclose(f);\
+        s = testFile("testout");\
+        unlink("testout");\
+} while(0);
+
+// It's evil to include code like this, but for the unit tests, such is
+// the way... jhrg 1/20/06
+string
+testFile(char *fn)
+{
+    ifstream ifs(fn);
+    ostringstream strm;
+    char line[1024];
+    while (!ifs.eof()) {
+        ifs.getline(line, 1024);
+        strm << line << endl;
+    }
+    ifs.close();
+    
+    return strm.str();
+}
diff --git a/unit-tests/test_config.h b/unit-tests/test_config.h
new file mode 100644
index 0000000..de41d48
--- /dev/null
+++ b/unit-tests/test_config.h
@@ -0,0 +1,7 @@
+#ifndef E_test_config_h
+#define E_test_config_h
+
+#define TEST_SRC_DIR "/Users/ndp/OPeNDAP/Projects/Hyrax/swdev/hyrax-1.7.0/src/libdap/unit-tests"
+
+#endif
+
diff --git a/unit-tests/test_config.h.in b/unit-tests/test_config.h.in
new file mode 100644
index 0000000..94c6dce
--- /dev/null
+++ b/unit-tests/test_config.h.in
@@ -0,0 +1,7 @@
+#ifndef E_test_config_h
+#define E_test_config_h
+
+#define TEST_SRC_DIR "@abs_srcdir@"
+
+#endif
+
diff --git a/util.cc b/util.cc
new file mode 100644
index 0000000..314227f
--- /dev/null
+++ b/util.cc
@@ -0,0 +1,567 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT_URI.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher <jgallagher at gso.uri.edu>
+
+// Utility functions used by the api.
+//
+// jhrg 9/21/94
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: util.cc 21699 2009-11-05 00:06:01Z jimg $"
+    };
+
+#include <cassert>
+#include <cstring>
+
+#include <ctype.h>
+#ifndef TM_IN_SYS_TIME
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#ifndef WIN32
+#include <unistd.h>    // for stat
+#else
+#include <io.h>
+#include <fcntl.h>
+#include <process.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <string>
+#include <sstream>
+#include <vector>
+#include <algorithm>
+#include <stdexcept>
+
+#include "BaseType.h"
+#include "Str.h"
+#include "Url.h"
+#include "Sequence.h"
+#include "Error.h"
+#include "parser.h"
+#include "util.h"
+#include "GNURegex.h"
+#include "debug.h"
+
+
+using namespace std;
+
+namespace libdap {
+
+// Remove spaces from the start of a URL and from the start of any constraint
+// expression it contains. 4/7/98 jhrg
+
+/** Removed spaces from the front of a URL and also from the front of the CE.
+    This function assumes that there are no holes in both the URL and the CE.
+    It will remove \e leading space, but not other spaces.
+
+    @todo Is this still needed? This function may predate the switch from
+    libwww to libcurl and the latter may not need to have spaces removed.
+    @param name The URL to process
+    @return Returns a new string object that contains the pruned URL. */
+string
+prune_spaces(const string &name)
+{
+    // If the URL does not even have white space return.
+    if (name.find_first_of(' ') == name.npos)
+        return name;
+    else {
+        // Strip leading spaces from http://...
+        unsigned int i = name.find_first_not_of(' ');
+        string tmp_name = name.substr(i);
+
+        // Strip leading spaces from constraint part (following `?').
+        unsigned int j = tmp_name.find('?') + 1;
+        i = tmp_name.find_first_not_of(' ', j);
+        tmp_name.erase(j, i - j);
+
+        return tmp_name;
+    }
+}
+
+// Compare elements in a list of (BaseType *)s and return true if there are
+// no duplicate elements, otherwise return false.
+
+bool
+unique_names(vector<BaseType *> l, const string &var_name,
+             const string &type_name, string &msg)
+{
+    // copy the identifier names to a vector
+    vector<string> names(l.size());
+
+    int nelem = 0;
+    typedef std::vector<BaseType *>::const_iterator citer ;
+    for (citer i = l.begin(); i != l.end(); i++) {
+        assert(*i);
+        names[nelem++] = (*i)->name();
+        DBG(cerr << "NAMES[" << nelem - 1 << "]=" << names[nelem-1] << endl);
+    }
+
+    // sort the array of names
+    sort(names.begin(), names.end());
+
+#ifdef DODS_DEBUG2
+    cout << "unique:" << endl;
+    for (int ii = 0; ii < nelem; ++ii)
+        cout << "NAMES[" << ii << "]=" << names[ii] << endl;
+#endif
+
+    // sort the array of names
+    sort(names.begin(), names.end());
+
+#ifdef DODS_DEBUG2
+    cout << "unique:" << endl;
+    for (int ii = 0; ii < nelem; ++ii)
+        cout << "NAMES[" << ii << "]=" << names[ii] << endl;
+#endif
+
+    // look for any instance of consecutive names that are ==
+    for (int j = 1; j < nelem; ++j) {
+        if (names[j-1] == names[j]) {
+            ostringstream oss;
+            oss << "The variable `" << names[j]
+            << "' is used more than once in " << type_name << " `"
+            << var_name << "'";
+            msg = oss.str();
+
+            return false;
+        }
+    }
+
+    return true;
+}
+
+const char *
+libdap_root()
+{
+    return LIBDAP_ROOT;
+}
+
+extern "C"
+    const char *
+    libdap_version()
+{
+    return PACKAGE_VERSION;
+}
+
+extern "C"
+    const char *
+    libdap_name()
+{
+    return PACKAGE_NAME;
+}
+
+// Since Server4 can get compressed responses using Tomcat, bail on this
+// software (which complicates building under Win32). It can be turned on
+// for use with Server3 in configure.ac.
+
+#if COMPRESSION_FOR_SERVER3
+
+// Return true if the program deflate exists and is executable by user, group
+// and world. If this returns false the caller should assume that server
+// filter programs won't be able to find the deflate program and thus won't
+// be able to compress the return document.
+// NB: this works because this function uses the same rules as compressor()
+// (which follows) to look for deflate. 2/11/98 jhrg
+
+bool
+deflate_exists()
+{
+    DBG(cerr << "Entering deflate_exists...");
+
+    int status = false;
+    struct stat buf;
+
+#ifdef WIN32
+    string deflate = (string)libdap_root() + "\\bin\\deflate";
+#else
+    string deflate = (string)libdap_root() + "/sbin/deflate";
+#endif
+
+    // Check that the file exists...
+    // First look for deflate using DODS_ROOT (compile-time constant subsumed
+    // by an environment variable) and if that fails in the CWD which finds
+    // the program when it is in the same directory as the dispatch script
+    // and other server components. 2/11/98 jhrg
+    status = (stat(deflate.c_str(), &buf) == 0)
+#ifdef WIN32
+             || (stat(".\\deflate", &buf) == 0);
+#else
+             || (stat("./deflate", &buf) == 0);
+#endif
+
+    // and that it can be executed.
+#ifdef WIN32
+    status &= (buf.st_mode & _S_IEXEC);
+#else
+    status &= buf.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH);
+#endif
+    DBG(cerr << " returning " << (status ? "true." : "false.") << endl);
+    return (status != 0);
+}
+
+FILE *
+compressor(FILE *output, int &childpid)
+{
+#ifdef WIN32
+    //  There is no such thing as a "fork" under win32. This makes it so that
+    //  we have to juggle handles more aggressively. This code hasn't been
+    //  tested and shown to work as of 07/2000.
+    int pid, data[2];
+    int hStdIn, hStdOut;
+
+    if (_pipe(data, 512, O_BINARY | O_NOINHERIT) < 0) {
+        cerr << "Could not create IPC channel for compressor process"
+        << endl;
+        return NULL;
+    }
+
+
+    // This sets up for the child process, but it has to be reversed for the
+    // parent after the spawn takes place.
+
+    // Store stdin, stdout so we have something to restore to
+    hStdIn  = _dup(_fileno(stdin));
+    hStdOut = _dup(_fileno(stdout));
+
+    // Child is to read from read end of pipe
+    if (_dup2(data[0], _fileno(stdin)) != 0) {
+        cerr << "dup of child stdin failed" << endl;
+        return NULL;
+    }
+    // Child is to write its's stdout to file
+    if (_dup2(_fileno(output), _fileno(stdout)) != 0) {
+        cerr << "dup of child stdout failed" << endl;
+        return NULL;
+    }
+
+    // Spawn child process
+    string deflate = "deflate.exe";
+    if ((pid = _spawnlp(_P_NOWAIT, deflate.c_str(), deflate.c_str(),
+                        "-c", "5", "-s", NULL)) < 0) {
+        cerr << "Could not spawn to create compressor process" << endl;
+        return NULL;
+    }
+
+    // Restore stdin, stdout for parent and close duplicate copies
+    if (_dup2(hStdIn, _fileno(stdin)) != 0) {
+        cerr << "dup of stdin failed" << endl;
+        return NULL;
+    }
+    if (_dup2(hStdOut, _fileno(stdout)) != 0) {
+        cerr << "dup of stdout failed" << endl;
+        return NULL;
+    }
+    close(hStdIn);
+    close(hStdOut);
+
+    // Tell the parent that it reads from the opposite end of the
+    // place where the child writes.
+    close(data[0]);
+    FILE *input = fdopen(data[1], "w");
+    setbuf(input, 0);
+    childpid = pid;
+    return input;
+
+#else
+    FILE *ret_file = NULL ;
+
+    int pid, data[2];
+
+    if (pipe(data) < 0) {
+        cerr << "Could not create IPC channel for compressor process"
+        << endl;
+        return NULL;
+    }
+
+    if ((pid = fork()) < 0) {
+        cerr << "Could not fork to create compressor process" << endl;
+        return NULL;
+    }
+
+    // The parent process closes the write end of the Pipe, and creates a
+    // FILE * using fdopen(). The FILE * is used by the calling program to
+    // access the read end of the Pipe.
+
+    if (pid > 0) {   // Parent, pid is that of the child
+        close(data[0]);
+        ret_file = fdopen(data[1], "w");
+        setbuf(ret_file, 0);
+        childpid = pid;
+    }
+    else {   // Child
+        close(data[1]);
+        dup2(data[0], 0); // Read from the pipe...
+        dup2(fileno(output), 1); // Write to the FILE *output.
+
+        DBG(cerr << "Opening compression stream." << endl);
+
+        // First try to run deflate using DODS_ROOT (the value read from the
+        // DODS_ROOT environment variable takes precedence over the value set
+        // at build time. If that fails, try the CWD.
+        string deflate = (string)libdap_root() + "/sbin/deflate";
+        (void) execl(deflate.c_str(), "deflate", "-c",  "5", "-s", NULL);
+        (void) execl("./deflate", "deflate", "-c",  "5", "-s", NULL);
+        cerr << "Warning: Could not start compressor!" << endl;
+        cerr << "defalte should be in DODS_ROOT/etc or in the CWD!"
+        << endl;
+        _exit(127);  // Only here if an error occurred.
+    }
+
+    return ret_file ;
+#endif
+}
+
+#endif // COMPRESSION_FOR_SERVER3
+
+// This function returns a pointer to the system time formated for an httpd
+// log file.
+
+string
+systime()
+{
+    time_t TimBin;
+
+    if (time(&TimBin) == (time_t) - 1)
+        return string("time() error");
+    else {
+        string TimStr = ctime(&TimBin);
+        return TimStr.substr(0, TimStr.size() - 2); // remove the \n
+    }
+}
+
+void
+downcase(string &s)
+{
+    for (unsigned int i = 0; i < s.length(); i++)
+        s[i] = tolower(s[i]);
+}
+
+bool
+is_quoted(const string &s)
+{
+    return (!s.empty() && s[0] == '\"' && s[s.length()-1] == '\"');
+}
+
+string
+remove_quotes(const string &s)
+{
+    if (is_quoted(s))
+        return s.substr(1, s.length() - 2);
+    else
+        return s;
+}
+
+#ifdef WIN32
+//  Sometimes need to buffer within an iostream under win32 when
+//  we want the output to go to a FILE *.  This is because
+//  it's not possible to associate an ofstream with a FILE *
+//  under the Standard ANSI C++ Library spec.  Unix systems
+//  don't follow the spec in this regard.
+void flush_stream(iostream ios, FILE *out)
+{
+    int nbytes;
+    char buffer[512];
+
+    ios.get(buffer, 512, NULL);
+    while ((nbytes = ios.gcount()) > 0) {
+        fwrite(buffer, 1, nbytes, out);
+        ios.get(buffer, 512, NULL);
+    }
+
+    return;
+}
+#endif
+
+// Jose Garcia
+void
+append_long_to_string(long val, int base, string &str_val)
+{
+    // The array digits contains 36 elements which are the
+    // posible valid digits for out bases in the range
+    // [2,36]
+    char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+    // result of val / base
+    ldiv_t r;
+
+    if (base > 36 || base < 2) {
+        // no conversion if wrong base
+        std::invalid_argument ex("The parameter base has an invalid value.");
+        throw ex;
+    }
+    if (val < 0)
+        str_val += '-';
+    r = ldiv(labs(val), base);
+
+    // output digits of val/base first
+    if (r.quot > 0)
+        append_long_to_string(r.quot, base, str_val);
+
+    // output last digit
+
+    str_val += digits[(int)r.rem];
+}
+
+// base defaults to 10
+string
+long_to_string(long val, int base)
+{
+    string s;
+    append_long_to_string(val, base, s);
+    return s;
+}
+
+// Jose Garcia
+void append_double_to_string(const double &num, string &str)
+{
+    // s having 100 characters should be enough for sprintf to do its job.
+    // I want to banish all instances of sprintf. 10/5/2001 jhrg
+    ostringstream oss;
+    oss.precision(9);
+    oss << num;
+    str += oss.str();
+}
+
+string
+double_to_string(const double &num)
+{
+    string s;
+    append_double_to_string(num, s);
+    return s;
+}
+
+// Get the version number of the core software. Defining this means that
+// clients of the DAP don't have to rely on config.h for the version
+// number.
+string
+dap_version()
+{
+    return (string)"OPeNDAP DAP/" + libdap_version() + ": compiled on " + __DATE__ + ":" + __TIME__ ;
+}
+
+// Given a pathname, return the file at the end of the path. This is used
+// when reporting errors (maybe other times, too) to keep the server from
+// revealing too much about its organization when sending error responses
+// back to clients. 10/11/2000 jhrg
+// MT-safe. 08/05/02 jhrg
+
+#ifdef WIN32
+static const char path_sep[] =
+    {"\\"
+    };
+#else
+static const char path_sep[] =
+    {"/"
+    };
+#endif
+
+string
+path_to_filename(string path)
+{
+    string::size_type pos = path.rfind(path_sep);
+
+    return (pos == string::npos) ? path : path.substr(++pos);
+}
+
+/** Read stuff from a file and dump it into a string. This assumes the file
+    holds character data only. Intended for testing...
+    @param fp Read from this file
+    @return Returns a string which holds the character data. */
+string
+file_to_string(FILE *fp)
+{
+    rewind(fp);
+    ostringstream oss;
+    char c;
+    while (fread(&c, 1, 1, fp))
+        oss << c;
+    return oss.str();
+}
+
+/** @name Security functions */
+//@{
+
+/** @brief sanitize the size of an array.
+    Test for integer overflow when dynamically allocating an array.
+    @param nelem Number of elements.
+    @param sz size of each element.
+    @return True if the \c nelem elements of \c sz size will overflow an array. */
+bool
+size_ok(unsigned int sz, unsigned int nelem)
+{
+    return (sz > 0 && nelem < UINT_MAX / sz);
+}
+
+/** @brief Does the string name a potentailly valid pathname?
+    Test the given pathname to verfiy that it is a valid name. We define this
+    as: Contains only printable characters; and Is less then 256 characters.
+    If \e strict is true, test that the pathname consists of only letters,
+    digits, and underscore, dash and dot characters instead of the more general
+    case where a pathname can be composed of any printable characters.
+
+    @note Using this function does not guarentee that the path is valid, only
+    that the path \e could be valid. The intent is foil attacks where an
+    exploit is encoded in a string then passed to a library function. This code
+    does not address whether the pathname references a valid resource.
+
+    @param path The pathname to test
+    @param strict Apply more restrictive tests (true by default)
+    @return true if the pathname consists of legal characters and is of legal
+    size, false otherwise. */
+bool
+pathname_ok(const string &path, bool strict)
+{
+    if (path.length() > 255)
+        return false;
+
+    Regex name("[-0-9A-z_./]+");
+    if (!strict)
+        name = "[:print:]+";
+
+    string::size_type len = path.length();
+    int result = name.match(path.c_str(), len);
+    // Protect against casting too big an uint to int
+    // if LEN is bigger than the max int32, the second test can't work
+    if (len > INT_MAX || result != static_cast<int>(len))
+        return false;
+
+    return true;
+}
+
+//@}
+
+} // namespace libdap
+
diff --git a/util.h b/util.h
new file mode 100644
index 0000000..438d4b1
--- /dev/null
+++ b/util.h
@@ -0,0 +1,149 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002,2003 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+// (c) COPYRIGHT URI/MIT 1994-1999
+// Please read the full copyright statement in the file COPYRIGHT.
+//
+// Authors:
+//      jhrg,jimg       James Gallagher (jgallagher at gso.uri.edu)
+
+// declarations for utility functions
+//
+// jhrg 9/21/94
+
+#ifndef _util_h
+#define _util_h 1
+
+#include <cstdio>
+#include <vector>
+
+#ifndef _basetype_h
+#include "BaseType.h"
+#endif
+
+using std::iostream;
+
+namespace libdap
+{
+
+string prune_spaces(const string &);
+bool unique_names(vector<BaseType *> l, const string &var, const string &type,
+                  string &msg);
+FILE *text_to_temp(string text);
+string systime();
+FILE *compressor(FILE *output, int &childpid);
+bool deflate_exists();
+const char *libdap_root();
+/** Return the version string for this package.
+    @note This function has C linkage so that it can be found using autoconf
+    tests.
+    @return The version string. */
+extern "C" const char *libdap_version();
+extern "C" const char *libdap_name();
+const char *dods_progress();
+#ifdef WIN32
+void flush_stream(iostream ios, FILE *out);
+#endif
+
+void downcase(string &s);
+bool is_quoted(const string &s);
+string remove_quotes(const string &s);
+
+// Jose Garcia
+/** @name Integer to string conversion functions
+   Fast, safe conversions from long to a character representation which gets
+   appended to a string. This method will take a long value 'val' and it will
+   recursively divide it by 'base' in order to "extract" one by one the
+   digits which compose it; these digits will be <i>appended</i> to the
+   string <tt>str_val</tt> which will become the textual representation of
+   'val'. Please notice that the digits ``extracted'' from `val' will vary
+   depending on the base chosen for the conversion; for example val=15
+   converted to base 10 will yield the digits (1,5), converted to base 16
+   will yield (F) and converted to base 2 will yield (1,1,1,1).
+
+   @param val The long value we which to convert to string.
+
+   @param base A value in the range [2,36] which is the base to use while
+   transforming the long value 'val' to its textual representation. Typical
+   bases are 2 (binary), 10 (decimal) and 16 (hexadecimal).
+
+   @param str_val This is the string that will hold the textual
+   representation of 'val'. The string <tt>str_val</tt> should be
+   pre-set to an empty
+   string ("") otherwise the output of this function will just append the
+   textual representation of val to whatever data is there; these feature may
+   be useful if you wish to append a long value to a string s1 (just like
+   operator+ does) without having to create a new string object s2 and then
+   use string::operator+ between s1 and s2.
+
+   @return void. This method returns nothing however be aware that it will
+   throw and exception of type <tt>std::invalid_argument</tt> if the parameter
+   base is not in the valid range. */
+//@{
+void append_long_to_string(long val, int base, string &str_val);
+string long_to_string(long val, int base = 10);
+//@}
+
+// Jose Garcia
+/** @name Double to string conversion functions
+    Conversions from double to a character representation which gets appended
+    to a string. This function depends on the standard routine sprintf to
+    convert a double to a textual representation which gets appended to the
+    string 'str'.
+
+    @param num The double you wish to append to str.
+
+    @param str The string where the textual representation of num will be
+    appended.
+
+    @return void. */
+//@{
+void append_double_to_string(const double &num, string &str);
+string double_to_string(const double &num);
+//@}
+
+/** Get the version of the DAP library. */
+string dap_version();
+
+/** Get the filename part from a path. This function can be used to return a
+    string that has the directory components stripped from a path. This is
+    useful when building error message strings.
+
+    If WIN32 is defined, use '\' as the path separator, otherwise use '/' as
+    the path separator.
+
+    @return A string containing only the filename given a path. */
+string path_to_filename(string path);
+
+string file_to_string(FILE *fp);
+
+time_t parse_time(const char * str, bool expand);
+
+bool size_ok(unsigned int sz, unsigned int nelem);
+bool pathname_ok(const string &path, bool strict = true);
+
+} // namespace libdap
+
+#endif
diff --git a/util_mit.cc b/util_mit.cc
new file mode 100644
index 0000000..8d0b2fa
--- /dev/null
+++ b/util_mit.cc
@@ -0,0 +1,368 @@
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112
+
+// This file was derived from the libwww source code of 1998/08/20. The
+// copyright for the source of this derivative work can be found in the file
+// COPYRIGHT_W3C.
+
+
+#include "config.h"
+
+static char rcsid[] not_used =
+    {"$Id: util_mit.cc 24370 2011-03-28 16:21:32Z jimg $"
+    };
+
+#include <cstdio>
+#include <cstring>
+#include <cstdlib>
+//#include <string>
+#include <ctype.h>
+
+#ifndef TM_IN_SYS_TIME
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <iostream>
+
+#include "util_mit.h"
+
+using std::cerr;
+using std::endl;
+using std::string;
+
+#include "debug.h"
+
+namespace libdap {
+
+static const char * months[12] =
+    {
+        "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+    };
+
+#ifndef HAVE_STRFTIME
+static const char * wkdays[7] =
+    {
+        "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+    };
+#endif
+
+/* Upper- and Lowercase macros
+
+   The problem here is that toupper(x) is not defined officially unless
+   isupper(x) is. These macros are CERTAINLY needed on #if defined(pyr) ||
+   define(mips) or BDSI platforms. For safefy, we make them mandatory.
+*/
+
+#ifndef TOLOWER
+#define TOLOWER(c) tolower((int) (c))
+#define TOUPPER(c) toupper((int) (c))
+#endif
+
+static int
+strncasecomp(const char *a, const char *b, int n)
+{
+    const char *p = a;
+    const char *q = b;
+
+    for (p = a, q = b;; p++, q++) {
+        int diff;
+        if (p == a + n) return 0; /*   Match up to n characters */
+        if (!(*p && *q)) return *p - *q;
+        diff = TOLOWER(*p) - TOLOWER(*q);
+        if (diff) return diff;
+    }
+    /*NOTREACHED*/
+}
+
+static int
+make_month(char * s, char ** ends)
+{
+    char * ptr = s;
+    while (!isalpha((int) *ptr)) ptr++;
+    if (*ptr) {
+        int i;
+        *ends = ptr + 3;
+        for (i = 0; i < 12; i++)
+            if (!strncasecomp(months[i], ptr, 3)) return i;
+    }
+    return 0;
+}
+
+/** Parse a string in GMT format to a local time time_t representation
+    Four formats are accepted:
+ Wkd, 00 Mon 0000 00:00:00 GMT  (rfc1123)
+ Weekday, 00-Mon-00 00:00:00 GMT  (rfc850)
+ Wkd Mon 00 00:00:00 0000 GMT  (ctime)
+ 1*DIGIT     (delta-seconds)
+
+    Copied from libwww. 09/19/02 jhrg
+
+    @param str The time string.
+    @param expand If the time is given in delta seconds, adjust it to seconds
+    since midnight 1 Jan 1970 if this is true. If false, simply convert the
+    string to a time_t and return. The default value is true.
+    @return The time in seconds since midnight 1 Jan 1970. */
+time_t
+parse_time(const char * str, bool expand)
+{
+    char * s;
+    struct tm tm;
+    time_t t;
+
+    if (!str) return 0;
+
+    if ((s = (char *)strchr(str, ','))) {  /* Thursday, 10-Jun-93 01:29:59 GMT */
+        s++;    /* or: Thu, 10 Jan 1993 01:29:59 GMT */
+        while (*s && *s == ' ') s++;
+        if (strchr(s, '-')) {         /* First format */
+            DBG(cerr << "Format...... Weekday, 00-Mon-00 00:00:00 GMT"
+                << endl);
+            if ((int)strlen(s) < 18) {
+                DBG(cerr << "ERROR....... Not a valid time format \""
+                    << s << "\"" << endl);
+                return 0;
+            }
+            tm.tm_mday = strtol(s, &s, 10);
+            tm.tm_mon = make_month(s, &s);
+            ++s;
+            tm.tm_year = strtol(s, &s, 10);
+            tm.tm_hour = strtol(s, &s, 10);
+            ++s;
+            tm.tm_min = strtol(s, &s, 10);
+            ++s;
+            tm.tm_sec = strtol(s, &s, 10);
+
+        }
+        else {         /* Second format */
+            DBG(cerr << "Format...... Wkd, 00 Mon 0000 00:00:00 GMT" << endl);
+            if ((int)strlen(s) < 20) {
+                DBG(cerr << "ERROR....... Not a valid time format \""
+                    << s << "\"" << endl);
+                return 0;
+            }
+            tm.tm_mday = strtol(s, &s, 10);
+            tm.tm_mon = make_month(s, &s);
+            tm.tm_year = strtol(s, &s, 10) - 1900;
+            tm.tm_hour = strtol(s, &s, 10);
+            ++s;
+            tm.tm_min = strtol(s, &s, 10);
+            ++s;
+            tm.tm_sec = strtol(s, &s, 10);
+        }
+    }
+    else if (isdigit((int) *str)) {
+
+        if (strchr(str, 'T')) { /* ISO (limited format) date string */
+            DBG(cerr << "Format...... YYYY.MM.DDThh:mmStzWkd" << endl);
+            s = (char *) str;
+            while (*s && *s == ' ') s++;
+            if ((int)strlen(s) < 21) {
+                DBG(cerr << "ERROR....... Not a valid time format \""
+                    << s << "\"" << endl);
+                return 0;
+            }
+            tm.tm_year = strtol(s, &s, 10) - 1900;
+            ++s;
+            tm.tm_mon  = strtol(s, &s, 10);
+            ++s;
+            tm.tm_mday = strtol(s, &s, 10);
+            ++s;
+            tm.tm_hour = strtol(s, &s, 10);
+            ++s;
+            tm.tm_min  = strtol(s, &s, 10);
+            ++s;
+            tm.tm_sec  = strtol(s, &s, 10);
+
+        }
+        else {         /* delta seconds */
+            t = expand ? time(NULL) + atol(str) : atol(str);
+
+            return t;
+        }
+
+    }
+    else {       /* Try the other format:  Wed Jun  9 01:29:59 1993 GMT */
+        DBG(cerr << "Format...... Wkd Mon 00 00:00:00 0000 GMT" << endl);
+        s = (char *) str;
+        while (*s && *s == ' ') s++;
+        DBG(cerr << "Trying...... The Wrong time format: " << s << endl);
+        if ((int)strlen(s) < 24) {
+            DBG(cerr << "ERROR....... Not a valid time format \""
+                << s << "\"" << endl);
+            return 0;
+        }
+        tm.tm_mon = make_month(s, &s);
+        tm.tm_mday = strtol(s, &s, 10);
+        tm.tm_hour = strtol(s, &s, 10);
+        ++s;
+        tm.tm_min = strtol(s, &s, 10);
+        ++s;
+        tm.tm_sec = strtol(s, &s, 10);
+        tm.tm_year = strtol(s, &s, 10) - 1900;
+    }
+    if (tm.tm_sec  < 0  ||  tm.tm_sec  > 59  ||
+        tm.tm_min  < 0  ||  tm.tm_min  > 59  ||
+        tm.tm_hour < 0  ||  tm.tm_hour > 23  ||
+        tm.tm_mday < 1  ||  tm.tm_mday > 31  ||
+        tm.tm_mon  < 0  ||  tm.tm_mon  > 11  ||
+        tm.tm_year < 70  ||  tm.tm_year > 120) {
+        DBG(cerr << "ERROR....... Parsed illegal time" << endl);
+        return 0;
+    }
+
+    /* Let mktime decide whether we have DST or not */
+    tm.tm_isdst = -1;
+
+#ifdef HAVE_TIMEGM
+
+    t = timegm(&tm);
+
+#else
+
+#ifdef HAVE_MKTIME
+
+    // Compute offset between localtime and GMT.
+    time_t offset;
+    time_t now = time(0);
+#ifdef _REENTRANT
+    struct tm gmt, local;
+    offset = mktime(gmtime_r(&now, &gmt)) - mktime(localtime_r(&now, &local));
+#else
+    offset = mktime(gmtime(&now)) - mktime(localtime(&now));
+#endif
+
+    t = mktime(&tm) + offset;
+
+#else
+
+#error "Neither mktime nor timegm defined"
+
+#endif /* HAVE_TIMEGM */
+#endif /* HAVE_MKTIME */
+
+    DBG(cerr << "Time string. " << str << " parsed to " << t
+        << " calendar time or \"" << ctime(&t) << "\" in local time" << endl);
+
+    return t;
+}
+
+/** Given a time in seconds since midnight 1 Jan 1970, return the RFC 1123
+    date string. Example result string: Sun, 06 Nov 1994 08:49:37 GMT
+
+
+    @param calendar Time in seconds
+    @param local If true, return the local time, if false return GMT. The
+    default value is false.
+    @return A RFC 1123 date string. */
+
+string date_time_str(time_t *calendar, bool local)
+{
+    char buf[40];
+
+#ifdef HAVE_STRFTIME
+    if (local) {
+        /*
+        ** Solaris 2.3 has a bug so we _must_ use reentrant version
+        ** Thomas Maslen <tmaslen at verity.com>
+        */
+#if defined(_REENTRANT) || defined(SOLARIS)
+        struct tm loctime;
+        localtime_r(calendar, &loctime);
+        strftime(buf, 40, "%a, %d %b %Y %H:%M:%S", &loctime);
+#else
+        struct tm *loctime = localtime(calendar);
+        strftime(buf, 40, "%a, %d %b %Y %H:%M:%S", loctime);
+#endif /* SOLARIS || _REENTRANT */
+    }
+    else {
+#if defined(_REENTRANT) || defined(SOLARIS)
+        struct tm gmt;
+        gmtime_r(calendar, &gmt);
+        strftime(buf, 40, "%a, %d %b %Y %H:%M:%S GMT", &gmt);
+#else
+        struct tm *gmt = gmtime(calendar);
+        strftime(buf, 40, "%a, %d %b %Y %H:%M:%S GMT", gmt);
+#endif /* SOLARIS || _REENTRANT */
+    }
+
+#else  /* !HAVE_STRFTIME */
+
+    if (local) {
+#if defined(_REENTRANT)
+        struct tm loctime;
+        localtime_r(calendar, &loctime);
+        snprintf(buf, 40, "%s, %02d %s %04d %02d:%02d:%02d",
+                wkdays[loctime.tm_wday],
+                loctime.tm_mday,
+                months[loctime.tm_mon],
+                loctime.tm_year + 1900,
+                loctime.tm_hour,
+                loctime.tm_min,
+                loctime.tm_sec);
+#else
+    struct tm *loctime = localtime(calendar);
+    snprintf(buf, 40, "%s, %02d %s %04d %02d:%02d:%02d",
+            wkdays[loctime->tm_wday],
+            loctime->tm_mday,
+            months[loctime->tm_mon],
+            loctime->tm_year + 1900,
+            loctime->tm_hour,
+            loctime->tm_min,
+            loctime->tm_sec);
+#endif /* _REENTRANT */
+    }
+    else {
+#if defined(_REENTRANT) || defined(SOLARIS)
+        struct tm gmt;
+        gmtime_r(calendar, &gmt);
+        snprintf(buf, 40, "%s, %02d %s %04d %02d:%02d:%02d GMT",
+                wkdays[gmt.tm_wday],
+                gmt.tm_mday,
+                months[gmt.tm_mon],
+                gmt.tm_year + 1900,
+                gmt.tm_hour,
+                gmt.tm_min,
+                gmt.tm_sec);
+#else
+    struct tm *gmt = gmtime(calendar);
+    snprintf(buf, 40, "%s, %02d %s %04d %02d:%02d:%02d GMT",
+            wkdays[gmt->tm_wday],
+            gmt->tm_mday,
+            months[gmt->tm_mon],
+            gmt->tm_year + 1900,
+            gmt->tm_hour,
+            gmt->tm_min,
+            gmt->tm_sec);
+#endif
+    }
+#endif
+    return string(buf);
+}
+
+} // namespace libdap
diff --git a/util_mit.h b/util_mit.h
new file mode 100644
index 0000000..ae24c79
--- /dev/null
+++ b/util_mit.h
@@ -0,0 +1,36 @@
+
+// -*- mode: c++; c-basic-offset:4 -*-
+
+// This file is part of libdap, A C++ implementation of the OPeNDAP Data
+// Access Protocol.
+
+// Copyright (c) 2002 OPeNDAP, Inc.
+// Author: James Gallagher <jgallagher at opendap.org>
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 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
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser 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
+//
+// You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
+
+#include <string>
+
+using std::string;
+
+namespace libdap
+{
+
+time_t parse_time(const char * str, bool expand = true);
+string date_time_str(time_t *calendar, bool local = false);
+
+} // namespace libdap
diff --git a/xdr-datatypes-config.h.in b/xdr-datatypes-config.h.in
new file mode 100644
index 0000000..28cac9b
--- /dev/null
+++ b/xdr-datatypes-config.h.in
@@ -0,0 +1,30 @@
+
+/*
+  Determine at compile-time the sizes of various XDR datatypes. This uses
+  symbols defined by configure (See configure.in). pcw 08/13/07
+*/
+
+#ifndef __XDR_DATATYPES__
+#define __XDR_DATATYPES__
+
+#ifdef WIN32
+#include <rpc.h>
+#include <winsock2.h>
+#include <xdr.h>
+#else
+#include <rpc/types.h>
+#include <netinet/in.h>
+#include <rpc/xdr.h>
+#endif
+
+
+#undef XDR_INT32
+#undef XDR_UINT32
+
+#undef XDR_INT16
+#undef XDR_UINT16
+
+#undef XDR_FLOAT64
+#undef XDR_FLOAT32
+
+#endif /* __XDR_DATATYPES__ */
diff --git a/xdr-datatypes-static.h b/xdr-datatypes-static.h
new file mode 100644
index 0000000..e7a20ca
--- /dev/null
+++ b/xdr-datatypes-static.h
@@ -0,0 +1,56 @@
+
+/*
+  Determine at compile-time the sizes of various datatypes. This uses symbols
+  defined by configure (See configure.in).
+  jhrg 10/24/94
+
+  This header is included by all of the DODS DAP library header files which
+  make use of the dods_* typedefs. C or C++ files can either include
+  config_dap.h, use their own configure script which defines SIZEOF_LONG,
+  _INT, _CHAR and _DOUBLE or set these preprocessor symbols themselves in a
+  Makefile, etc.
+
+  This used to be part of the config_dap.h header, but including that in the
+  DAP library headers introduced problems when the DAP was used in conjunction
+  with other libraries. 8/1/2000 jhrg
+*/
+
+#ifndef __XDR_DATATYPES__
+#define __XDR_DATATYPES__
+
+#ifdef WIN32
+#include <rpc.h>
+#include <winsock2.h>
+#include <xdr.h>
+#else
+#include <rpc/types.h>
+#include <netinet/in.h>
+#include <rpc/xdr.h>
+#endif
+
+#ifndef XDR_INT32
+#define XDR_INT32 xdr_int32_t
+#endif
+
+#ifndef XDR_UINT32
+#define XDR_UINT32 xdr_uint32_t
+#endif
+
+#ifndef XDR_INT16
+#define XDR_INT16 xdr_int16_t
+#endif
+
+#ifndef XDR_UINT16
+#define XDR_UINT16 xdr_uint16_t
+#endif
+
+#ifndef XDR_FLOAT64
+#define XDR_FLOAT64 xdr_double
+#endif
+
+#ifndef XDR_FLOAT32
+#define XDR_FLOAT32 xdr_float
+#endif
+
+#endif /* __XDR_DATATYPES__ */
+
diff --git a/xdr-datatypes.h b/xdr-datatypes.h
new file mode 100644
index 0000000..9167595
--- /dev/null
+++ b/xdr-datatypes.h
@@ -0,0 +1,31 @@
+/* xdr-datatypes-config.h.  Generated from xdr-datatypes-config.h.in by configure.  */
+
+/*
+  Determine at compile-time the sizes of various XDR datatypes. This uses
+  symbols defined by configure (See configure.in). pcw 08/13/07
+*/
+
+#ifndef __XDR_DATATYPES__
+#define __XDR_DATATYPES__
+
+#ifdef WIN32
+#include <rpc.h>
+#include <winsock2.h>
+#include <xdr.h>
+#else
+#include <rpc/types.h>
+#include <netinet/in.h>
+#include <rpc/xdr.h>
+#endif
+
+
+#define XDR_INT32 xdr_int32_t
+#define XDR_UINT32 xdr_u_int32_t
+
+#define XDR_INT16 xdr_int16_t
+#define XDR_UINT16 xdr_u_int16_t
+
+#define XDR_FLOAT64 xdr_double
+#define XDR_FLOAT32 xdr_float
+
+#endif /* __XDR_DATATYPES__ */
diff --git a/xdrutil_ppc.c b/xdrutil_ppc.c
new file mode 100644
index 0000000..3f90b74
--- /dev/null
+++ b/xdrutil_ppc.c
@@ -0,0 +1,41 @@
+/*  The the old-style C function prototypes such as those found in the XDR */
+/*  structure in <rpc/xdr.h> under OS X are not usable from C++.  This,    */
+/*  along with xdr_destroy() being a macro that expands into that old      */
+/*  style ("()" used to mean any number of unspecified args) means that    */
+/*  we cannot use delete_xdrstdio from C++ under OS X.  The other two      */
+/*  functions were brought along for uniformity.                           */
+/*  ROM - 6/22/2003                                                        */
+
+#ifdef __POWERPC__
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+XDR *
+new_xdrstdio(FILE *stream, enum xdr_op xop)
+{
+    XDR *xdr = (XDR *)malloc(sizeof(XDR));
+    
+    xdrstdio_create(xdr, stream, xop);
+    
+    return xdr;
+}
+
+XDR *
+set_xdrstdio(XDR *xdr, FILE *stream, enum xdr_op xop)
+{
+    xdrstdio_create(xdr, stream, xop);
+    
+    return xdr;
+}
+
+// Delete an XDR pointer allocated using the above function. Do not close the
+// associated FILE pointer.
+void
+delete_xdrstdio(XDR *xdr)
+{
+    xdr_destroy(xdr);
+
+    free(xdr);xdr = 0;
+}
+#endif  /*  __POWERPC__  */

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/libdap.git



More information about the debian-science-commits mailing list